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