2 * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
10 #include "crypto/cryptlib.h"
11 #include <openssl/conf.h>
12 #include "internal/thread_once.h"
13 #include "internal/property.h"
14 #include "internal/cryptlib.h"
15 #include "internal/core.h"
16 #include "internal/bio.h"
17 #include "internal/provider.h"
18 #include "crypto/decoder.h"
19 #include "crypto/context.h"
21 struct ossl_lib_ctx_st
{
22 CRYPTO_RWLOCK
*lock
, *rand_crngt_lock
;
23 OSSL_EX_DATA_GLOBAL global
;
25 void *property_string_data
;
26 void *evp_method_store
;
30 void *global_properties
;
33 CRYPTO_THREAD_LOCAL rcu_local_key
;
38 OSSL_METHOD_STORE
*decoder_store
;
40 OSSL_METHOD_STORE
*encoder_store
;
41 OSSL_METHOD_STORE
*store_loader_store
;
44 #if defined(OPENSSL_THREADS)
49 void *thread_event_handler
;
52 STACK_OF(SSL_COMP
) *comp_methods
;
58 int ossl_lib_ctx_write_lock(OSSL_LIB_CTX
*ctx
)
60 return CRYPTO_THREAD_write_lock(ossl_lib_ctx_get_concrete(ctx
)->lock
);
63 int ossl_lib_ctx_read_lock(OSSL_LIB_CTX
*ctx
)
65 return CRYPTO_THREAD_read_lock(ossl_lib_ctx_get_concrete(ctx
)->lock
);
68 int ossl_lib_ctx_unlock(OSSL_LIB_CTX
*ctx
)
70 return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx
)->lock
);
73 int ossl_lib_ctx_is_child(OSSL_LIB_CTX
*ctx
)
75 ctx
= ossl_lib_ctx_get_concrete(ctx
);
82 static void context_deinit_objs(OSSL_LIB_CTX
*ctx
);
84 static int context_init(OSSL_LIB_CTX
*ctx
)
88 if (!CRYPTO_THREAD_init_local(&ctx
->rcu_local_key
, NULL
))
91 ctx
->lock
= CRYPTO_THREAD_lock_new();
92 if (ctx
->lock
== NULL
)
95 ctx
->rand_crngt_lock
= CRYPTO_THREAD_lock_new();
96 if (ctx
->rand_crngt_lock
== NULL
)
99 /* Initialize ex_data. */
100 if (!ossl_do_ex_data_init(ctx
))
104 /* P2. We want evp_method_store to be cleaned up before the provider store */
105 ctx
->evp_method_store
= ossl_method_store_new(ctx
);
106 if (ctx
->evp_method_store
== NULL
)
110 /* P2. Must be freed before the provider store is freed */
111 ctx
->provider_conf
= ossl_prov_conf_ctx_new(ctx
);
112 if (ctx
->provider_conf
== NULL
)
117 ctx
->drbg
= ossl_rand_ctx_new(ctx
);
118 if (ctx
->drbg
== NULL
)
123 * P2. We want decoder_store/decoder_cache to be cleaned up before the
126 ctx
->decoder_store
= ossl_method_store_new(ctx
);
127 if (ctx
->decoder_store
== NULL
)
129 ctx
->decoder_cache
= ossl_decoder_cache_new(ctx
);
130 if (ctx
->decoder_cache
== NULL
)
133 /* P2. We want encoder_store to be cleaned up before the provider store */
134 ctx
->encoder_store
= ossl_method_store_new(ctx
);
135 if (ctx
->encoder_store
== NULL
)
138 /* P2. We want loader_store to be cleaned up before the provider store */
139 ctx
->store_loader_store
= ossl_method_store_new(ctx
);
140 if (ctx
->store_loader_store
== NULL
)
144 /* P1. Needs to be freed before the child provider data is freed */
145 ctx
->provider_store
= ossl_provider_store_new(ctx
);
146 if (ctx
->provider_store
== NULL
)
149 /* Default priority. */
150 ctx
->property_string_data
= ossl_property_string_data_new(ctx
);
151 if (ctx
->property_string_data
== NULL
)
154 ctx
->namemap
= ossl_stored_namemap_new(ctx
);
155 if (ctx
->namemap
== NULL
)
158 ctx
->property_defns
= ossl_property_defns_new(ctx
);
159 if (ctx
->property_defns
== NULL
)
162 ctx
->global_properties
= ossl_ctx_global_properties_new(ctx
);
163 if (ctx
->global_properties
== NULL
)
167 ctx
->bio_core
= ossl_bio_core_globals_new(ctx
);
168 if (ctx
->bio_core
== NULL
)
172 ctx
->drbg_nonce
= ossl_prov_drbg_nonce_ctx_new(ctx
);
173 if (ctx
->drbg_nonce
== NULL
)
177 ctx
->self_test_cb
= ossl_self_test_set_callback_new(ctx
);
178 if (ctx
->self_test_cb
== NULL
)
183 ctx
->thread_event_handler
= ossl_thread_event_ctx_new(ctx
);
184 if (ctx
->thread_event_handler
== NULL
)
187 ctx
->fips_prov
= ossl_fips_prov_ossl_ctx_new(ctx
);
188 if (ctx
->fips_prov
== NULL
)
192 #ifndef OPENSSL_NO_THREAD_POOL
193 ctx
->threads
= ossl_threads_ctx_new(ctx
);
194 if (ctx
->threads
== NULL
)
200 ctx
->child_provider
= ossl_child_prov_ctx_new(ctx
);
201 if (ctx
->child_provider
== NULL
)
205 /* Everything depends on properties, so we also pre-initialise that */
206 if (!ossl_property_parse_init(ctx
))
210 ctx
->comp_methods
= ossl_load_builtin_compressions();
216 context_deinit_objs(ctx
);
219 ossl_crypto_cleanup_all_ex_data_int(ctx
);
221 CRYPTO_THREAD_lock_free(ctx
->rand_crngt_lock
);
222 CRYPTO_THREAD_lock_free(ctx
->lock
);
223 CRYPTO_THREAD_cleanup_local(&ctx
->rcu_local_key
);
224 memset(ctx
, '\0', sizeof(*ctx
));
228 static void context_deinit_objs(OSSL_LIB_CTX
*ctx
)
230 /* P2. We want evp_method_store to be cleaned up before the provider store */
231 if (ctx
->evp_method_store
!= NULL
) {
232 ossl_method_store_free(ctx
->evp_method_store
);
233 ctx
->evp_method_store
= NULL
;
237 if (ctx
->drbg
!= NULL
) {
238 ossl_rand_ctx_free(ctx
->drbg
);
244 if (ctx
->provider_conf
!= NULL
) {
245 ossl_prov_conf_ctx_free(ctx
->provider_conf
);
246 ctx
->provider_conf
= NULL
;
250 * P2. We want decoder_store/decoder_cache to be cleaned up before the
253 if (ctx
->decoder_store
!= NULL
) {
254 ossl_method_store_free(ctx
->decoder_store
);
255 ctx
->decoder_store
= NULL
;
257 if (ctx
->decoder_cache
!= NULL
) {
258 ossl_decoder_cache_free(ctx
->decoder_cache
);
259 ctx
->decoder_cache
= NULL
;
263 /* P2. We want encoder_store to be cleaned up before the provider store */
264 if (ctx
->encoder_store
!= NULL
) {
265 ossl_method_store_free(ctx
->encoder_store
);
266 ctx
->encoder_store
= NULL
;
269 /* P2. We want loader_store to be cleaned up before the provider store */
270 if (ctx
->store_loader_store
!= NULL
) {
271 ossl_method_store_free(ctx
->store_loader_store
);
272 ctx
->store_loader_store
= NULL
;
276 /* P1. Needs to be freed before the child provider data is freed */
277 if (ctx
->provider_store
!= NULL
) {
278 ossl_provider_store_free(ctx
->provider_store
);
279 ctx
->provider_store
= NULL
;
282 /* Default priority. */
283 if (ctx
->property_string_data
!= NULL
) {
284 ossl_property_string_data_free(ctx
->property_string_data
);
285 ctx
->property_string_data
= NULL
;
288 if (ctx
->namemap
!= NULL
) {
289 ossl_stored_namemap_free(ctx
->namemap
);
293 if (ctx
->property_defns
!= NULL
) {
294 ossl_property_defns_free(ctx
->property_defns
);
295 ctx
->property_defns
= NULL
;
298 if (ctx
->global_properties
!= NULL
) {
299 ossl_ctx_global_properties_free(ctx
->global_properties
);
300 ctx
->global_properties
= NULL
;
304 if (ctx
->bio_core
!= NULL
) {
305 ossl_bio_core_globals_free(ctx
->bio_core
);
306 ctx
->bio_core
= NULL
;
310 if (ctx
->drbg_nonce
!= NULL
) {
311 ossl_prov_drbg_nonce_ctx_free(ctx
->drbg_nonce
);
312 ctx
->drbg_nonce
= NULL
;
316 if (ctx
->self_test_cb
!= NULL
) {
317 ossl_self_test_set_callback_free(ctx
->self_test_cb
);
318 ctx
->self_test_cb
= NULL
;
322 if (ctx
->rand_crngt
!= NULL
) {
323 ossl_rand_crng_ctx_free(ctx
->rand_crngt
);
324 ctx
->rand_crngt
= NULL
;
328 if (ctx
->thread_event_handler
!= NULL
) {
329 ossl_thread_event_ctx_free(ctx
->thread_event_handler
);
330 ctx
->thread_event_handler
= NULL
;
333 if (ctx
->fips_prov
!= NULL
) {
334 ossl_fips_prov_ossl_ctx_free(ctx
->fips_prov
);
335 ctx
->fips_prov
= NULL
;
339 #ifndef OPENSSL_NO_THREAD_POOL
340 if (ctx
->threads
!= NULL
) {
341 ossl_threads_ctx_free(ctx
->threads
);
348 if (ctx
->child_provider
!= NULL
) {
349 ossl_child_prov_ctx_free(ctx
->child_provider
);
350 ctx
->child_provider
= NULL
;
355 if (ctx
->comp_methods
!= NULL
) {
356 ossl_free_compression_methods_int(ctx
->comp_methods
);
357 ctx
->comp_methods
= NULL
;
363 static int context_deinit(OSSL_LIB_CTX
*ctx
)
368 ossl_ctx_thread_stop(ctx
);
370 context_deinit_objs(ctx
);
372 ossl_crypto_cleanup_all_ex_data_int(ctx
);
374 CRYPTO_THREAD_lock_free(ctx
->rand_crngt_lock
);
375 CRYPTO_THREAD_lock_free(ctx
->lock
);
376 ctx
->rand_crngt_lock
= NULL
;
378 CRYPTO_THREAD_cleanup_local(&ctx
->rcu_local_key
);
383 /* The default default context */
384 static OSSL_LIB_CTX default_context_int
;
386 static CRYPTO_ONCE default_context_init
= CRYPTO_ONCE_STATIC_INIT
;
387 static CRYPTO_THREAD_LOCAL default_context_thread_local
;
388 static int default_context_inited
= 0;
390 DEFINE_RUN_ONCE_STATIC(default_context_do_init
)
392 if (!CRYPTO_THREAD_init_local(&default_context_thread_local
, NULL
))
395 if (!context_init(&default_context_int
))
398 default_context_inited
= 1;
402 CRYPTO_THREAD_cleanup_local(&default_context_thread_local
);
407 void ossl_lib_ctx_default_deinit(void)
409 if (!default_context_inited
)
411 context_deinit(&default_context_int
);
412 CRYPTO_THREAD_cleanup_local(&default_context_thread_local
);
413 default_context_inited
= 0;
416 static OSSL_LIB_CTX
*get_thread_default_context(void)
418 if (!RUN_ONCE(&default_context_init
, default_context_do_init
))
421 return CRYPTO_THREAD_get_local(&default_context_thread_local
);
424 static OSSL_LIB_CTX
*get_default_context(void)
426 OSSL_LIB_CTX
*current_defctx
= get_thread_default_context();
428 if (current_defctx
== NULL
)
429 current_defctx
= &default_context_int
;
430 return current_defctx
;
433 static int set_default_context(OSSL_LIB_CTX
*defctx
)
435 if (defctx
== &default_context_int
)
438 return CRYPTO_THREAD_set_local(&default_context_thread_local
, defctx
);
442 OSSL_LIB_CTX
*OSSL_LIB_CTX_new(void)
444 OSSL_LIB_CTX
*ctx
= OPENSSL_zalloc(sizeof(*ctx
));
446 if (ctx
!= NULL
&& !context_init(ctx
)) {
454 OSSL_LIB_CTX
*OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE
*handle
,
455 const OSSL_DISPATCH
*in
)
457 OSSL_LIB_CTX
*ctx
= OSSL_LIB_CTX_new();
462 if (!ossl_bio_init_core(ctx
, in
)) {
463 OSSL_LIB_CTX_free(ctx
);
470 OSSL_LIB_CTX
*OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE
*handle
,
471 const OSSL_DISPATCH
*in
)
473 OSSL_LIB_CTX
*ctx
= OSSL_LIB_CTX_new_from_dispatch(handle
, in
);
478 if (!ossl_provider_init_as_child(ctx
, handle
, in
)) {
479 OSSL_LIB_CTX_free(ctx
);
487 int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX
*ctx
, const char *config_file
)
489 return CONF_modules_load_file_ex(ctx
, config_file
, NULL
, 0) > 0;
493 void OSSL_LIB_CTX_free(OSSL_LIB_CTX
*ctx
)
495 if (ossl_lib_ctx_is_default(ctx
))
500 ossl_provider_deinit_child(ctx
);
507 OSSL_LIB_CTX
*OSSL_LIB_CTX_get0_global_default(void)
509 if (!RUN_ONCE(&default_context_init
, default_context_do_init
))
512 return &default_context_int
;
515 OSSL_LIB_CTX
*OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX
*libctx
)
517 OSSL_LIB_CTX
*current_defctx
;
519 if ((current_defctx
= get_default_context()) != NULL
) {
521 set_default_context(libctx
);
522 return current_defctx
;
528 void ossl_release_default_drbg_ctx(void)
530 /* early release of the DRBG in global default libctx */
531 if (default_context_int
.drbg
!= NULL
) {
532 ossl_rand_ctx_free(default_context_int
.drbg
);
533 default_context_int
.drbg
= NULL
;
538 OSSL_LIB_CTX
*ossl_lib_ctx_get_concrete(OSSL_LIB_CTX
*ctx
)
542 return get_default_context();
547 int ossl_lib_ctx_is_default(OSSL_LIB_CTX
*ctx
)
550 if (ctx
== NULL
|| ctx
== get_default_context())
556 int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX
*ctx
)
559 if (ossl_lib_ctx_get_concrete(ctx
) == &default_context_int
)
565 void *ossl_lib_ctx_get_data(OSSL_LIB_CTX
*ctx
, int index
)
569 ctx
= ossl_lib_ctx_get_concrete(ctx
);
574 case OSSL_LIB_CTX_PROPERTY_STRING_INDEX
:
575 return ctx
->property_string_data
;
576 case OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX
:
577 return ctx
->evp_method_store
;
578 case OSSL_LIB_CTX_PROVIDER_STORE_INDEX
:
579 return ctx
->provider_store
;
580 case OSSL_LIB_CTX_NAMEMAP_INDEX
:
582 case OSSL_LIB_CTX_PROPERTY_DEFN_INDEX
:
583 return ctx
->property_defns
;
584 case OSSL_LIB_CTX_GLOBAL_PROPERTIES
:
585 return ctx
->global_properties
;
586 case OSSL_LIB_CTX_DRBG_INDEX
:
588 case OSSL_LIB_CTX_DRBG_NONCE_INDEX
:
589 return ctx
->drbg_nonce
;
591 case OSSL_LIB_CTX_PROVIDER_CONF_INDEX
:
592 return ctx
->provider_conf
;
593 case OSSL_LIB_CTX_BIO_CORE_INDEX
:
594 return ctx
->bio_core
;
595 case OSSL_LIB_CTX_CHILD_PROVIDER_INDEX
:
596 return ctx
->child_provider
;
597 case OSSL_LIB_CTX_DECODER_STORE_INDEX
:
598 return ctx
->decoder_store
;
599 case OSSL_LIB_CTX_DECODER_CACHE_INDEX
:
600 return ctx
->decoder_cache
;
601 case OSSL_LIB_CTX_ENCODER_STORE_INDEX
:
602 return ctx
->encoder_store
;
603 case OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX
:
604 return ctx
->store_loader_store
;
605 case OSSL_LIB_CTX_SELF_TEST_CB_INDEX
:
606 return ctx
->self_test_cb
;
608 #ifndef OPENSSL_NO_THREAD_POOL
609 case OSSL_LIB_CTX_THREAD_INDEX
:
613 case OSSL_LIB_CTX_RAND_CRNGT_INDEX
: {
616 * rand_crngt must be lazily initialized because it calls into
617 * libctx, so must not be called from context_init, else a deadlock
620 * We use a separate lock because code called by the instantiation
621 * of rand_crngt is liable to try and take the libctx lock.
623 if (CRYPTO_THREAD_read_lock(ctx
->rand_crngt_lock
) != 1)
626 if (ctx
->rand_crngt
== NULL
) {
627 CRYPTO_THREAD_unlock(ctx
->rand_crngt_lock
);
629 if (CRYPTO_THREAD_write_lock(ctx
->rand_crngt_lock
) != 1)
632 if (ctx
->rand_crngt
== NULL
)
633 ctx
->rand_crngt
= ossl_rand_crng_ctx_new(ctx
);
638 CRYPTO_THREAD_unlock(ctx
->rand_crngt_lock
);
644 case OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX
:
645 return ctx
->thread_event_handler
;
647 case OSSL_LIB_CTX_FIPS_PROV_INDEX
:
648 return ctx
->fips_prov
;
651 case OSSL_LIB_CTX_COMP_METHODS
:
652 return (void *)&ctx
->comp_methods
;
659 void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX
*ctx
, int index
)
661 return ossl_lib_ctx_get_data(ctx
, index
);
664 OSSL_EX_DATA_GLOBAL
*ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX
*ctx
)
666 ctx
= ossl_lib_ctx_get_concrete(ctx
);
672 const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX
*libctx
)
675 return "FIPS internal library context";
677 if (ossl_lib_ctx_is_global_default(libctx
))
678 return "Global default library context";
679 if (ossl_lib_ctx_is_default(libctx
))
680 return "Thread-local default library context";
681 return "Non-default library context";
685 CRYPTO_THREAD_LOCAL
*ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX
*libctx
)
687 libctx
= ossl_lib_ctx_get_concrete(libctx
);
690 return &libctx
->rcu_local_key
;
693 int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX
*libctx
)
695 libctx
= ossl_lib_ctx_get_concrete(libctx
);
698 return libctx
->conf_diagnostics
;
701 void OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX
*libctx
, int value
)
703 libctx
= ossl_lib_ctx_get_concrete(libctx
);
706 libctx
->conf_diagnostics
= value
;