xref: /freebsd/crypto/openssl/crypto/x509/by_file.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
374664626SKris Kennaway  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
874664626SKris Kennaway  */
974664626SKris Kennaway 
1074664626SKris Kennaway #include <stdio.h>
1174664626SKris Kennaway #include <time.h>
1274664626SKris Kennaway #include <errno.h>
1374664626SKris Kennaway 
14e71b7053SJung-uk Kim #include "internal/cryptlib.h"
1574664626SKris Kennaway #include <openssl/buffer.h>
1674664626SKris Kennaway #include <openssl/x509.h>
1774664626SKris Kennaway #include <openssl/pem.h>
1817f01e99SJung-uk Kim #include "x509_local.h"
1974664626SKris Kennaway 
2074664626SKris Kennaway static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
2174664626SKris Kennaway                         long argl, char **ret);
22*b077aed3SPierre Pronchery static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc,
23*b077aed3SPierre Pronchery                            long argl, char **ret, OSSL_LIB_CTX *libctx,
24*b077aed3SPierre Pronchery                            const char *propq);
25*b077aed3SPierre Pronchery 
26*b077aed3SPierre Pronchery 
27e71b7053SJung-uk Kim static X509_LOOKUP_METHOD x509_file_lookup = {
2874664626SKris Kennaway     "Load file into cache",
29e71b7053SJung-uk Kim     NULL,                       /* new_item */
3074664626SKris Kennaway     NULL,                       /* free */
3174664626SKris Kennaway     NULL,                       /* init */
3274664626SKris Kennaway     NULL,                       /* shutdown */
3374664626SKris Kennaway     by_file_ctrl,               /* ctrl */
3474664626SKris Kennaway     NULL,                       /* get_by_subject */
3574664626SKris Kennaway     NULL,                       /* get_by_issuer_serial */
3674664626SKris Kennaway     NULL,                       /* get_by_fingerprint */
3774664626SKris Kennaway     NULL,                       /* get_by_alias */
38*b077aed3SPierre Pronchery     NULL,                       /* get_by_subject_ex */
39*b077aed3SPierre Pronchery     by_file_ctrl_ex,            /* ctrl_ex */
4074664626SKris Kennaway };
4174664626SKris Kennaway 
X509_LOOKUP_file(void)4274664626SKris Kennaway X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
4374664626SKris Kennaway {
44e71b7053SJung-uk Kim     return &x509_file_lookup;
4574664626SKris Kennaway }
4674664626SKris Kennaway 
by_file_ctrl_ex(X509_LOOKUP * ctx,int cmd,const char * argp,long argl,char ** ret,OSSL_LIB_CTX * libctx,const char * propq)47*b077aed3SPierre Pronchery static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp,
48*b077aed3SPierre Pronchery                            long argl, char **ret, OSSL_LIB_CTX *libctx,
49*b077aed3SPierre Pronchery                            const char *propq)
5074664626SKris Kennaway {
51f579bf8eSKris Kennaway     int ok = 0;
5247902a71SJung-uk Kim     const char *file;
5374664626SKris Kennaway 
546f9291ceSJung-uk Kim     switch (cmd) {
5574664626SKris Kennaway     case X509_L_FILE_LOAD:
566f9291ceSJung-uk Kim         if (argl == X509_FILETYPE_DEFAULT) {
57c9cf7b5cSJung-uk Kim             file = ossl_safe_getenv(X509_get_default_cert_file_env());
585c87c606SMark Murray             if (file)
59*b077aed3SPierre Pronchery                 ok = (X509_load_cert_crl_file_ex(ctx, file, X509_FILETYPE_PEM,
60*b077aed3SPierre Pronchery                                                  libctx, propq) != 0);
615c87c606SMark Murray 
625c87c606SMark Murray             else
63*b077aed3SPierre Pronchery                 ok = (X509_load_cert_crl_file_ex(
64*b077aed3SPierre Pronchery                          ctx, X509_get_default_cert_file(),
65*b077aed3SPierre Pronchery                          X509_FILETYPE_PEM, libctx, propq) != 0);
665c87c606SMark Murray 
676f9291ceSJung-uk Kim             if (!ok) {
68*b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_X509, X509_R_LOADING_DEFAULTS);
6974664626SKris Kennaway             }
706f9291ceSJung-uk Kim         } else {
71f579bf8eSKris Kennaway             if (argl == X509_FILETYPE_PEM)
72*b077aed3SPierre Pronchery                 ok = (X509_load_cert_crl_file_ex(ctx, argp, X509_FILETYPE_PEM,
73*b077aed3SPierre Pronchery                                                  libctx, propq) != 0);
74f579bf8eSKris Kennaway             else
75*b077aed3SPierre Pronchery                 ok = (X509_load_cert_file_ex(ctx, argp, (int)argl, libctx,
76*b077aed3SPierre Pronchery                                              propq) != 0);
7774664626SKris Kennaway         }
7874664626SKris Kennaway         break;
7974664626SKris Kennaway     }
80e71b7053SJung-uk Kim     return ok;
8174664626SKris Kennaway }
8274664626SKris Kennaway 
by_file_ctrl(X509_LOOKUP * ctx,int cmd,const char * argp,long argl,char ** ret)83*b077aed3SPierre Pronchery static int by_file_ctrl(X509_LOOKUP *ctx, int cmd,
84*b077aed3SPierre Pronchery                         const char *argp, long argl, char **ret)
85*b077aed3SPierre Pronchery {
86*b077aed3SPierre Pronchery     return by_file_ctrl_ex(ctx, cmd, argp, argl, ret, NULL, NULL);
87*b077aed3SPierre Pronchery }
88*b077aed3SPierre Pronchery 
X509_load_cert_file_ex(X509_LOOKUP * ctx,const char * file,int type,OSSL_LIB_CTX * libctx,const char * propq)89*b077aed3SPierre Pronchery int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type,
90*b077aed3SPierre Pronchery                            OSSL_LIB_CTX *libctx, const char *propq)
9174664626SKris Kennaway {
9274664626SKris Kennaway     int ret = 0;
9374664626SKris Kennaway     BIO *in = NULL;
9474664626SKris Kennaway     int i, count = 0;
9574664626SKris Kennaway     X509 *x = NULL;
9674664626SKris Kennaway 
97e71b7053SJung-uk Kim     in = BIO_new(BIO_s_file());
9874664626SKris Kennaway 
996f9291ceSJung-uk Kim     if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
100*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB);
101*b077aed3SPierre Pronchery         goto err;
102*b077aed3SPierre Pronchery     }
103*b077aed3SPierre Pronchery 
104*b077aed3SPierre Pronchery     if (type != X509_FILETYPE_PEM && type != X509_FILETYPE_ASN1) {
105*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE);
106*b077aed3SPierre Pronchery         goto err;
107*b077aed3SPierre Pronchery     }
108*b077aed3SPierre Pronchery     x = X509_new_ex(libctx, propq);
109*b077aed3SPierre Pronchery     if (x == NULL) {
110*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
11174664626SKris Kennaway         goto err;
11274664626SKris Kennaway     }
11374664626SKris Kennaway 
1146f9291ceSJung-uk Kim     if (type == X509_FILETYPE_PEM) {
1156f9291ceSJung-uk Kim         for (;;) {
116*b077aed3SPierre Pronchery             ERR_set_mark();
117*b077aed3SPierre Pronchery             if (PEM_read_bio_X509_AUX(in, &x, NULL, "") == NULL) {
1183b4e3dcbSSimon L. B. Nielsen                 if ((ERR_GET_REASON(ERR_peek_last_error()) ==
1196f9291ceSJung-uk Kim                      PEM_R_NO_START_LINE) && (count > 0)) {
120*b077aed3SPierre Pronchery                     ERR_pop_to_mark();
12174664626SKris Kennaway                     break;
1226f9291ceSJung-uk Kim                 } else {
123*b077aed3SPierre Pronchery                     ERR_clear_last_mark();
12474664626SKris Kennaway                     goto err;
12574664626SKris Kennaway                 }
12674664626SKris Kennaway             }
127*b077aed3SPierre Pronchery             ERR_clear_last_mark();
12874664626SKris Kennaway             i = X509_STORE_add_cert(ctx->store_ctx, x);
1296f9291ceSJung-uk Kim             if (!i)
1306f9291ceSJung-uk Kim                 goto err;
13174664626SKris Kennaway             count++;
13274664626SKris Kennaway             X509_free(x);
13374664626SKris Kennaway             x = NULL;
13474664626SKris Kennaway         }
13574664626SKris Kennaway         ret = count;
1366f9291ceSJung-uk Kim     } else if (type == X509_FILETYPE_ASN1) {
137*b077aed3SPierre Pronchery         if (d2i_X509_bio(in, &x) == NULL) {
138*b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
13974664626SKris Kennaway             goto err;
14074664626SKris Kennaway         }
14174664626SKris Kennaway         i = X509_STORE_add_cert(ctx->store_ctx, x);
1426f9291ceSJung-uk Kim         if (!i)
1436f9291ceSJung-uk Kim             goto err;
14474664626SKris Kennaway         ret = i;
14574664626SKris Kennaway     }
146e71b7053SJung-uk Kim     if (ret == 0)
147*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND);
14874664626SKris Kennaway  err:
1496f9291ceSJung-uk Kim     X509_free(x);
1506f9291ceSJung-uk Kim     BIO_free(in);
151e71b7053SJung-uk Kim     return ret;
15274664626SKris Kennaway }
15374664626SKris Kennaway 
X509_load_cert_file(X509_LOOKUP * ctx,const char * file,int type)154*b077aed3SPierre Pronchery int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
155*b077aed3SPierre Pronchery {
156*b077aed3SPierre Pronchery     return X509_load_cert_file_ex(ctx, file, type, NULL, NULL);
157*b077aed3SPierre Pronchery }
158*b077aed3SPierre Pronchery 
X509_load_crl_file(X509_LOOKUP * ctx,const char * file,int type)15974664626SKris Kennaway int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
16074664626SKris Kennaway {
16174664626SKris Kennaway     int ret = 0;
16274664626SKris Kennaway     BIO *in = NULL;
16374664626SKris Kennaway     int i, count = 0;
16474664626SKris Kennaway     X509_CRL *x = NULL;
16574664626SKris Kennaway 
166e71b7053SJung-uk Kim     in = BIO_new(BIO_s_file());
16774664626SKris Kennaway 
1686f9291ceSJung-uk Kim     if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
169*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB);
17074664626SKris Kennaway         goto err;
17174664626SKris Kennaway     }
17274664626SKris Kennaway 
1736f9291ceSJung-uk Kim     if (type == X509_FILETYPE_PEM) {
1746f9291ceSJung-uk Kim         for (;;) {
17547902a71SJung-uk Kim             x = PEM_read_bio_X509_CRL(in, NULL, NULL, "");
1766f9291ceSJung-uk Kim             if (x == NULL) {
1773b4e3dcbSSimon L. B. Nielsen                 if ((ERR_GET_REASON(ERR_peek_last_error()) ==
1786f9291ceSJung-uk Kim                      PEM_R_NO_START_LINE) && (count > 0)) {
17974664626SKris Kennaway                     ERR_clear_error();
18074664626SKris Kennaway                     break;
1816f9291ceSJung-uk Kim                 } else {
182*b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB);
18374664626SKris Kennaway                     goto err;
18474664626SKris Kennaway                 }
18574664626SKris Kennaway             }
18674664626SKris Kennaway             i = X509_STORE_add_crl(ctx->store_ctx, x);
1876f9291ceSJung-uk Kim             if (!i)
1886f9291ceSJung-uk Kim                 goto err;
18974664626SKris Kennaway             count++;
19074664626SKris Kennaway             X509_CRL_free(x);
19174664626SKris Kennaway             x = NULL;
19274664626SKris Kennaway         }
19374664626SKris Kennaway         ret = count;
1946f9291ceSJung-uk Kim     } else if (type == X509_FILETYPE_ASN1) {
19574664626SKris Kennaway         x = d2i_X509_CRL_bio(in, NULL);
1966f9291ceSJung-uk Kim         if (x == NULL) {
197*b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
19874664626SKris Kennaway             goto err;
19974664626SKris Kennaway         }
20074664626SKris Kennaway         i = X509_STORE_add_crl(ctx->store_ctx, x);
2016f9291ceSJung-uk Kim         if (!i)
2026f9291ceSJung-uk Kim             goto err;
20374664626SKris Kennaway         ret = i;
2046f9291ceSJung-uk Kim     } else {
205*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE);
20674664626SKris Kennaway         goto err;
20774664626SKris Kennaway     }
208e71b7053SJung-uk Kim     if (ret == 0)
209*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_FOUND);
21074664626SKris Kennaway  err:
2116f9291ceSJung-uk Kim     X509_CRL_free(x);
2126f9291ceSJung-uk Kim     BIO_free(in);
213e71b7053SJung-uk Kim     return ret;
21474664626SKris Kennaway }
21574664626SKris Kennaway 
X509_load_cert_crl_file_ex(X509_LOOKUP * ctx,const char * file,int type,OSSL_LIB_CTX * libctx,const char * propq)216*b077aed3SPierre Pronchery int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type,
217*b077aed3SPierre Pronchery                                OSSL_LIB_CTX *libctx, const char *propq)
218f579bf8eSKris Kennaway {
219f579bf8eSKris Kennaway     STACK_OF(X509_INFO) *inf;
220f579bf8eSKris Kennaway     X509_INFO *itmp;
221f579bf8eSKris Kennaway     BIO *in;
222f579bf8eSKris Kennaway     int i, count = 0;
223e71b7053SJung-uk Kim 
224f579bf8eSKris Kennaway     if (type != X509_FILETYPE_PEM)
225*b077aed3SPierre Pronchery         return X509_load_cert_file_ex(ctx, file, type, libctx, propq);
226f579bf8eSKris Kennaway     in = BIO_new_file(file, "r");
227f579bf8eSKris Kennaway     if (!in) {
228*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB);
229f579bf8eSKris Kennaway         return 0;
230f579bf8eSKris Kennaway     }
231*b077aed3SPierre Pronchery     inf = PEM_X509_INFO_read_bio_ex(in, NULL, NULL, "", libctx, propq);
232f579bf8eSKris Kennaway     BIO_free(in);
233f579bf8eSKris Kennaway     if (!inf) {
234*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB);
235f579bf8eSKris Kennaway         return 0;
236f579bf8eSKris Kennaway     }
237f579bf8eSKris Kennaway     for (i = 0; i < sk_X509_INFO_num(inf); i++) {
238f579bf8eSKris Kennaway         itmp = sk_X509_INFO_value(inf, i);
239f579bf8eSKris Kennaway         if (itmp->x509) {
240e71b7053SJung-uk Kim             if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509))
241e71b7053SJung-uk Kim                 goto err;
242f579bf8eSKris Kennaway             count++;
24350ef0093SJacques Vidrine         }
24450ef0093SJacques Vidrine         if (itmp->crl) {
245e71b7053SJung-uk Kim             if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl))
246e71b7053SJung-uk Kim                 goto err;
247f579bf8eSKris Kennaway             count++;
248f579bf8eSKris Kennaway         }
249f579bf8eSKris Kennaway     }
250e71b7053SJung-uk Kim     if (count == 0)
251*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
252e71b7053SJung-uk Kim  err:
253f579bf8eSKris Kennaway     sk_X509_INFO_pop_free(inf, X509_INFO_free);
254f579bf8eSKris Kennaway     return count;
255f579bf8eSKris Kennaway }
256*b077aed3SPierre Pronchery 
X509_load_cert_crl_file(X509_LOOKUP * ctx,const char * file,int type)257*b077aed3SPierre Pronchery int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
258*b077aed3SPierre Pronchery {
259*b077aed3SPierre Pronchery     return X509_load_cert_crl_file_ex(ctx, file, type, NULL, NULL);
260*b077aed3SPierre Pronchery }
261*b077aed3SPierre Pronchery 
262