diff options
Diffstat (limited to 'crypto/context.c')
-rw-r--r-- | crypto/context.c | 633 |
1 files changed, 402 insertions, 231 deletions
diff --git a/crypto/context.c b/crypto/context.c index ac6938e619eb..f15bc3d755e5 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,55 +9,72 @@ #include "crypto/cryptlib.h" #include <openssl/conf.h> +#include <openssl/trace.h> #include "internal/thread_once.h" #include "internal/property.h" +#include "internal/cryptlib.h" #include "internal/core.h" #include "internal/bio.h" #include "internal/provider.h" -#include "crypto/ctype.h" -#include "crypto/rand.h" - -struct ossl_lib_ctx_onfree_list_st { - ossl_lib_ctx_onfree_fn *fn; - struct ossl_lib_ctx_onfree_list_st *next; -}; +#include "crypto/decoder.h" +#include "crypto/context.h" struct ossl_lib_ctx_st { CRYPTO_RWLOCK *lock; - CRYPTO_EX_DATA data; - - /* - * For most data in the OSSL_LIB_CTX we just use ex_data to store it. But - * that doesn't work for ex_data itself - so we store that directly. - */ OSSL_EX_DATA_GLOBAL global; - /* Map internal static indexes to dynamically created indexes */ - int dyn_indexes[OSSL_LIB_CTX_MAX_INDEXES]; - - /* Keep a separate lock for each index */ - CRYPTO_RWLOCK *index_locks[OSSL_LIB_CTX_MAX_INDEXES]; + void *property_string_data; + void *evp_method_store; + void *provider_store; + void *namemap; + void *property_defns; + void *global_properties; + void *drbg; + void *drbg_nonce; + CRYPTO_THREAD_LOCAL rcu_local_key; +#ifndef FIPS_MODULE + void *provider_conf; + void *bio_core; + void *child_provider; + OSSL_METHOD_STORE *decoder_store; + void *decoder_cache; + OSSL_METHOD_STORE *encoder_store; + OSSL_METHOD_STORE *store_loader_store; + void *self_test_cb; + void *indicator_cb; +#endif +#if defined(OPENSSL_THREADS) + void *threads; +#endif +#ifdef FIPS_MODULE + void *thread_event_handler; + void *fips_prov; +#endif + STACK_OF(SSL_COMP) *comp_methods; - CRYPTO_RWLOCK *oncelock; - int run_once_done[OSSL_LIB_CTX_MAX_RUN_ONCE]; - int run_once_ret[OSSL_LIB_CTX_MAX_RUN_ONCE]; - struct ossl_lib_ctx_onfree_list_st *onfreelist; - unsigned int ischild:1; + int ischild; + int conf_diagnostics; }; int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx) { - return CRYPTO_THREAD_write_lock(ossl_lib_ctx_get_concrete(ctx)->lock); + if ((ctx = ossl_lib_ctx_get_concrete(ctx)) == NULL) + return 0; + return CRYPTO_THREAD_write_lock(ctx->lock); } int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx) { - return CRYPTO_THREAD_read_lock(ossl_lib_ctx_get_concrete(ctx)->lock); + if ((ctx = ossl_lib_ctx_get_concrete(ctx)) == NULL) + return 0; + return CRYPTO_THREAD_read_lock(ctx->lock); } int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx) { - return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock); + if ((ctx = ossl_lib_ctx_get_concrete(ctx)) == NULL) + return 0; + return CRYPTO_THREAD_unlock(ctx->lock); } int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx) @@ -69,76 +86,300 @@ int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx) return ctx->ischild; } +static void context_deinit_objs(OSSL_LIB_CTX *ctx); + static int context_init(OSSL_LIB_CTX *ctx) { - size_t i; int exdata_done = 0; - ctx->lock = CRYPTO_THREAD_lock_new(); - if (ctx->lock == NULL) + if (!CRYPTO_THREAD_init_local(&ctx->rcu_local_key, NULL)) return 0; - ctx->oncelock = CRYPTO_THREAD_lock_new(); - if (ctx->oncelock == NULL) + ctx->lock = CRYPTO_THREAD_lock_new(); + if (ctx->lock == NULL) goto err; - for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) { - ctx->index_locks[i] = CRYPTO_THREAD_lock_new(); - ctx->dyn_indexes[i] = -1; - if (ctx->index_locks[i] == NULL) - goto err; - } - - /* OSSL_LIB_CTX is built on top of ex_data so we initialise that directly */ + /* Initialize ex_data. */ if (!ossl_do_ex_data_init(ctx)) goto err; exdata_done = 1; - if (!ossl_crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, - &ctx->data)) + /* P2. We want evp_method_store to be cleaned up before the provider store */ + ctx->evp_method_store = ossl_method_store_new(ctx); + if (ctx->evp_method_store == NULL) + goto err; + OSSL_TRACE1(QUERY, "context_init: allocating store %p\n", ctx->evp_method_store); + +#ifndef FIPS_MODULE + /* P2. Must be freed before the provider store is freed */ + ctx->provider_conf = ossl_prov_conf_ctx_new(ctx); + if (ctx->provider_conf == NULL) + goto err; +#endif + + /* P2. */ + ctx->drbg = ossl_rand_ctx_new(ctx); + if (ctx->drbg == NULL) + goto err; + +#ifndef FIPS_MODULE + /* + * P2. We want decoder_store/decoder_cache to be cleaned up before the + * provider store + */ + ctx->decoder_store = ossl_method_store_new(ctx); + if (ctx->decoder_store == NULL) + goto err; + ctx->decoder_cache = ossl_decoder_cache_new(ctx); + if (ctx->decoder_cache == NULL) + goto err; + + /* P2. We want encoder_store to be cleaned up before the provider store */ + ctx->encoder_store = ossl_method_store_new(ctx); + if (ctx->encoder_store == NULL) + goto err; + + /* P2. We want loader_store to be cleaned up before the provider store */ + ctx->store_loader_store = ossl_method_store_new(ctx); + if (ctx->store_loader_store == NULL) + goto err; +#endif + + /* P1. Needs to be freed before the child provider data is freed */ + ctx->provider_store = ossl_provider_store_new(ctx); + if (ctx->provider_store == NULL) + goto err; + + /* Default priority. */ + ctx->property_string_data = ossl_property_string_data_new(ctx); + if (ctx->property_string_data == NULL) + goto err; + + ctx->namemap = ossl_stored_namemap_new(ctx); + if (ctx->namemap == NULL) + goto err; + + ctx->property_defns = ossl_property_defns_new(ctx); + if (ctx->property_defns == NULL) + goto err; + + ctx->global_properties = ossl_ctx_global_properties_new(ctx); + if (ctx->global_properties == NULL) + goto err; + +#ifndef FIPS_MODULE + ctx->bio_core = ossl_bio_core_globals_new(ctx); + if (ctx->bio_core == NULL) + goto err; +#endif + + ctx->drbg_nonce = ossl_prov_drbg_nonce_ctx_new(ctx); + if (ctx->drbg_nonce == NULL) + goto err; + +#ifndef FIPS_MODULE + ctx->self_test_cb = ossl_self_test_set_callback_new(ctx); + if (ctx->self_test_cb == NULL) + goto err; + ctx->indicator_cb = ossl_indicator_set_callback_new(ctx); + if (ctx->indicator_cb == NULL) + goto err; +#endif + +#ifdef FIPS_MODULE + ctx->thread_event_handler = ossl_thread_event_ctx_new(ctx); + if (ctx->thread_event_handler == NULL) + goto err; + + ctx->fips_prov = ossl_fips_prov_ossl_ctx_new(ctx); + if (ctx->fips_prov == NULL) + goto err; +#endif + +#ifndef OPENSSL_NO_THREAD_POOL + ctx->threads = ossl_threads_ctx_new(ctx); + if (ctx->threads == NULL) + goto err; +#endif + + /* Low priority. */ +#ifndef FIPS_MODULE + ctx->child_provider = ossl_child_prov_ctx_new(ctx); + if (ctx->child_provider == NULL) goto err; +#endif /* Everything depends on properties, so we also pre-initialise that */ if (!ossl_property_parse_init(ctx)) goto err; +#ifndef FIPS_MODULE + ctx->comp_methods = ossl_load_builtin_compressions(); +#endif + return 1; + err: + context_deinit_objs(ctx); + if (exdata_done) ossl_crypto_cleanup_all_ex_data_int(ctx); - for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) - CRYPTO_THREAD_lock_free(ctx->index_locks[i]); - CRYPTO_THREAD_lock_free(ctx->oncelock); + CRYPTO_THREAD_lock_free(ctx->lock); + CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key); memset(ctx, '\0', sizeof(*ctx)); return 0; } -static int context_deinit(OSSL_LIB_CTX *ctx) +static void context_deinit_objs(OSSL_LIB_CTX *ctx) { - struct ossl_lib_ctx_onfree_list_st *tmp, *onfree; - int i; + /* P2. We want evp_method_store to be cleaned up before the provider store */ + if (ctx->evp_method_store != NULL) { + ossl_method_store_free(ctx->evp_method_store); + ctx->evp_method_store = NULL; + } + + /* P2. */ + if (ctx->drbg != NULL) { + ossl_rand_ctx_free(ctx->drbg); + ctx->drbg = NULL; + } + +#ifndef FIPS_MODULE + /* P2. */ + if (ctx->provider_conf != NULL) { + ossl_prov_conf_ctx_free(ctx->provider_conf); + ctx->provider_conf = NULL; + } + + /* + * P2. We want decoder_store/decoder_cache to be cleaned up before the + * provider store + */ + if (ctx->decoder_store != NULL) { + ossl_method_store_free(ctx->decoder_store); + ctx->decoder_store = NULL; + } + if (ctx->decoder_cache != NULL) { + ossl_decoder_cache_free(ctx->decoder_cache); + ctx->decoder_cache = NULL; + } + + + /* P2. We want encoder_store to be cleaned up before the provider store */ + if (ctx->encoder_store != NULL) { + ossl_method_store_free(ctx->encoder_store); + ctx->encoder_store = NULL; + } + + /* P2. We want loader_store to be cleaned up before the provider store */ + if (ctx->store_loader_store != NULL) { + ossl_method_store_free(ctx->store_loader_store); + ctx->store_loader_store = NULL; + } +#endif + + /* P1. Needs to be freed before the child provider data is freed */ + if (ctx->provider_store != NULL) { + ossl_provider_store_free(ctx->provider_store); + ctx->provider_store = NULL; + } + + /* Default priority. */ + if (ctx->property_string_data != NULL) { + ossl_property_string_data_free(ctx->property_string_data); + ctx->property_string_data = NULL; + } + + if (ctx->namemap != NULL) { + ossl_stored_namemap_free(ctx->namemap); + ctx->namemap = NULL; + } + + if (ctx->property_defns != NULL) { + ossl_property_defns_free(ctx->property_defns); + ctx->property_defns = NULL; + } + + if (ctx->global_properties != NULL) { + ossl_ctx_global_properties_free(ctx->global_properties); + ctx->global_properties = NULL; + } + +#ifndef FIPS_MODULE + if (ctx->bio_core != NULL) { + ossl_bio_core_globals_free(ctx->bio_core); + ctx->bio_core = NULL; + } +#endif + + if (ctx->drbg_nonce != NULL) { + ossl_prov_drbg_nonce_ctx_free(ctx->drbg_nonce); + ctx->drbg_nonce = NULL; + } +#ifndef FIPS_MODULE + if (ctx->indicator_cb != NULL) { + ossl_indicator_set_callback_free(ctx->indicator_cb); + ctx->indicator_cb = NULL; + } + + if (ctx->self_test_cb != NULL) { + ossl_self_test_set_callback_free(ctx->self_test_cb); + ctx->self_test_cb = NULL; + } +#endif + +#ifdef FIPS_MODULE + if (ctx->thread_event_handler != NULL) { + ossl_thread_event_ctx_free(ctx->thread_event_handler); + ctx->thread_event_handler = NULL; + } + + if (ctx->fips_prov != NULL) { + ossl_fips_prov_ossl_ctx_free(ctx->fips_prov); + ctx->fips_prov = NULL; + } +#endif + +#ifndef OPENSSL_NO_THREAD_POOL + if (ctx->threads != NULL) { + ossl_threads_ctx_free(ctx->threads); + ctx->threads = NULL; + } +#endif + + /* Low priority. */ +#ifndef FIPS_MODULE + if (ctx->child_provider != NULL) { + ossl_child_prov_ctx_free(ctx->child_provider); + ctx->child_provider = NULL; + } +#endif + +#ifndef FIPS_MODULE + if (ctx->comp_methods != NULL) { + ossl_free_compression_methods_int(ctx->comp_methods); + ctx->comp_methods = NULL; + } +#endif + +} + +static int context_deinit(OSSL_LIB_CTX *ctx) +{ if (ctx == NULL) return 1; ossl_ctx_thread_stop(ctx); - onfree = ctx->onfreelist; - while (onfree != NULL) { - onfree->fn(ctx); - tmp = onfree; - onfree = onfree->next; - OPENSSL_free(tmp); - } - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, &ctx->data); + context_deinit_objs(ctx); + ossl_crypto_cleanup_all_ex_data_int(ctx); - for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) - CRYPTO_THREAD_lock_free(ctx->index_locks[i]); - CRYPTO_THREAD_lock_free(ctx->oncelock); CRYPTO_THREAD_lock_free(ctx->lock); ctx->lock = NULL; + CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key); return 1; } @@ -148,17 +389,32 @@ static OSSL_LIB_CTX default_context_int; static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT; static CRYPTO_THREAD_LOCAL default_context_thread_local; +static int default_context_inited = 0; DEFINE_RUN_ONCE_STATIC(default_context_do_init) { - return CRYPTO_THREAD_init_local(&default_context_thread_local, NULL) - && context_init(&default_context_int); + if (!CRYPTO_THREAD_init_local(&default_context_thread_local, NULL)) + goto err; + + if (!context_init(&default_context_int)) + goto deinit_thread; + + default_context_inited = 1; + return 1; + +deinit_thread: + CRYPTO_THREAD_cleanup_local(&default_context_thread_local); +err: + return 0; } void ossl_lib_ctx_default_deinit(void) { + if (!default_context_inited) + return; context_deinit(&default_context_int); CRYPTO_THREAD_cleanup_local(&default_context_thread_local); + default_context_inited = 0; } static OSSL_LIB_CTX *get_thread_default_context(void) @@ -173,7 +429,7 @@ static OSSL_LIB_CTX *get_default_context(void) { OSSL_LIB_CTX *current_defctx = get_thread_default_context(); - if (current_defctx == NULL) + if (current_defctx == NULL && default_context_inited) current_defctx = &default_context_int; return current_defctx; } @@ -275,15 +531,10 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx) void ossl_release_default_drbg_ctx(void) { - int dynidx = default_context_int.dyn_indexes[OSSL_LIB_CTX_DRBG_INDEX]; - - /* early release of the DRBG in global default libctx, no locking */ - if (dynidx != -1) { - void *data; - - data = CRYPTO_get_ex_data(&default_context_int.data, dynidx); - ossl_rand_ctx_free(data); - CRYPTO_set_ex_data(&default_context_int.data, dynidx, NULL); + /* early release of the DRBG in global default libctx */ + if (default_context_int.drbg != NULL) { + ossl_rand_ctx_free(default_context_int.drbg); + default_context_int.drbg = NULL; } } #endif @@ -315,127 +566,73 @@ int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx) return 0; } -static void ossl_lib_ctx_generic_new(void *parent_ign, void *ptr_ign, - CRYPTO_EX_DATA *ad, int index, - long argl_ign, void *argp) -{ - const OSSL_LIB_CTX_METHOD *meth = argp; - OSSL_LIB_CTX *ctx = ossl_crypto_ex_data_get_ossl_lib_ctx(ad); - void *ptr = meth->new_func(ctx); - - if (ptr != NULL) { - if (!CRYPTO_THREAD_write_lock(ctx->lock)) - /* - * Can't return something, so best to hope that something will - * fail later. :( - */ - return; - CRYPTO_set_ex_data(ad, index, ptr); - CRYPTO_THREAD_unlock(ctx->lock); - } -} -static void ossl_lib_ctx_generic_free(void *parent_ign, void *ptr, - CRYPTO_EX_DATA *ad, int index, - long argl_ign, void *argp) -{ - const OSSL_LIB_CTX_METHOD *meth = argp; - - meth->free_func(ptr); -} - -static int ossl_lib_ctx_init_index(OSSL_LIB_CTX *ctx, int static_index, - const OSSL_LIB_CTX_METHOD *meth) -{ - int idx; - - ctx = ossl_lib_ctx_get_concrete(ctx); - if (ctx == NULL) - return 0; - - idx = ossl_crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, 0, - (void *)meth, - ossl_lib_ctx_generic_new, - NULL, ossl_lib_ctx_generic_free, - meth->priority); - if (idx < 0) - return 0; - - ctx->dyn_indexes[static_index] = idx; - return 1; -} - -void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index, - const OSSL_LIB_CTX_METHOD *meth) +void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index) { - void *data = NULL; - int dynidx; - ctx = ossl_lib_ctx_get_concrete(ctx); if (ctx == NULL) return NULL; - if (!CRYPTO_THREAD_read_lock(ctx->lock)) - return NULL; - dynidx = ctx->dyn_indexes[index]; - CRYPTO_THREAD_unlock(ctx->lock); - - if (dynidx != -1) { - if (!CRYPTO_THREAD_read_lock(ctx->index_locks[index])) - return NULL; - if (!CRYPTO_THREAD_read_lock(ctx->lock)) { - CRYPTO_THREAD_unlock(ctx->index_locks[index]); - return NULL; - } - data = CRYPTO_get_ex_data(&ctx->data, dynidx); - CRYPTO_THREAD_unlock(ctx->lock); - CRYPTO_THREAD_unlock(ctx->index_locks[index]); - return data; - } - - if (!CRYPTO_THREAD_write_lock(ctx->index_locks[index])) - return NULL; - if (!CRYPTO_THREAD_write_lock(ctx->lock)) { - CRYPTO_THREAD_unlock(ctx->index_locks[index]); - return NULL; - } + switch (index) { + case OSSL_LIB_CTX_PROPERTY_STRING_INDEX: + return ctx->property_string_data; + case OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX: + return ctx->evp_method_store; + case OSSL_LIB_CTX_PROVIDER_STORE_INDEX: + return ctx->provider_store; + case OSSL_LIB_CTX_NAMEMAP_INDEX: + return ctx->namemap; + case OSSL_LIB_CTX_PROPERTY_DEFN_INDEX: + return ctx->property_defns; + case OSSL_LIB_CTX_GLOBAL_PROPERTIES: + return ctx->global_properties; + case OSSL_LIB_CTX_DRBG_INDEX: + return ctx->drbg; + case OSSL_LIB_CTX_DRBG_NONCE_INDEX: + return ctx->drbg_nonce; +#ifndef FIPS_MODULE + case OSSL_LIB_CTX_PROVIDER_CONF_INDEX: + return ctx->provider_conf; + case OSSL_LIB_CTX_BIO_CORE_INDEX: + return ctx->bio_core; + case OSSL_LIB_CTX_CHILD_PROVIDER_INDEX: + return ctx->child_provider; + case OSSL_LIB_CTX_DECODER_STORE_INDEX: + return ctx->decoder_store; + case OSSL_LIB_CTX_DECODER_CACHE_INDEX: + return ctx->decoder_cache; + case OSSL_LIB_CTX_ENCODER_STORE_INDEX: + return ctx->encoder_store; + case OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX: + return ctx->store_loader_store; + case OSSL_LIB_CTX_SELF_TEST_CB_INDEX: + return ctx->self_test_cb; + case OSSL_LIB_CTX_INDICATOR_CB_INDEX: + return ctx->indicator_cb; +#endif +#ifndef OPENSSL_NO_THREAD_POOL + case OSSL_LIB_CTX_THREAD_INDEX: + return ctx->threads; +#endif - dynidx = ctx->dyn_indexes[index]; - if (dynidx != -1) { - data = CRYPTO_get_ex_data(&ctx->data, dynidx); - CRYPTO_THREAD_unlock(ctx->lock); - CRYPTO_THREAD_unlock(ctx->index_locks[index]); - return data; - } +#ifdef FIPS_MODULE + case OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX: + return ctx->thread_event_handler; - if (!ossl_lib_ctx_init_index(ctx, index, meth)) { - CRYPTO_THREAD_unlock(ctx->lock); - CRYPTO_THREAD_unlock(ctx->index_locks[index]); - return NULL; - } + case OSSL_LIB_CTX_FIPS_PROV_INDEX: + return ctx->fips_prov; +#endif - CRYPTO_THREAD_unlock(ctx->lock); + case OSSL_LIB_CTX_COMP_METHODS: + return (void *)&ctx->comp_methods; - /* - * The alloc call ensures there's a value there. We release the ctx->lock - * for this, because the allocation itself may recursively call - * ossl_lib_ctx_get_data for other indexes (never this one). The allocation - * will itself aquire the ctx->lock when it actually comes to store the - * allocated data (see ossl_lib_ctx_generic_new() above). We call - * ossl_crypto_alloc_ex_data_intern() here instead of CRYPTO_alloc_ex_data(). - * They do the same thing except that the latter calls CRYPTO_get_ex_data() - * as well - which we must not do without holding the ctx->lock. - */ - if (ossl_crypto_alloc_ex_data_intern(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, - &ctx->data, ctx->dyn_indexes[index])) { - if (!CRYPTO_THREAD_read_lock(ctx->lock)) - goto end; - data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]); - CRYPTO_THREAD_unlock(ctx->lock); + default: + return NULL; } +} -end: - CRYPTO_THREAD_unlock(ctx->index_locks[index]); - return data; +void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX *ctx, int index) +{ + return ossl_lib_ctx_get_data(ctx, index); } OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx) @@ -446,56 +643,6 @@ OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx) return &ctx->global; } -int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, - ossl_lib_ctx_run_once_fn run_once_fn) -{ - int done = 0, ret = 0; - - ctx = ossl_lib_ctx_get_concrete(ctx); - if (ctx == NULL) - return 0; - - if (!CRYPTO_THREAD_read_lock(ctx->oncelock)) - return 0; - done = ctx->run_once_done[idx]; - if (done) - ret = ctx->run_once_ret[idx]; - CRYPTO_THREAD_unlock(ctx->oncelock); - - if (done) - return ret; - - if (!CRYPTO_THREAD_write_lock(ctx->oncelock)) - return 0; - if (ctx->run_once_done[idx]) { - ret = ctx->run_once_ret[idx]; - CRYPTO_THREAD_unlock(ctx->oncelock); - return ret; - } - - ret = run_once_fn(ctx); - ctx->run_once_done[idx] = 1; - ctx->run_once_ret[idx] = ret; - CRYPTO_THREAD_unlock(ctx->oncelock); - - return ret; -} - -int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn) -{ - struct ossl_lib_ctx_onfree_list_st *newonfree - = OPENSSL_malloc(sizeof(*newonfree)); - - if (newonfree == NULL) - return 0; - - newonfree->fn = onfreefn; - newonfree->next = ctx->onfreelist; - ctx->onfreelist = newonfree; - - return 1; -} - const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx) { #ifdef FIPS_MODULE @@ -508,3 +655,27 @@ const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx) return "Non-default library context"; #endif } + +CRYPTO_THREAD_LOCAL *ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX *libctx) +{ + libctx = ossl_lib_ctx_get_concrete(libctx); + if (libctx == NULL) + return NULL; + return &libctx->rcu_local_key; +} + +int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX *libctx) +{ + libctx = ossl_lib_ctx_get_concrete(libctx); + if (libctx == NULL) + return 0; + return libctx->conf_diagnostics; +} + +void OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX *libctx, int value) +{ + libctx = ossl_lib_ctx_get_concrete(libctx); + if (libctx == NULL) + return; + libctx->conf_diagnostics = value; +} |