2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
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
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"
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
;
25 OSSL_STORE_post_process_info_fn post_process
;
26 void *post_process_data
;
28 /* 0 before the first STORE_load(), 1 otherwise */
32 OSSL_STORE_CTX
*OSSL_STORE_open(const char *uri
, const UI_METHOD
*ui_method
,
34 OSSL_STORE_post_process_info_fn post_process
,
35 void *post_process_data
)
37 const OSSL_STORE_LOADER
*loader
= NULL
;
38 OSSL_STORE_LOADER_CTX
*loader_ctx
= NULL
;
39 OSSL_STORE_CTX
*ctx
= NULL
;
40 char scheme_copy
[256], *p
, *schemes
[2];
45 * Put the file scheme first. If the uri does represent an existing file,
46 * possible device name and all, then it should be loaded. Only a failed
47 * attempt at loading a local file should have us try something else.
49 schemes
[schemes_n
++] = "file";
52 * Now, check if we have something that looks like a scheme, and add it
53 * as a second scheme. However, also check if there's an authority start
54 * (://), because that will invalidate the previous file scheme. Also,
55 * check that this isn't actually the file scheme, as there's no point
56 * going through that one twice!
58 OPENSSL_strlcpy(scheme_copy
, uri
, sizeof(scheme_copy
));
59 if ((p
= strchr(scheme_copy
, ':')) != NULL
) {
61 if (strcasecmp(scheme_copy
, "file") != 0) {
62 if (strncmp(p
, "//", 2) == 0)
63 schemes_n
--; /* Invalidate the file scheme */
64 schemes
[schemes_n
++] = scheme_copy
;
70 /* Try each scheme until we find one that could open the URI */
71 for (i
= 0; loader_ctx
== NULL
&& i
< schemes_n
; i
++) {
72 if ((loader
= ossl_store_get0_loader_int(schemes
[i
])) != NULL
)
73 loader_ctx
= loader
->open(loader
, uri
, ui_method
, ui_data
);
75 if (loader_ctx
== NULL
)
78 if ((ctx
= OPENSSL_zalloc(sizeof(*ctx
))) == NULL
) {
79 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN
, ERR_R_MALLOC_FAILURE
);
84 ctx
->loader_ctx
= loader_ctx
;
85 ctx
->ui_method
= ui_method
;
86 ctx
->ui_data
= ui_data
;
87 ctx
->post_process
= post_process
;
88 ctx
->post_process_data
= post_process_data
;
91 * If the attempt to open with the 'file' scheme loader failed and the
92 * other scheme loader succeeded, the failure to open with the 'file'
93 * scheme loader leaves an error on the error stack. Let's remove it.
100 ERR_clear_last_mark();
101 if (loader_ctx
!= NULL
) {
103 * We ignore a returned error because we will return NULL anyway in
104 * this case, so if something goes wrong when closing, that'll simply
105 * just add another entry on the error stack.
107 (void)loader
->close(loader_ctx
);
112 int OSSL_STORE_ctrl(OSSL_STORE_CTX
*ctx
, int cmd
, ...)
118 ret
= OSSL_STORE_vctrl(ctx
, cmd
, args
);
124 int OSSL_STORE_vctrl(OSSL_STORE_CTX
*ctx
, int cmd
, va_list args
)
126 if (ctx
->loader
->ctrl
!= NULL
)
127 return ctx
->loader
->ctrl(ctx
->loader_ctx
, cmd
, args
);
131 OSSL_STORE_INFO
*OSSL_STORE_load(OSSL_STORE_CTX
*ctx
)
133 OSSL_STORE_INFO
*v
= NULL
;
137 if (OSSL_STORE_eof(ctx
))
140 v
= ctx
->loader
->load(ctx
->loader_ctx
, ctx
->ui_method
, ctx
->ui_data
);
142 if (ctx
->post_process
!= NULL
&& v
!= NULL
) {
143 v
= ctx
->post_process(v
, ctx
->post_process_data
);
146 * By returning NULL, the callback decides that this object should
156 int OSSL_STORE_error(OSSL_STORE_CTX
*ctx
)
158 return ctx
->loader
->error(ctx
->loader_ctx
);
161 int OSSL_STORE_eof(OSSL_STORE_CTX
*ctx
)
163 return ctx
->loader
->eof(ctx
->loader_ctx
);
166 int OSSL_STORE_close(OSSL_STORE_CTX
*ctx
)
168 int loader_ret
= ctx
->loader
->close(ctx
->loader_ctx
);
175 * Functions to generate OSSL_STORE_INFOs, one function for each type we
176 * support having in them as well as a generic constructor.
178 * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
179 * and will therefore be freed when the OSSL_STORE_INFO is freed.
181 static OSSL_STORE_INFO
*store_info_new(int type
, void *data
)
183 OSSL_STORE_INFO
*info
= OPENSSL_zalloc(sizeof(*info
));
193 OSSL_STORE_INFO
*OSSL_STORE_INFO_new_NAME(char *name
)
195 OSSL_STORE_INFO
*info
= store_info_new(OSSL_STORE_INFO_NAME
, NULL
);
198 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME
,
199 ERR_R_MALLOC_FAILURE
);
203 info
->_
.name
.name
= name
;
204 info
->_
.name
.desc
= NULL
;
209 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO
*info
, char *desc
)
211 if (info
->type
!= OSSL_STORE_INFO_NAME
) {
212 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION
,
213 ERR_R_PASSED_INVALID_ARGUMENT
);
217 info
->_
.name
.desc
= desc
;
221 OSSL_STORE_INFO
*OSSL_STORE_INFO_new_PARAMS(EVP_PKEY
*params
)
223 OSSL_STORE_INFO
*info
= store_info_new(OSSL_STORE_INFO_PARAMS
, params
);
226 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS
,
227 ERR_R_MALLOC_FAILURE
);
231 OSSL_STORE_INFO
*OSSL_STORE_INFO_new_PKEY(EVP_PKEY
*pkey
)
233 OSSL_STORE_INFO
*info
= store_info_new(OSSL_STORE_INFO_PKEY
, pkey
);
236 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY
,
237 ERR_R_MALLOC_FAILURE
);
241 OSSL_STORE_INFO
*OSSL_STORE_INFO_new_CERT(X509
*x509
)
243 OSSL_STORE_INFO
*info
= store_info_new(OSSL_STORE_INFO_CERT
, x509
);
246 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT
,
247 ERR_R_MALLOC_FAILURE
);
251 OSSL_STORE_INFO
*OSSL_STORE_INFO_new_CRL(X509_CRL
*crl
)
253 OSSL_STORE_INFO
*info
= store_info_new(OSSL_STORE_INFO_CRL
, crl
);
256 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL
,
257 ERR_R_MALLOC_FAILURE
);
262 * Functions to try to extract data from a OSSL_STORE_INFO.
264 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO
*info
)
269 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO
*info
)
271 if (info
->type
== OSSL_STORE_INFO_NAME
)
272 return info
->_
.name
.name
;
276 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO
*info
)
278 if (info
->type
== OSSL_STORE_INFO_NAME
) {
279 char *ret
= OPENSSL_strdup(info
->_
.name
.name
);
282 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME
,
283 ERR_R_MALLOC_FAILURE
);
286 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME
,
287 OSSL_STORE_R_NOT_A_NAME
);
291 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO
*info
)
293 if (info
->type
== OSSL_STORE_INFO_NAME
)
294 return info
->_
.name
.desc
;
298 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO
*info
)
300 if (info
->type
== OSSL_STORE_INFO_NAME
) {
301 char *ret
= OPENSSL_strdup(info
->_
.name
.desc
302 ? info
->_
.name
.desc
: "");
305 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION
,
306 ERR_R_MALLOC_FAILURE
);
309 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION
,
310 OSSL_STORE_R_NOT_A_NAME
);
314 EVP_PKEY
*OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO
*info
)
316 if (info
->type
== OSSL_STORE_INFO_PARAMS
)
317 return info
->_
.params
;
321 EVP_PKEY
*OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO
*info
)
323 if (info
->type
== OSSL_STORE_INFO_PARAMS
) {
324 EVP_PKEY_up_ref(info
->_
.params
);
325 return info
->_
.params
;
327 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS
,
328 OSSL_STORE_R_NOT_PARAMETERS
);
332 EVP_PKEY
*OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO
*info
)
334 if (info
->type
== OSSL_STORE_INFO_PKEY
)
339 EVP_PKEY
*OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO
*info
)
341 if (info
->type
== OSSL_STORE_INFO_PKEY
) {
342 EVP_PKEY_up_ref(info
->_
.pkey
);
345 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY
,
346 OSSL_STORE_R_NOT_A_KEY
);
350 X509
*OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO
*info
)
352 if (info
->type
== OSSL_STORE_INFO_CERT
)
357 X509
*OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO
*info
)
359 if (info
->type
== OSSL_STORE_INFO_CERT
) {
360 X509_up_ref(info
->_
.x509
);
363 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT
,
364 OSSL_STORE_R_NOT_A_CERTIFICATE
);
368 X509_CRL
*OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO
*info
)
370 if (info
->type
== OSSL_STORE_INFO_CRL
)
375 X509_CRL
*OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO
*info
)
377 if (info
->type
== OSSL_STORE_INFO_CRL
) {
378 X509_CRL_up_ref(info
->_
.crl
);
381 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL
,
382 OSSL_STORE_R_NOT_A_CRL
);
387 * Free the OSSL_STORE_INFO
389 void OSSL_STORE_INFO_free(OSSL_STORE_INFO
*info
)
392 switch (info
->type
) {
393 case OSSL_STORE_INFO_EMBEDDED
:
394 BUF_MEM_free(info
->_
.embedded
.blob
);
395 OPENSSL_free(info
->_
.embedded
.pem_name
);
397 case OSSL_STORE_INFO_NAME
:
398 OPENSSL_free(info
->_
.name
.name
);
399 OPENSSL_free(info
->_
.name
.desc
);
401 case OSSL_STORE_INFO_PARAMS
:
402 EVP_PKEY_free(info
->_
.params
);
404 case OSSL_STORE_INFO_PKEY
:
405 EVP_PKEY_free(info
->_
.pkey
);
407 case OSSL_STORE_INFO_CERT
:
408 X509_free(info
->_
.x509
);
410 case OSSL_STORE_INFO_CRL
:
411 X509_CRL_free(info
->_
.crl
);
418 /* Internal functions */
419 OSSL_STORE_INFO
*ossl_store_info_new_EMBEDDED(const char *new_pem_name
,
422 OSSL_STORE_INFO
*info
= store_info_new(OSSL_STORE_INFO_EMBEDDED
, NULL
);
425 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED
,
426 ERR_R_MALLOC_FAILURE
);
430 info
->_
.embedded
.blob
= embedded
;
431 info
->_
.embedded
.pem_name
=
432 new_pem_name
== NULL
? NULL
: OPENSSL_strdup(new_pem_name
);
434 if (new_pem_name
!= NULL
&& info
->_
.embedded
.pem_name
== NULL
) {
435 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED
,
436 ERR_R_MALLOC_FAILURE
);
437 OSSL_STORE_INFO_free(info
);
444 BUF_MEM
*ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO
*info
)
446 if (info
->type
== OSSL_STORE_INFO_EMBEDDED
)
447 return info
->_
.embedded
.blob
;
451 char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO
*info
)
453 if (info
->type
== OSSL_STORE_INFO_EMBEDDED
)
454 return info
->_
.embedded
.pem_name
;
458 OSSL_STORE_CTX
*ossl_store_attach_pem_bio(BIO
*bp
, const UI_METHOD
*ui_method
,
461 OSSL_STORE_CTX
*ctx
= NULL
;
462 const OSSL_STORE_LOADER
*loader
= NULL
;
463 OSSL_STORE_LOADER_CTX
*loader_ctx
= NULL
;
465 if ((loader
= ossl_store_get0_loader_int("file")) == NULL
466 || ((loader_ctx
= ossl_store_file_attach_pem_bio_int(bp
)) == NULL
))
468 if ((ctx
= OPENSSL_zalloc(sizeof(*ctx
))) == NULL
) {
469 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO
,
470 ERR_R_MALLOC_FAILURE
);
474 ctx
->loader
= loader
;
475 ctx
->loader_ctx
= loader_ctx
;
477 ctx
->ui_method
= ui_method
;
478 ctx
->ui_data
= ui_data
;
479 ctx
->post_process
= NULL
;
480 ctx
->post_process_data
= NULL
;
483 if (loader_ctx
!= NULL
)
485 * We ignore a returned error because we will return NULL anyway in
486 * this case, so if something goes wrong when closing, that'll simply
487 * just add another entry on the error stack.
489 (void)loader
->close(loader_ctx
);
493 int ossl_store_detach_pem_bio(OSSL_STORE_CTX
*ctx
)
495 int loader_ret
= ossl_store_file_detach_pem_bio_int(ctx
->loader_ctx
);