1 /* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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_local.h" 19 20 static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, 21 long argl, char **ret); 22 static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, 23 long argl, char **ret, OSSL_LIB_CTX *libctx, 24 const char *propq); 25 26 27 static X509_LOOKUP_METHOD x509_file_lookup = { 28 "Load file into cache", 29 NULL, /* new_item */ 30 NULL, /* free */ 31 NULL, /* init */ 32 NULL, /* shutdown */ 33 by_file_ctrl, /* ctrl */ 34 NULL, /* get_by_subject */ 35 NULL, /* get_by_issuer_serial */ 36 NULL, /* get_by_fingerprint */ 37 NULL, /* get_by_alias */ 38 NULL, /* get_by_subject_ex */ 39 by_file_ctrl_ex, /* ctrl_ex */ 40 }; 41 42 X509_LOOKUP_METHOD *X509_LOOKUP_file(void) 43 { 44 return &x509_file_lookup; 45 } 46 47 static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, 48 long argl, char **ret, OSSL_LIB_CTX *libctx, 49 const char *propq) 50 { 51 int ok = 0; 52 const char *file; 53 54 switch (cmd) { 55 case X509_L_FILE_LOAD: 56 if (argl == X509_FILETYPE_DEFAULT) { 57 file = ossl_safe_getenv(X509_get_default_cert_file_env()); 58 if (file) 59 ok = (X509_load_cert_crl_file_ex(ctx, file, X509_FILETYPE_PEM, 60 libctx, propq) != 0); 61 62 else 63 ok = (X509_load_cert_crl_file_ex( 64 ctx, X509_get_default_cert_file(), 65 X509_FILETYPE_PEM, libctx, propq) != 0); 66 67 if (!ok) { 68 ERR_raise(ERR_LIB_X509, X509_R_LOADING_DEFAULTS); 69 } 70 } else { 71 if (argl == X509_FILETYPE_PEM) 72 ok = (X509_load_cert_crl_file_ex(ctx, argp, X509_FILETYPE_PEM, 73 libctx, propq) != 0); 74 else 75 ok = (X509_load_cert_file_ex(ctx, argp, (int)argl, libctx, 76 propq) != 0); 77 } 78 break; 79 } 80 return ok; 81 } 82 83 static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, 84 const char *argp, long argl, char **ret) 85 { 86 return by_file_ctrl_ex(ctx, cmd, argp, argl, ret, NULL, NULL); 87 } 88 89 int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, 90 OSSL_LIB_CTX *libctx, const char *propq) 91 { 92 int ret = 0; 93 BIO *in = NULL; 94 int i, count = 0; 95 X509 *x = NULL; 96 97 in = BIO_new(BIO_s_file()); 98 99 if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 100 ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); 101 goto err; 102 } 103 104 if (type != X509_FILETYPE_PEM && type != X509_FILETYPE_ASN1) { 105 ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); 106 goto err; 107 } 108 x = X509_new_ex(libctx, propq); 109 if (x == NULL) { 110 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 111 goto err; 112 } 113 114 if (type == X509_FILETYPE_PEM) { 115 for (;;) { 116 ERR_set_mark(); 117 if (PEM_read_bio_X509_AUX(in, &x, NULL, "") == NULL) { 118 if ((ERR_GET_REASON(ERR_peek_last_error()) == 119 PEM_R_NO_START_LINE) && (count > 0)) { 120 ERR_pop_to_mark(); 121 break; 122 } else { 123 ERR_clear_last_mark(); 124 goto err; 125 } 126 } 127 ERR_clear_last_mark(); 128 i = X509_STORE_add_cert(ctx->store_ctx, x); 129 if (!i) 130 goto err; 131 count++; 132 X509_free(x); 133 x = NULL; 134 } 135 ret = count; 136 } else if (type == X509_FILETYPE_ASN1) { 137 if (d2i_X509_bio(in, &x) == NULL) { 138 ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); 139 goto err; 140 } 141 i = X509_STORE_add_cert(ctx->store_ctx, x); 142 if (!i) 143 goto err; 144 ret = i; 145 } 146 if (ret == 0) 147 ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND); 148 err: 149 X509_free(x); 150 BIO_free(in); 151 return ret; 152 } 153 154 int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) 155 { 156 return X509_load_cert_file_ex(ctx, file, type, NULL, NULL); 157 } 158 159 int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) 160 { 161 int ret = 0; 162 BIO *in = NULL; 163 int i, count = 0; 164 X509_CRL *x = NULL; 165 166 in = BIO_new(BIO_s_file()); 167 168 if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 169 ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); 170 goto err; 171 } 172 173 if (type == X509_FILETYPE_PEM) { 174 for (;;) { 175 x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); 176 if (x == NULL) { 177 if ((ERR_GET_REASON(ERR_peek_last_error()) == 178 PEM_R_NO_START_LINE) && (count > 0)) { 179 ERR_clear_error(); 180 break; 181 } else { 182 ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); 183 goto err; 184 } 185 } 186 i = X509_STORE_add_crl(ctx->store_ctx, x); 187 if (!i) 188 goto err; 189 count++; 190 X509_CRL_free(x); 191 x = NULL; 192 } 193 ret = count; 194 } else if (type == X509_FILETYPE_ASN1) { 195 x = d2i_X509_CRL_bio(in, NULL); 196 if (x == NULL) { 197 ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); 198 goto err; 199 } 200 i = X509_STORE_add_crl(ctx->store_ctx, x); 201 if (!i) 202 goto err; 203 ret = i; 204 } else { 205 ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); 206 goto err; 207 } 208 if (ret == 0) 209 ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_FOUND); 210 err: 211 X509_CRL_free(x); 212 BIO_free(in); 213 return ret; 214 } 215 216 int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type, 217 OSSL_LIB_CTX *libctx, const char *propq) 218 { 219 STACK_OF(X509_INFO) *inf; 220 X509_INFO *itmp; 221 BIO *in; 222 int i, count = 0; 223 224 if (type != X509_FILETYPE_PEM) 225 return X509_load_cert_file_ex(ctx, file, type, libctx, propq); 226 in = BIO_new_file(file, "r"); 227 if (!in) { 228 ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); 229 return 0; 230 } 231 inf = PEM_X509_INFO_read_bio_ex(in, NULL, NULL, "", libctx, propq); 232 BIO_free(in); 233 if (!inf) { 234 ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); 235 return 0; 236 } 237 for (i = 0; i < sk_X509_INFO_num(inf); i++) { 238 itmp = sk_X509_INFO_value(inf, i); 239 if (itmp->x509) { 240 if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) 241 goto err; 242 count++; 243 } 244 if (itmp->crl) { 245 if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) 246 goto err; 247 count++; 248 } 249 } 250 if (count == 0) 251 ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND); 252 err: 253 sk_X509_INFO_pop_free(inf, X509_INFO_free); 254 return count; 255 } 256 257 int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) 258 { 259 return X509_load_cert_crl_file_ex(ctx, file, type, NULL, NULL); 260 } 261 262