Make sure OSSL_STORE_load() isn't caught in an endless loop
[oweals/openssl.git] / crypto / store / store_lib.c
1 /*
2  * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 <stdlib.h>
11 #include <string.h>
12
13 #include <openssl/crypto.h>
14 #include <openssl/err.h>
15 #include <openssl/store.h>
16 #include "internal/thread_once.h"
17 #include "internal/store_int.h"
18 #include "store_locl.h"
19
20 struct ossl_store_ctx_st {
21     const OSSL_STORE_LOADER *loader;
22     OSSL_STORE_LOADER_CTX *loader_ctx;
23     const UI_METHOD *ui_method;
24     void *ui_data;
25     OSSL_STORE_post_process_info_fn post_process;
26     void *post_process_data;
27 };
28
29 OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method,
30                                 void *ui_data,
31                                 OSSL_STORE_post_process_info_fn post_process,
32                                 void *post_process_data)
33 {
34     const OSSL_STORE_LOADER *loader;
35     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
36     OSSL_STORE_CTX *ctx = NULL;
37     char scheme_copy[256], *p;
38
39     OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy));
40     if ((p = strchr(scheme_copy, ':')) != NULL) {
41         *p = '\0';
42         p = scheme_copy;
43     } else {
44         p = "file";
45     }
46
47     if ((loader = ossl_store_get0_loader_int(p)) == NULL
48         || (loader_ctx = loader->open(loader, uri, ui_method, ui_data)) == NULL)
49         goto done;
50     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
51         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE);
52         goto done;
53     }
54
55     ctx->loader = loader;
56     ctx->loader_ctx = loader_ctx;
57     loader_ctx = NULL;
58     ctx->ui_method = ui_method;
59     ctx->ui_data = ui_data;
60     ctx->post_process = post_process;
61     ctx->post_process_data = post_process_data;
62
63  done:
64     if (loader_ctx != NULL) {
65         /*
66          * We ignore a returned error because we will return NULL anyway in
67          * this case, so if something goes wrong when closing, that'll simply
68          * just add another entry on the error stack.
69          */
70         (void)loader->close(loader_ctx);
71     }
72     return ctx;
73 }
74
75 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...)
76 {
77     va_list args;
78     int ret = 0;
79
80     va_start(args, cmd);
81     if (ctx->loader->ctrl != NULL)
82         ret = ctx->loader->ctrl(ctx->loader_ctx, cmd, args);
83     va_end(args);
84
85     return ret;
86 }
87
88 OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
89 {
90     OSSL_STORE_INFO *v = NULL;
91
92  again:
93     if (OSSL_STORE_eof(ctx))
94         return NULL;
95
96     v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data);
97
98     if (ctx->post_process != NULL && v != NULL) {
99         v = ctx->post_process(v, ctx->post_process_data);
100
101         /*
102          * By returning NULL, the callback decides that this object should
103          * be ignored.
104          */
105         if (v == NULL)
106             goto again;
107     }
108
109     return v;
110 }
111
112 int OSSL_STORE_error(OSSL_STORE_CTX *ctx)
113 {
114     return ctx->loader->error(ctx->loader_ctx);
115 }
116
117 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)
118 {
119     return ctx->loader->eof(ctx->loader_ctx);
120 }
121
122 int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
123 {
124     int loader_ret = ctx->loader->close(ctx->loader_ctx);
125
126     OPENSSL_free(ctx);
127     return loader_ret;
128 }
129
130 /*
131  * Functions to generate OSSL_STORE_INFOs, one function for each type we
132  * support having in them.  Along with each of them, one macro that
133  * can be used to determine what types are supported.
134  *
135  * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
136  * and will therefore be freed when the OSSL_STORE_INFO is freed.
137  */
138 static OSSL_STORE_INFO *store_info_new(int type, void *data)
139 {
140     OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info));
141
142     if (info == NULL)
143         return NULL;
144
145     info->type = type;
146     info->_.data = data;
147     return info;
148 }
149
150 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name)
151 {
152     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL);
153
154     if (info == NULL) {
155         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME,
156                       ERR_R_MALLOC_FAILURE);
157         return NULL;
158     }
159
160     info->_.name.name = name;
161     info->_.name.desc = NULL;
162
163     return info;
164 }
165
166 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc)
167 {
168     if (info->type != OSSL_STORE_INFO_NAME) {
169         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION,
170                       ERR_R_PASSED_INVALID_ARGUMENT);
171         return 0;
172     }
173
174     info->_.name.desc = desc;
175
176     return 1;
177 }
178 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
179 {
180     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params);
181
182     if (info == NULL)
183         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS,
184                       ERR_R_MALLOC_FAILURE);
185     return info;
186 }
187
188 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
189 {
190     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey);
191
192     if (info == NULL)
193         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY,
194                       ERR_R_MALLOC_FAILURE);
195     return info;
196 }
197
198 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
199 {
200     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509);
201
202     if (info == NULL)
203         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT,
204                       ERR_R_MALLOC_FAILURE);
205     return info;
206 }
207
208 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl)
209 {
210     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl);
211
212     if (info == NULL)
213         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL,
214                       ERR_R_MALLOC_FAILURE);
215     return info;
216 }
217
218 /*
219  * Functions to try to extract data from a OSSL_STORE_INFO.
220  */
221 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info)
222 {
223     return info->type;
224 }
225
226 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info)
227 {
228     if (info->type == OSSL_STORE_INFO_NAME)
229         return info->_.name.name;
230     return NULL;
231 }
232
233 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info)
234 {
235     if (info->type == OSSL_STORE_INFO_NAME) {
236         char *ret = OPENSSL_strdup(info->_.name.name);
237
238         if (ret == NULL)
239             OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
240                           ERR_R_MALLOC_FAILURE);
241         return ret;
242     }
243     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
244                   OSSL_STORE_R_NOT_A_NAME);
245     return NULL;
246 }
247
248 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info)
249 {
250     if (info->type == OSSL_STORE_INFO_NAME)
251         return info->_.name.desc;
252     return NULL;
253 }
254
255 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info)
256 {
257     if (info->type == OSSL_STORE_INFO_NAME) {
258         char *ret = OPENSSL_strdup(info->_.name.desc
259                                    ? info->_.name.desc : "");
260
261         if (ret == NULL)
262             OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
263                      ERR_R_MALLOC_FAILURE);
264         return ret;
265     }
266     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
267                   OSSL_STORE_R_NOT_A_NAME);
268     return NULL;
269 }
270
271 EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info)
272 {
273     if (info->type == OSSL_STORE_INFO_PARAMS)
274         return info->_.params;
275     return NULL;
276 }
277
278 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info)
279 {
280     if (info->type == OSSL_STORE_INFO_PARAMS) {
281         EVP_PKEY_up_ref(info->_.params);
282         return info->_.params;
283     }
284     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS,
285                   OSSL_STORE_R_NOT_PARAMETERS);
286     return NULL;
287 }
288
289 EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info)
290 {
291     if (info->type == OSSL_STORE_INFO_PKEY)
292         return info->_.pkey;
293     return NULL;
294 }
295
296 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info)
297 {
298     if (info->type == OSSL_STORE_INFO_PKEY) {
299         EVP_PKEY_up_ref(info->_.pkey);
300         return info->_.pkey;
301     }
302     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY,
303                   OSSL_STORE_R_NOT_A_KEY);
304     return NULL;
305 }
306
307 X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info)
308 {
309     if (info->type == OSSL_STORE_INFO_CERT)
310         return info->_.x509;
311     return NULL;
312 }
313
314 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info)
315 {
316     if (info->type == OSSL_STORE_INFO_CERT) {
317         X509_up_ref(info->_.x509);
318         return info->_.x509;
319     }
320     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT,
321                   OSSL_STORE_R_NOT_A_CERTIFICATE);
322     return NULL;
323 }
324
325 X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info)
326 {
327     if (info->type == OSSL_STORE_INFO_CRL)
328         return info->_.crl;
329     return NULL;
330 }
331
332 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info)
333 {
334     if (info->type == OSSL_STORE_INFO_CRL) {
335         X509_CRL_up_ref(info->_.crl);
336         return info->_.crl;
337     }
338     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL,
339                   OSSL_STORE_R_NOT_A_CRL);
340     return NULL;
341 }
342
343 /*
344  * Free the OSSL_STORE_INFO
345  */
346 void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
347 {
348     if (info != NULL) {
349         switch (info->type) {
350         case OSSL_STORE_INFO_EMBEDDED:
351             BUF_MEM_free(info->_.embedded.blob);
352             OPENSSL_free(info->_.embedded.pem_name);
353             break;
354         case OSSL_STORE_INFO_NAME:
355             OPENSSL_free(info->_.name.name);
356             OPENSSL_free(info->_.name.desc);
357             break;
358         case OSSL_STORE_INFO_PARAMS:
359             EVP_PKEY_free(info->_.params);
360             break;
361         case OSSL_STORE_INFO_PKEY:
362             EVP_PKEY_free(info->_.pkey);
363             break;
364         case OSSL_STORE_INFO_CERT:
365             X509_free(info->_.x509);
366             break;
367         case OSSL_STORE_INFO_CRL:
368             X509_CRL_free(info->_.crl);
369             break;
370         }
371         OPENSSL_free(info);
372     }
373 }
374
375 /* Internal functions */
376 OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
377                                               BUF_MEM *embedded)
378 {
379     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL);
380
381     if (info == NULL) {
382         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
383                       ERR_R_MALLOC_FAILURE);
384         return NULL;
385     }
386
387     info->_.embedded.blob = embedded;
388     info->_.embedded.pem_name =
389         new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
390
391     if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) {
392         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
393                       ERR_R_MALLOC_FAILURE);
394         OSSL_STORE_INFO_free(info);
395         info = NULL;
396     }
397
398     return info;
399 }
400
401 BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info)
402 {
403     if (info->type == OSSL_STORE_INFO_EMBEDDED)
404         return info->_.embedded.blob;
405     return NULL;
406 }
407
408 char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
409 {
410     if (info->type == OSSL_STORE_INFO_EMBEDDED)
411         return info->_.embedded.pem_name;
412     return NULL;
413 }
414
415 OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
416                                           void *ui_data)
417 {
418     OSSL_STORE_CTX *ctx = NULL;
419     const OSSL_STORE_LOADER *loader = NULL;
420     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
421
422     if ((loader = ossl_store_get0_loader_int("file")) == NULL
423         || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL))
424         goto done;
425     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
426         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO,
427                      ERR_R_MALLOC_FAILURE);
428         goto done;
429     }
430
431     ctx->loader = loader;
432     ctx->loader_ctx = loader_ctx;
433     loader_ctx = NULL;
434     ctx->ui_method = ui_method;
435     ctx->ui_data = ui_data;
436     ctx->post_process = NULL;
437     ctx->post_process_data = NULL;
438
439  done:
440     if (loader_ctx != NULL)
441         /*
442          * We ignore a returned error because we will return NULL anyway in
443          * this case, so if something goes wrong when closing, that'll simply
444          * just add another entry on the error stack.
445          */
446         (void)loader->close(loader_ctx);
447     return ctx;
448 }
449
450 int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx)
451 {
452     int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx);
453
454     OPENSSL_free(ctx);
455     return loader_ret;
456 }