STORE: Add the possibility to specify an expected info type
[openssl.git] / crypto / store / store_lib.c
1 /*
2  * Copyright 2016-2018 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 "e_os.h"
11 #include <stdlib.h>
12 #include <string.h>
13 #include <assert.h>
14
15 #include "e_os.h"
16
17 #include <openssl/crypto.h>
18 #include <openssl/err.h>
19 #include <openssl/store.h>
20 #include "internal/thread_once.h"
21 #include "internal/store_int.h"
22 #include "store_locl.h"
23
24 struct ossl_store_ctx_st {
25     const OSSL_STORE_LOADER *loader;
26     OSSL_STORE_LOADER_CTX *loader_ctx;
27     const UI_METHOD *ui_method;
28     void *ui_data;
29     OSSL_STORE_post_process_info_fn post_process;
30     void *post_process_data;
31     int expected_type;
32
33     /* 0 before the first STORE_load(), 1 otherwise */
34     int loading;
35 };
36
37 OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method,
38                                 void *ui_data,
39                                 OSSL_STORE_post_process_info_fn post_process,
40                                 void *post_process_data)
41 {
42     const OSSL_STORE_LOADER *loader = NULL;
43     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
44     OSSL_STORE_CTX *ctx = NULL;
45     char scheme_copy[256], *p, *schemes[2];
46     size_t schemes_n = 0;
47     size_t i;
48
49     /*
50      * Put the file scheme first.  If the uri does represent an existing file,
51      * possible device name and all, then it should be loaded.  Only a failed
52      * attempt at loading a local file should have us try something else.
53      */
54     schemes[schemes_n++] = "file";
55
56     /*
57      * Now, check if we have something that looks like a scheme, and add it
58      * as a second scheme.  However, also check if there's an authority start
59      * (://), because that will invalidate the previous file scheme.  Also,
60      * check that this isn't actually the file scheme, as there's no point
61      * going through that one twice!
62      */
63     OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy));
64     if ((p = strchr(scheme_copy, ':')) != NULL) {
65         *p++ = '\0';
66         if (strcasecmp(scheme_copy, "file") != 0) {
67             if (strncmp(p, "//", 2) == 0)
68                 schemes_n--;         /* Invalidate the file scheme */
69             schemes[schemes_n++] = scheme_copy;
70         }
71     }
72
73     ERR_set_mark();
74
75     /* Try each scheme until we find one that could open the URI */
76     for (i = 0; loader_ctx == NULL && i < schemes_n; i++) {
77         if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL)
78             loader_ctx = loader->open(loader, uri, ui_method, ui_data);
79     }
80     if (loader_ctx == NULL)
81         goto err;
82
83     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
84         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE);
85         goto err;
86     }
87
88     ctx->loader = loader;
89     ctx->loader_ctx = loader_ctx;
90     ctx->ui_method = ui_method;
91     ctx->ui_data = ui_data;
92     ctx->post_process = post_process;
93     ctx->post_process_data = post_process_data;
94
95     /*
96      * If the attempt to open with the 'file' scheme loader failed and the
97      * other scheme loader succeeded, the failure to open with the 'file'
98      * scheme loader leaves an error on the error stack.  Let's remove it.
99      */
100     ERR_pop_to_mark();
101
102     return ctx;
103
104  err:
105     ERR_clear_last_mark();
106     if (loader_ctx != NULL) {
107         /*
108          * We ignore a returned error because we will return NULL anyway in
109          * this case, so if something goes wrong when closing, that'll simply
110          * just add another entry on the error stack.
111          */
112         (void)loader->close(loader_ctx);
113     }
114     return NULL;
115 }
116
117 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...)
118 {
119     va_list args;
120     int ret;
121
122     va_start(args, cmd);
123     ret = OSSL_STORE_vctrl(ctx, cmd, args);
124     va_end(args);
125
126     return ret;
127 }
128
129 int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args)
130 {
131     if (ctx->loader->ctrl != NULL)
132         return ctx->loader->ctrl(ctx->loader_ctx, cmd, args);
133     return 0;
134 }
135
136 int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type)
137 {
138     if (ctx->loading) {
139         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_EXPECT,
140                       OSSL_STORE_R_LOADING_STARTED);
141         return 0;
142     }
143
144     ctx->expected_type = expected_type;
145     if (ctx->loader->expect != NULL)
146         return ctx->loader->expect(ctx->loader_ctx, expected_type);
147     return 1;
148 }
149
150 OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
151 {
152     OSSL_STORE_INFO *v = NULL;
153
154     ctx->loading = 1;
155  again:
156     if (OSSL_STORE_eof(ctx))
157         return NULL;
158
159     v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data);
160
161     if (ctx->post_process != NULL && v != NULL) {
162         v = ctx->post_process(v, ctx->post_process_data);
163
164         /*
165          * By returning NULL, the callback decides that this object should
166          * be ignored.
167          */
168         if (v == NULL)
169             goto again;
170     }
171
172     if (v != NULL && ctx->expected_type != 0) {
173         int returned_type = OSSL_STORE_INFO_get_type(v);
174
175         if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) {
176             /*
177              * Soft assert here so those who want to harsly weed out faulty
178              * loaders can do so using a debugging version of libcrypto.
179              */
180             if (ctx->loader->expect != NULL)
181                 assert(ctx->expected_type == returned_type);
182
183             if (ctx->expected_type != returned_type) {
184                 OSSL_STORE_INFO_free(v);
185                 goto again;
186             }
187         }
188     }
189
190     return v;
191 }
192
193 int OSSL_STORE_error(OSSL_STORE_CTX *ctx)
194 {
195     return ctx->loader->error(ctx->loader_ctx);
196 }
197
198 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)
199 {
200     return ctx->loader->eof(ctx->loader_ctx);
201 }
202
203 int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
204 {
205     int loader_ret = ctx->loader->close(ctx->loader_ctx);
206
207     OPENSSL_free(ctx);
208     return loader_ret;
209 }
210
211 /*
212  * Functions to generate OSSL_STORE_INFOs, one function for each type we
213  * support having in them as well as a generic constructor.
214  *
215  * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
216  * and will therefore be freed when the OSSL_STORE_INFO is freed.
217  */
218 static OSSL_STORE_INFO *store_info_new(int type, void *data)
219 {
220     OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info));
221
222     if (info == NULL)
223         return NULL;
224
225     info->type = type;
226     info->_.data = data;
227     return info;
228 }
229
230 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name)
231 {
232     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL);
233
234     if (info == NULL) {
235         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME,
236                       ERR_R_MALLOC_FAILURE);
237         return NULL;
238     }
239
240     info->_.name.name = name;
241     info->_.name.desc = NULL;
242
243     return info;
244 }
245
246 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc)
247 {
248     if (info->type != OSSL_STORE_INFO_NAME) {
249         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION,
250                       ERR_R_PASSED_INVALID_ARGUMENT);
251         return 0;
252     }
253
254     info->_.name.desc = desc;
255
256     return 1;
257 }
258 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
259 {
260     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params);
261
262     if (info == NULL)
263         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS,
264                       ERR_R_MALLOC_FAILURE);
265     return info;
266 }
267
268 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
269 {
270     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey);
271
272     if (info == NULL)
273         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY,
274                       ERR_R_MALLOC_FAILURE);
275     return info;
276 }
277
278 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
279 {
280     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509);
281
282     if (info == NULL)
283         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT,
284                       ERR_R_MALLOC_FAILURE);
285     return info;
286 }
287
288 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl)
289 {
290     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl);
291
292     if (info == NULL)
293         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL,
294                       ERR_R_MALLOC_FAILURE);
295     return info;
296 }
297
298 /*
299  * Functions to try to extract data from a OSSL_STORE_INFO.
300  */
301 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info)
302 {
303     return info->type;
304 }
305
306 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info)
307 {
308     if (info->type == OSSL_STORE_INFO_NAME)
309         return info->_.name.name;
310     return NULL;
311 }
312
313 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info)
314 {
315     if (info->type == OSSL_STORE_INFO_NAME) {
316         char *ret = OPENSSL_strdup(info->_.name.name);
317
318         if (ret == NULL)
319             OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
320                           ERR_R_MALLOC_FAILURE);
321         return ret;
322     }
323     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
324                   OSSL_STORE_R_NOT_A_NAME);
325     return NULL;
326 }
327
328 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info)
329 {
330     if (info->type == OSSL_STORE_INFO_NAME)
331         return info->_.name.desc;
332     return NULL;
333 }
334
335 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info)
336 {
337     if (info->type == OSSL_STORE_INFO_NAME) {
338         char *ret = OPENSSL_strdup(info->_.name.desc
339                                    ? info->_.name.desc : "");
340
341         if (ret == NULL)
342             OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
343                      ERR_R_MALLOC_FAILURE);
344         return ret;
345     }
346     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
347                   OSSL_STORE_R_NOT_A_NAME);
348     return NULL;
349 }
350
351 EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info)
352 {
353     if (info->type == OSSL_STORE_INFO_PARAMS)
354         return info->_.params;
355     return NULL;
356 }
357
358 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info)
359 {
360     if (info->type == OSSL_STORE_INFO_PARAMS) {
361         EVP_PKEY_up_ref(info->_.params);
362         return info->_.params;
363     }
364     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS,
365                   OSSL_STORE_R_NOT_PARAMETERS);
366     return NULL;
367 }
368
369 EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info)
370 {
371     if (info->type == OSSL_STORE_INFO_PKEY)
372         return info->_.pkey;
373     return NULL;
374 }
375
376 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info)
377 {
378     if (info->type == OSSL_STORE_INFO_PKEY) {
379         EVP_PKEY_up_ref(info->_.pkey);
380         return info->_.pkey;
381     }
382     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY,
383                   OSSL_STORE_R_NOT_A_KEY);
384     return NULL;
385 }
386
387 X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info)
388 {
389     if (info->type == OSSL_STORE_INFO_CERT)
390         return info->_.x509;
391     return NULL;
392 }
393
394 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info)
395 {
396     if (info->type == OSSL_STORE_INFO_CERT) {
397         X509_up_ref(info->_.x509);
398         return info->_.x509;
399     }
400     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT,
401                   OSSL_STORE_R_NOT_A_CERTIFICATE);
402     return NULL;
403 }
404
405 X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info)
406 {
407     if (info->type == OSSL_STORE_INFO_CRL)
408         return info->_.crl;
409     return NULL;
410 }
411
412 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info)
413 {
414     if (info->type == OSSL_STORE_INFO_CRL) {
415         X509_CRL_up_ref(info->_.crl);
416         return info->_.crl;
417     }
418     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL,
419                   OSSL_STORE_R_NOT_A_CRL);
420     return NULL;
421 }
422
423 /*
424  * Free the OSSL_STORE_INFO
425  */
426 void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
427 {
428     if (info != NULL) {
429         switch (info->type) {
430         case OSSL_STORE_INFO_EMBEDDED:
431             BUF_MEM_free(info->_.embedded.blob);
432             OPENSSL_free(info->_.embedded.pem_name);
433             break;
434         case OSSL_STORE_INFO_NAME:
435             OPENSSL_free(info->_.name.name);
436             OPENSSL_free(info->_.name.desc);
437             break;
438         case OSSL_STORE_INFO_PARAMS:
439             EVP_PKEY_free(info->_.params);
440             break;
441         case OSSL_STORE_INFO_PKEY:
442             EVP_PKEY_free(info->_.pkey);
443             break;
444         case OSSL_STORE_INFO_CERT:
445             X509_free(info->_.x509);
446             break;
447         case OSSL_STORE_INFO_CRL:
448             X509_CRL_free(info->_.crl);
449             break;
450         }
451         OPENSSL_free(info);
452     }
453 }
454
455 /* Internal functions */
456 OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
457                                               BUF_MEM *embedded)
458 {
459     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL);
460
461     if (info == NULL) {
462         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
463                       ERR_R_MALLOC_FAILURE);
464         return NULL;
465     }
466
467     info->_.embedded.blob = embedded;
468     info->_.embedded.pem_name =
469         new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
470
471     if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) {
472         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
473                       ERR_R_MALLOC_FAILURE);
474         OSSL_STORE_INFO_free(info);
475         info = NULL;
476     }
477
478     return info;
479 }
480
481 BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info)
482 {
483     if (info->type == OSSL_STORE_INFO_EMBEDDED)
484         return info->_.embedded.blob;
485     return NULL;
486 }
487
488 char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
489 {
490     if (info->type == OSSL_STORE_INFO_EMBEDDED)
491         return info->_.embedded.pem_name;
492     return NULL;
493 }
494
495 OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
496                                           void *ui_data)
497 {
498     OSSL_STORE_CTX *ctx = NULL;
499     const OSSL_STORE_LOADER *loader = NULL;
500     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
501
502     if ((loader = ossl_store_get0_loader_int("file")) == NULL
503         || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL))
504         goto done;
505     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
506         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO,
507                      ERR_R_MALLOC_FAILURE);
508         goto done;
509     }
510
511     ctx->loader = loader;
512     ctx->loader_ctx = loader_ctx;
513     loader_ctx = NULL;
514     ctx->ui_method = ui_method;
515     ctx->ui_data = ui_data;
516     ctx->post_process = NULL;
517     ctx->post_process_data = NULL;
518
519  done:
520     if (loader_ctx != NULL)
521         /*
522          * We ignore a returned error because we will return NULL anyway in
523          * this case, so if something goes wrong when closing, that'll simply
524          * just add another entry on the error stack.
525          */
526         (void)loader->close(loader_ctx);
527     return ctx;
528 }
529
530 int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx)
531 {
532     int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx);
533
534     OPENSSL_free(ctx);
535     return loader_ret;
536 }