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