1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <time.h> 12 #include <errno.h> 13 14 #include "internal/cryptlib.h" 15 #include <openssl/buffer.h> 16 #include <openssl/x509.h> 17 #include <openssl/pem.h> 18 #include "x509_lcl.h" 19 20 static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, 21 long argl, char **ret); 22 static X509_LOOKUP_METHOD x509_file_lookup = { 23 "Load file into cache", 24 NULL, /* new_item */ 25 NULL, /* free */ 26 NULL, /* init */ 27 NULL, /* shutdown */ 28 by_file_ctrl, /* ctrl */ 29 NULL, /* get_by_subject */ 30 NULL, /* get_by_issuer_serial */ 31 NULL, /* get_by_fingerprint */ 32 NULL, /* get_by_alias */ 33 }; 34 35 X509_LOOKUP_METHOD *X509_LOOKUP_file(void) 36 { 37 return &x509_file_lookup; 38 } 39 40 static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, 41 long argl, char **ret) 42 { 43 int ok = 0; 44 const char *file; 45 46 switch (cmd) { 47 case X509_L_FILE_LOAD: 48 if (argl == X509_FILETYPE_DEFAULT) { 49 file = ossl_safe_getenv(X509_get_default_cert_file_env()); 50 if (file) 51 ok = (X509_load_cert_crl_file(ctx, file, 52 X509_FILETYPE_PEM) != 0); 53 54 else 55 ok = (X509_load_cert_crl_file 56 (ctx, X509_get_default_cert_file(), 57 X509_FILETYPE_PEM) != 0); 58 59 if (!ok) { 60 X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); 61 } 62 } else { 63 if (argl == X509_FILETYPE_PEM) 64 ok = (X509_load_cert_crl_file(ctx, argp, 65 X509_FILETYPE_PEM) != 0); 66 else 67 ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); 68 } 69 break; 70 } 71 return ok; 72 } 73 74 int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) 75 { 76 int ret = 0; 77 BIO *in = NULL; 78 int i, count = 0; 79 X509 *x = NULL; 80 81 in = BIO_new(BIO_s_file()); 82 83 if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 84 X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); 85 goto err; 86 } 87 88 if (type == X509_FILETYPE_PEM) { 89 for (;;) { 90 x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); 91 if (x == NULL) { 92 if ((ERR_GET_REASON(ERR_peek_last_error()) == 93 PEM_R_NO_START_LINE) && (count > 0)) { 94 ERR_clear_error(); 95 break; 96 } else { 97 X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); 98 goto err; 99 } 100 } 101 i = X509_STORE_add_cert(ctx->store_ctx, x); 102 if (!i) 103 goto err; 104 count++; 105 X509_free(x); 106 x = NULL; 107 } 108 ret = count; 109 } else if (type == X509_FILETYPE_ASN1) { 110 x = d2i_X509_bio(in, NULL); 111 if (x == NULL) { 112 X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); 113 goto err; 114 } 115 i = X509_STORE_add_cert(ctx->store_ctx, x); 116 if (!i) 117 goto err; 118 ret = i; 119 } else { 120 X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); 121 goto err; 122 } 123 if (ret == 0) 124 X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_NO_CERTIFICATE_FOUND); 125 err: 126 X509_free(x); 127 BIO_free(in); 128 return ret; 129 } 130 131 int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) 132 { 133 int ret = 0; 134 BIO *in = NULL; 135 int i, count = 0; 136 X509_CRL *x = NULL; 137 138 in = BIO_new(BIO_s_file()); 139 140 if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 141 X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); 142 goto err; 143 } 144 145 if (type == X509_FILETYPE_PEM) { 146 for (;;) { 147 x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); 148 if (x == NULL) { 149 if ((ERR_GET_REASON(ERR_peek_last_error()) == 150 PEM_R_NO_START_LINE) && (count > 0)) { 151 ERR_clear_error(); 152 break; 153 } else { 154 X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); 155 goto err; 156 } 157 } 158 i = X509_STORE_add_crl(ctx->store_ctx, x); 159 if (!i) 160 goto err; 161 count++; 162 X509_CRL_free(x); 163 x = NULL; 164 } 165 ret = count; 166 } else if (type == X509_FILETYPE_ASN1) { 167 x = d2i_X509_CRL_bio(in, NULL); 168 if (x == NULL) { 169 X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); 170 goto err; 171 } 172 i = X509_STORE_add_crl(ctx->store_ctx, x); 173 if (!i) 174 goto err; 175 ret = i; 176 } else { 177 X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); 178 goto err; 179 } 180 if (ret == 0) 181 X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_NO_CRL_FOUND); 182 err: 183 X509_CRL_free(x); 184 BIO_free(in); 185 return ret; 186 } 187 188 int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) 189 { 190 STACK_OF(X509_INFO) *inf; 191 X509_INFO *itmp; 192 BIO *in; 193 int i, count = 0; 194 195 if (type != X509_FILETYPE_PEM) 196 return X509_load_cert_file(ctx, file, type); 197 in = BIO_new_file(file, "r"); 198 if (!in) { 199 X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); 200 return 0; 201 } 202 inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); 203 BIO_free(in); 204 if (!inf) { 205 X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); 206 return 0; 207 } 208 for (i = 0; i < sk_X509_INFO_num(inf); i++) { 209 itmp = sk_X509_INFO_value(inf, i); 210 if (itmp->x509) { 211 if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) 212 goto err; 213 count++; 214 } 215 if (itmp->crl) { 216 if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) 217 goto err; 218 count++; 219 } 220 } 221 if (count == 0) 222 X509err(X509_F_X509_LOAD_CERT_CRL_FILE, 223 X509_R_NO_CERTIFICATE_OR_CRL_FOUND); 224 err: 225 sk_X509_INFO_pop_free(inf, X509_INFO_free); 226 return count; 227 } 228