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