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