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