2 * Copyright 2019-2025 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 <openssl/trace.h>
13 #include "internal/thread_once.h"
14 #include "internal/property.h"
15 #include "internal/cryptlib.h"
16 #include "internal/core.h"
17 #include "internal/bio.h"
18 #include "internal/provider.h"
19 #include "internal/threads_common.h"
20 #include "crypto/decoder.h"
21 #include "crypto/context.h"
23 struct ossl_lib_ctx_st
{
25 OSSL_EX_DATA_GLOBAL global
;
27 void *property_string_data
;
28 void *evp_method_store
;
32 void *global_properties
;
39 OSSL_METHOD_STORE
*decoder_store
;
41 OSSL_METHOD_STORE
*encoder_store
;
42 OSSL_METHOD_STORE
*store_loader_store
;
46 #if defined(OPENSSL_THREADS)
52 STACK_OF(SSL_COMP
) *comp_methods
;
58 int ossl_lib_ctx_write_lock(OSSL_LIB_CTX
*ctx
)
60 if ((ctx
= ossl_lib_ctx_get_concrete(ctx
)) == NULL
)
62 return CRYPTO_THREAD_write_lock(ctx
->lock
);
65 int ossl_lib_ctx_read_lock(OSSL_LIB_CTX
*ctx
)
67 if ((ctx
= ossl_lib_ctx_get_concrete(ctx
)) == NULL
)
69 return CRYPTO_THREAD_read_lock(ctx
->lock
);
72 int ossl_lib_ctx_unlock(OSSL_LIB_CTX
*ctx
)
74 if ((ctx
= ossl_lib_ctx_get_concrete(ctx
)) == NULL
)
76 return CRYPTO_THREAD_unlock(ctx
->lock
);
79 int ossl_lib_ctx_is_child(OSSL_LIB_CTX
*ctx
)
81 ctx
= ossl_lib_ctx_get_concrete(ctx
);
88 static void context_deinit_objs(OSSL_LIB_CTX
*ctx
);
90 static int context_init(OSSL_LIB_CTX
*ctx
)
94 ctx
->lock
= CRYPTO_THREAD_lock_new();
95 if (ctx
->lock
== NULL
)
98 /* Initialize ex_data. */
99 if (!ossl_do_ex_data_init(ctx
))
103 /* P2. We want evp_method_store to be cleaned up before the provider store */
104 ctx
->evp_method_store
= ossl_method_store_new(ctx
);
105 if (ctx
->evp_method_store
== NULL
)
107 OSSL_TRACE1(QUERY
, "context_init: allocating store %p\n", ctx
->evp_method_store
);
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
)
180 ctx
->indicator_cb
= ossl_indicator_set_callback_new(ctx
);
181 if (ctx
->indicator_cb
== NULL
)
186 if (!ossl_thread_event_ctx_new(ctx
))
189 ctx
->fips_prov
= ossl_fips_prov_ossl_ctx_new(ctx
);
190 if (ctx
->fips_prov
== NULL
)
194 #ifndef OPENSSL_NO_THREAD_POOL
195 ctx
->threads
= ossl_threads_ctx_new(ctx
);
196 if (ctx
->threads
== NULL
)
202 ctx
->child_provider
= ossl_child_prov_ctx_new(ctx
);
203 if (ctx
->child_provider
== NULL
)
207 /* Everything depends on properties, so we also pre-initialise that */
208 if (!ossl_property_parse_init(ctx
))
212 ctx
->comp_methods
= ossl_load_builtin_compressions();
218 context_deinit_objs(ctx
);
221 ossl_crypto_cleanup_all_ex_data_int(ctx
);
223 CRYPTO_THREAD_lock_free(ctx
->lock
);
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
->indicator_cb
!= NULL
) {
317 ossl_indicator_set_callback_free(ctx
->indicator_cb
);
318 ctx
->indicator_cb
= NULL
;
321 if (ctx
->self_test_cb
!= NULL
) {
322 ossl_self_test_set_callback_free(ctx
->self_test_cb
);
323 ctx
->self_test_cb
= NULL
;
328 ossl_thread_event_ctx_free(ctx
);
330 if (ctx
->fips_prov
!= NULL
) {
331 ossl_fips_prov_ossl_ctx_free(ctx
->fips_prov
);
332 ctx
->fips_prov
= NULL
;
336 #ifndef OPENSSL_NO_THREAD_POOL
337 if (ctx
->threads
!= NULL
) {
338 ossl_threads_ctx_free(ctx
->threads
);
345 if (ctx
->child_provider
!= NULL
) {
346 ossl_child_prov_ctx_free(ctx
->child_provider
);
347 ctx
->child_provider
= NULL
;
352 if (ctx
->comp_methods
!= NULL
) {
353 ossl_free_compression_methods_int(ctx
->comp_methods
);
354 ctx
->comp_methods
= NULL
;
360 static int context_deinit(OSSL_LIB_CTX
*ctx
)
365 ossl_ctx_thread_stop(ctx
);
367 context_deinit_objs(ctx
);
369 ossl_crypto_cleanup_all_ex_data_int(ctx
);
371 CRYPTO_THREAD_lock_free(ctx
->lock
);
377 /* The default default context */
378 static OSSL_LIB_CTX default_context_int
;
380 static CRYPTO_ONCE default_context_init
= CRYPTO_ONCE_STATIC_INIT
;
381 static CRYPTO_THREAD_LOCAL default_context_thread_local
;
382 static int default_context_inited
= 0;
384 DEFINE_RUN_ONCE_STATIC(default_context_do_init
)
386 if (!CRYPTO_THREAD_init_local(&default_context_thread_local
, NULL
))
389 if (!context_init(&default_context_int
))
392 default_context_inited
= 1;
396 CRYPTO_THREAD_cleanup_local(&default_context_thread_local
);
401 void ossl_lib_ctx_default_deinit(void)
403 if (!default_context_inited
)
405 context_deinit(&default_context_int
);
406 CRYPTO_THREAD_cleanup_local(&default_context_thread_local
);
407 default_context_inited
= 0;
410 static OSSL_LIB_CTX
*get_thread_default_context(void)
412 if (!RUN_ONCE(&default_context_init
, default_context_do_init
))
415 return CRYPTO_THREAD_get_local(&default_context_thread_local
);
418 static OSSL_LIB_CTX
*get_default_context(void)
420 OSSL_LIB_CTX
*current_defctx
= get_thread_default_context();
422 if (current_defctx
== NULL
&& default_context_inited
)
423 current_defctx
= &default_context_int
;
424 return current_defctx
;
427 static int set_default_context(OSSL_LIB_CTX
*defctx
)
429 if (defctx
== &default_context_int
)
432 return CRYPTO_THREAD_set_local(&default_context_thread_local
, defctx
);
436 OSSL_LIB_CTX
*OSSL_LIB_CTX_new(void)
438 OSSL_LIB_CTX
*ctx
= OPENSSL_zalloc(sizeof(*ctx
));
440 if (ctx
!= NULL
&& !context_init(ctx
)) {
448 OSSL_LIB_CTX
*OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE
*handle
,
449 const OSSL_DISPATCH
*in
)
451 OSSL_LIB_CTX
*ctx
= OSSL_LIB_CTX_new();
456 if (!ossl_bio_init_core(ctx
, in
)) {
457 OSSL_LIB_CTX_free(ctx
);
464 OSSL_LIB_CTX
*OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE
*handle
,
465 const OSSL_DISPATCH
*in
)
467 OSSL_LIB_CTX
*ctx
= OSSL_LIB_CTX_new_from_dispatch(handle
, in
);
472 if (!ossl_provider_init_as_child(ctx
, handle
, in
)) {
473 OSSL_LIB_CTX_free(ctx
);
481 int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX
*ctx
, const char *config_file
)
483 return CONF_modules_load_file_ex(ctx
, config_file
, NULL
, 0) > 0;
487 void OSSL_LIB_CTX_free(OSSL_LIB_CTX
*ctx
)
489 if (ctx
== NULL
|| ossl_lib_ctx_is_default(ctx
))
494 ossl_provider_deinit_child(ctx
);
501 OSSL_LIB_CTX
*OSSL_LIB_CTX_get0_global_default(void)
503 if (!RUN_ONCE(&default_context_init
, default_context_do_init
))
506 return &default_context_int
;
509 OSSL_LIB_CTX
*OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX
*libctx
)
511 OSSL_LIB_CTX
*current_defctx
;
513 if ((current_defctx
= get_default_context()) != NULL
) {
515 set_default_context(libctx
);
516 return current_defctx
;
522 void ossl_release_default_drbg_ctx(void)
524 /* early release of the DRBG in global default libctx */
525 if (default_context_int
.drbg
!= NULL
) {
526 ossl_rand_ctx_free(default_context_int
.drbg
);
527 default_context_int
.drbg
= NULL
;
532 OSSL_LIB_CTX
*ossl_lib_ctx_get_concrete(OSSL_LIB_CTX
*ctx
)
536 return get_default_context();
541 int ossl_lib_ctx_is_default(OSSL_LIB_CTX
*ctx
)
544 if (ctx
== NULL
|| ctx
== get_default_context())
550 int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX
*ctx
)
553 if (ossl_lib_ctx_get_concrete(ctx
) == &default_context_int
)
559 void *ossl_lib_ctx_get_data(OSSL_LIB_CTX
*ctx
, int index
)
561 ctx
= ossl_lib_ctx_get_concrete(ctx
);
566 case OSSL_LIB_CTX_PROPERTY_STRING_INDEX
:
567 return ctx
->property_string_data
;
568 case OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX
:
569 return ctx
->evp_method_store
;
570 case OSSL_LIB_CTX_PROVIDER_STORE_INDEX
:
571 return ctx
->provider_store
;
572 case OSSL_LIB_CTX_NAMEMAP_INDEX
:
574 case OSSL_LIB_CTX_PROPERTY_DEFN_INDEX
:
575 return ctx
->property_defns
;
576 case OSSL_LIB_CTX_GLOBAL_PROPERTIES
:
577 return ctx
->global_properties
;
578 case OSSL_LIB_CTX_DRBG_INDEX
:
580 case OSSL_LIB_CTX_DRBG_NONCE_INDEX
:
581 return ctx
->drbg_nonce
;
583 case OSSL_LIB_CTX_PROVIDER_CONF_INDEX
:
584 return ctx
->provider_conf
;
585 case OSSL_LIB_CTX_BIO_CORE_INDEX
:
586 return ctx
->bio_core
;
587 case OSSL_LIB_CTX_CHILD_PROVIDER_INDEX
:
588 return ctx
->child_provider
;
589 case OSSL_LIB_CTX_DECODER_STORE_INDEX
:
590 return ctx
->decoder_store
;
591 case OSSL_LIB_CTX_DECODER_CACHE_INDEX
:
592 return ctx
->decoder_cache
;
593 case OSSL_LIB_CTX_ENCODER_STORE_INDEX
:
594 return ctx
->encoder_store
;
595 case OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX
:
596 return ctx
->store_loader_store
;
597 case OSSL_LIB_CTX_SELF_TEST_CB_INDEX
:
598 return ctx
->self_test_cb
;
599 case OSSL_LIB_CTX_INDICATOR_CB_INDEX
:
600 return ctx
->indicator_cb
;
602 #ifndef OPENSSL_NO_THREAD_POOL
603 case OSSL_LIB_CTX_THREAD_INDEX
:
608 case OSSL_LIB_CTX_FIPS_PROV_INDEX
:
609 return ctx
->fips_prov
;
612 case OSSL_LIB_CTX_COMP_METHODS
:
613 return (void *)&ctx
->comp_methods
;
620 void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX
*ctx
, int index
)
622 return ossl_lib_ctx_get_data(ctx
, index
);
625 OSSL_EX_DATA_GLOBAL
*ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX
*ctx
)
627 ctx
= ossl_lib_ctx_get_concrete(ctx
);
633 const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX
*libctx
)
636 return "FIPS internal library context";
638 if (ossl_lib_ctx_is_global_default(libctx
))
639 return "Global default library context";
640 if (ossl_lib_ctx_is_default(libctx
))
641 return "Thread-local default library context";
642 return "Non-default library context";
646 int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX
*libctx
)
648 libctx
= ossl_lib_ctx_get_concrete(libctx
);
651 return libctx
->conf_diagnostics
;
654 void OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX
*libctx
, int value
)
656 libctx
= ossl_lib_ctx_get_concrete(libctx
);
659 libctx
->conf_diagnostics
= value
;