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