diff --git a/crypto/build.info b/crypto/build.info index ffcc2b0183..ed4581eef5 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -99,7 +99,7 @@ $UTIL_COMMON=\ SOURCE[../libcrypto]=$UTIL_COMMON \ mem.c mem_sec.c \ cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ - o_fopen.c getenv.c o_init.c init.c trace.c provider.c \ + o_fopen.c getenv.c o_init.c init.c trace.c provider.c provider_child.c \ punycode.c SOURCE[../providers/libfips.a]=$UTIL_COMMON diff --git a/crypto/context.c b/crypto/context.c index b21fdf077d..1e0dfa8e01 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -13,6 +13,7 @@ #include "internal/property.h" #include "internal/core.h" #include "internal/bio.h" +#include "internal/provider.h" struct ossl_lib_ctx_onfree_list_st { ossl_lib_ctx_onfree_fn *fn; @@ -39,6 +40,7 @@ struct ossl_lib_ctx_st { 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 ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx) @@ -56,6 +58,15 @@ int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx) return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock); } +int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx) +{ + ctx = ossl_lib_ctx_get_concrete(ctx); + + if (ctx == NULL) + return 0; + return ctx->ischild; +} + static int context_init(OSSL_LIB_CTX *ctx) { size_t i; @@ -185,7 +196,8 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_new(void) } #ifndef FIPS_MODULE -OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in) +OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in) { OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new(); @@ -200,6 +212,23 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in) return ctx; } +OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in) +{ + OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new_from_dispatch(handle, in); + + if (ctx == NULL) + return NULL; + + if (!ossl_provider_init_as_child(ctx, handle, in)) { + OSSL_LIB_CTX_free(ctx); + return NULL; + } + ctx->ischild = 1; + + return ctx; +} + int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file) { return CONF_modules_load_file_ex(ctx, config_file, NULL, 0) > 0; diff --git a/crypto/provider.c b/crypto/provider.c index bdff44afb9..743c2f4846 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -88,6 +88,11 @@ void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov) return ossl_provider_prov_ctx(prov); } +const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov) +{ + return ossl_provider_get0_dispatch(prov); +} + int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov) { return ossl_provider_self_test(prov); diff --git a/crypto/provider_child.c b/crypto/provider_child.c new file mode 100644 index 0000000000..fa1d004122 --- /dev/null +++ b/crypto/provider_child.c @@ -0,0 +1,232 @@ +/* + * Copyright 2019-2021 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/cryptlib.h" + +DEFINE_STACK_OF(OSSL_PROVIDER) + +struct child_prov_globals { + const OSSL_CORE_HANDLE *handle; + OSSL_CORE_PROVIDER *curr_prov; + STACK_OF(OSSL_PROVIDER) *childprovs; + unsigned int isinited:1; + CRYPTO_RWLOCK *lock; + OSSL_FUNC_core_get_libctx_fn *c_get_libctx; + OSSL_FUNC_core_provider_do_all_fn *c_prov_do_all; + OSSL_FUNC_core_provider_name_fn *c_prov_name; + OSSL_FUNC_core_provider_get0_provider_ctx_fn *c_prov_get0_provider_ctx; + OSSL_FUNC_core_provider_get0_dispatch_fn *c_prov_get0_dispatch; +}; + +static void *child_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) +{ + return OPENSSL_zalloc(sizeof(struct child_prov_globals)); +} + +/* Wrapper with a void return type for use with sk_OSSL_PROVIDER_pop_free */ +static void ossl_prov_free(OSSL_PROVIDER *prov) +{ + OSSL_PROVIDER_unload(prov); +} + +static void child_prov_ossl_ctx_free(void *vgbl) +{ + struct child_prov_globals *gbl = vgbl; + + sk_OSSL_PROVIDER_pop_free(gbl->childprovs, ossl_prov_free); + CRYPTO_THREAD_lock_free(gbl->lock); + OPENSSL_free(gbl); +} + +static const OSSL_LIB_CTX_METHOD child_prov_ossl_ctx_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + child_prov_ossl_ctx_new, + child_prov_ossl_ctx_free, +}; + +static OSSL_provider_init_fn ossl_child_provider_init; + +static int ossl_child_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, + void **provctx) +{ + OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; + OSSL_LIB_CTX *ctx; + struct child_prov_globals *gbl; + + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_CORE_GET_LIBCTX: + c_get_libctx = OSSL_FUNC_core_get_libctx(in); + break; + default: + /* Just ignore anything we don't understand */ + break; + } + } + + if (c_get_libctx == NULL) + return 0; + + /* + * We need an OSSL_LIB_CTX but c_get_libctx returns OPENSSL_CORE_CTX. We are + * a built-in provider and so we can get away with this cast. Normal + * providers can't do this. + */ + ctx = (OSSL_LIB_CTX *)c_get_libctx(handle); + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + *provctx = gbl->c_prov_get0_provider_ctx(gbl->curr_prov); + *out = gbl->c_prov_get0_dispatch(gbl->curr_prov); + + return 1; +} + +static int provider_create_child_cb(OSSL_CORE_PROVIDER *prov, void *cbdata) +{ + OSSL_LIB_CTX *ctx = cbdata; + struct child_prov_globals *gbl; + const char *provname; + OSSL_PROVIDER *cprov; + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + provname = gbl->c_prov_name(prov); + + /* + * We're operating under a lock so we can store the "current" provider in + * the global data. + */ + gbl->curr_prov = prov; + + /* + * Create it - passing 1 as final param so we don't try and recursively init + * children + */ + if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init, + 1)) == NULL) + return 0; + + if (!ossl_provider_activate(cprov, 0)) { + ossl_provider_free(cprov); + return 0; + } + ossl_provider_set_child(cprov); + + if (!sk_OSSL_PROVIDER_push(gbl->childprovs, cprov)) { + OSSL_PROVIDER_unload(cprov); + return 0; + } + + return 1; +} + +int ossl_provider_init_child_providers(OSSL_LIB_CTX *ctx) +{ + struct child_prov_globals *gbl; + + /* Should never happen */ + if (ctx == NULL) + return 0; + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(gbl->lock)) + return 0; + if (gbl->isinited) { + CRYPTO_THREAD_unlock(gbl->lock); + return 1; + } + CRYPTO_THREAD_unlock(gbl->lock); + + if (!CRYPTO_THREAD_write_lock(gbl->lock)) + return 0; + if (!gbl->isinited) { + if (!gbl->c_prov_do_all(gbl->c_get_libctx(gbl->handle), + provider_create_child_cb, ctx)) { + CRYPTO_THREAD_unlock(gbl->lock); + return 0; + } + gbl->isinited = 1; + } + CRYPTO_THREAD_unlock(gbl->lock); + + return 1; +} + +int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, + const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in) +{ + struct child_prov_globals *gbl; + + if (ctx == NULL) + return 0; + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + gbl->handle = handle; + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_CORE_GET_LIBCTX: + gbl->c_get_libctx = OSSL_FUNC_core_get_libctx(in); + break; + case OSSL_FUNC_CORE_PROVIDER_DO_ALL: + gbl->c_prov_do_all = OSSL_FUNC_core_provider_do_all(in); + break; + case OSSL_FUNC_CORE_PROVIDER_NAME: + gbl->c_prov_name = OSSL_FUNC_core_provider_name(in); + break; + case OSSL_FUNC_CORE_PROVIDER_GET0_PROVIDER_CTX: + gbl->c_prov_get0_provider_ctx + = OSSL_FUNC_core_provider_get0_provider_ctx(in); + break; + case OSSL_FUNC_CORE_PROVIDER_GET0_DISPATCH: + gbl->c_prov_get0_dispatch = OSSL_FUNC_core_provider_get0_dispatch(in); + break; + default: + /* Just ignore anything we don't understand */ + break; + } + } + + if (gbl->c_prov_do_all == NULL + || gbl->c_prov_name == NULL + || gbl->c_prov_get0_provider_ctx == NULL + || gbl->c_prov_get0_dispatch == NULL) + return 0; + + gbl->childprovs = sk_OSSL_PROVIDER_new_null(); + if (gbl->childprovs == NULL) + return 0; + gbl->lock = CRYPTO_THREAD_lock_new(); + if (gbl->lock == NULL) + return 0; + + return 1; +} diff --git a/crypto/provider_core.c b/crypto/provider_core.c index db8763d50d..3e2e2ac335 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -22,6 +22,7 @@ #include "internal/provider.h" #include "internal/refcount.h" #include "internal/bio.h" +#include "internal/core.h" #include "provider_local.h" #ifndef FIPS_MODULE # include @@ -91,8 +92,12 @@ struct ossl_provider_st { size_t operation_bits_sz; CRYPTO_RWLOCK *opbits_lock; + /* Whether this provider is the child of some other provider */ + unsigned int ischild:1; + /* Provider side data */ void *provctx; + const OSSL_DISPATCH *dispatch; }; DEFINE_STACK_OF(OSSL_PROVIDER) @@ -234,8 +239,13 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, * Make sure any providers are loaded from config before we try to find * them. */ - if (!noconfig && ossl_lib_ctx_is_default(libctx)) - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (!noconfig) { + if (ossl_lib_ctx_is_default(libctx)) + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (ossl_lib_ctx_is_child(libctx) + && !ossl_provider_init_child_providers(libctx)) + return NULL; + } #endif tmpl.name = (char *)name; @@ -362,8 +372,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov) */ if (ref == 0) { if (prov->flag_initialized) { - if (prov->teardown != NULL) - prov->teardown(prov->provctx); + ossl_provider_teardown(prov); #ifndef OPENSSL_NO_ERR # ifndef FIPS_MODULE if (prov->error_strings != NULL) { @@ -581,6 +590,7 @@ static int provider_init(OSSL_PROVIDER *prov, int flag_lock) goto end; } prov->provctx = tmp_provctx; + prov->dispatch = provider_dispatch; for (; provider_dispatch->function_id != 0; provider_dispatch++) { switch (provider_dispatch->function_id) { @@ -845,6 +855,9 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, */ if (ossl_lib_ctx_is_default(ctx)) OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (ossl_lib_ctx_is_child(ctx) + && !ossl_provider_init_child_providers(ctx)) + return 0; #endif if (store == NULL) @@ -990,6 +1003,14 @@ void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov) return NULL; } +const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov) +{ + if (prov != NULL) + return prov->dispatch; + + return NULL; +} + OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov) { return prov != NULL ? prov->libctx : NULL; @@ -998,7 +1019,7 @@ OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov) /* Wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov) { - if (prov->teardown != NULL) + if (prov->teardown != NULL && !prov->ischild) prov->teardown(prov->provctx); } @@ -1133,6 +1154,11 @@ int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, return 1; } +void ossl_provider_set_child(OSSL_PROVIDER *prov) +{ + prov->ischild = 1; +} + /*- * Core functions for the provider * =============================== @@ -1350,7 +1376,15 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CRYPTO_SECURE_ALLOCATED, (void (*)(void))CRYPTO_secure_allocated }, { OSSL_FUNC_OPENSSL_CLEANSE, (void (*)(void))OPENSSL_cleanse }, - +#ifndef FIPS_MODULE + { OSSL_FUNC_CORE_PROVIDER_DO_ALL, (void (*)(void))OSSL_PROVIDER_do_all }, + { OSSL_FUNC_CORE_PROVIDER_NAME, + (void (*)(void))OSSL_PROVIDER_name }, + { OSSL_FUNC_CORE_PROVIDER_GET0_PROVIDER_CTX, + (void (*)(void))OSSL_PROVIDER_get0_provider_ctx }, + { OSSL_FUNC_CORE_PROVIDER_GET0_DISPATCH, + (void (*)(void))OSSL_PROVIDER_get0_dispatch }, +#endif { 0, NULL } }; static const OSSL_DISPATCH *core_dispatch = core_dispatch_; diff --git a/doc/man3/OSSL_LIB_CTX.pod b/doc/man3/OSSL_LIB_CTX.pod index 9796c8575c..1af8e53d7b 100644 --- a/doc/man3/OSSL_LIB_CTX.pod +++ b/doc/man3/OSSL_LIB_CTX.pod @@ -14,7 +14,8 @@ OSSL_LIB_CTX_set0_default typedef struct ossl_lib_ctx_st OSSL_LIB_CTX; OSSL_LIB_CTX *OSSL_LIB_CTX_new(void); - OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in); + OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in); int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file); void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx); OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void); @@ -36,10 +37,11 @@ OSSL_LIB_CTX_new() creates a new OpenSSL library context. OSSL_LIB_CTX_new_from_dispatch() creates a new OpenSSL library context initialised to use callbacks from the OSSL_DISPATCH structure. This is primarily -useful for provider authors. The dispatch structure passed should be the same -one as passed to a provider's OSSL_provider_init function in the I argument. -Some OpenSSL functions, such as L, require the library -context to be created in this way in order to work. +useful for provider authors. The I and dispatch structure arguments +passed should be the same ones as passed to a provider's +OSSL_provider_init function. Some OpenSSL functions, such as +L, require the library context to be created in this +way in order to work. OSSL_LIB_CTX_load_config() loads a configuration file using the given C. This can be used to associate a library context with providers that are loaded diff --git a/include/internal/core.h b/include/internal/core.h index 68b3943679..091b4b2d04 100644 --- a/include/internal/core.h +++ b/include/internal/core.h @@ -64,5 +64,6 @@ char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM *algo); __owur int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx); __owur int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx); int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx); +int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx); #endif diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index 94d93abda2..9245a0b870 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -165,7 +165,8 @@ typedef struct ossl_ex_data_global_st { # define OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX 15 # define OSSL_LIB_CTX_PROVIDER_CONF_INDEX 16 # define OSSL_LIB_CTX_BIO_CORE_INDEX 17 -# define OSSL_LIB_CTX_MAX_INDEXES 18 +# define OSSL_LIB_CTX_CHILD_PROVIDER_INDEX 18 +# define OSSL_LIB_CTX_MAX_INDEXES 19 # define OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY 0 # define OSSL_LIB_CTX_METHOD_HIGH_PRIORITY 1 diff --git a/include/internal/provider.h b/include/internal/provider.h index 64fe2f1178..13b72ad2de 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -41,6 +41,7 @@ int ossl_provider_set_fallback(OSSL_PROVIDER *prov); int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path); int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name, const char *value); +void ossl_provider_set_child(OSSL_PROVIDER *prov); /* Disable fallback loading */ int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx); @@ -69,6 +70,7 @@ const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov); const char *ossl_provider_module_name(const OSSL_PROVIDER *prov); const char *ossl_provider_module_path(const OSSL_PROVIDER *prov); void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov); +const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov); OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov); /* Thin wrappers around calls to the provider */ @@ -96,6 +98,12 @@ int ossl_provider_clear_all_operation_bits(OSSL_LIB_CTX *libctx); /* Configuration */ void ossl_provider_add_conf_module(void); +/* Child providers */ +int ossl_provider_init_child_providers(OSSL_LIB_CTX *ctx); +int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, + const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in); + # ifdef __cplusplus } # endif diff --git a/include/openssl/core.h b/include/openssl/core.h index 3356ef2088..71e860f99d 100644 --- a/include/openssl/core.h +++ b/include/openssl/core.h @@ -30,6 +30,7 @@ extern "C" { typedef struct ossl_core_handle_st OSSL_CORE_HANDLE; typedef struct openssl_core_ctx_st OPENSSL_CORE_CTX; typedef struct ossl_core_bio_st OSSL_CORE_BIO; +typedef struct ossl_core_provider_st OSSL_CORE_PROVIDER; /* * Dispatch table element. function_id numbers and the functions are defined diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index d088a66f30..6b5e2e2935 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -183,6 +183,23 @@ OSSL_CORE_MAKE_FUNC(size_t, get_nonce, (const OSSL_CORE_HANDLE *handle, OSSL_CORE_MAKE_FUNC(void, cleanup_nonce, (const OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len)) +/* Functions to access the core's providers */ +#define OSSL_FUNC_CORE_PROVIDER_DO_ALL 105 +#define OSSL_FUNC_CORE_PROVIDER_NAME 106 +#define OSSL_FUNC_CORE_PROVIDER_GET0_PROVIDER_CTX 107 +#define OSSL_FUNC_CORE_PROVIDER_GET0_DISPATCH 108 + +OSSL_CORE_MAKE_FUNC(int, core_provider_do_all, (const OPENSSL_CORE_CTX *ctx, + int (*cb)(OSSL_CORE_PROVIDER *provider, + void *cbdata), + void *cbdata)) +OSSL_CORE_MAKE_FUNC(const char *, core_provider_name, + (const OSSL_CORE_PROVIDER *prov)) +OSSL_CORE_MAKE_FUNC(void *, core_provider_get0_provider_ctx, + (const OSSL_CORE_PROVIDER *prov)) +OSSL_CORE_MAKE_FUNC(const OSSL_DISPATCH *, core_provider_get0_dispatch, + (const OSSL_CORE_PROVIDER *prov)) + /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */ # define OSSL_FUNC_PROVIDER_TEARDOWN 1024 OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void *provctx)) diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in index e868172acc..724e2ca5da 100644 --- a/include/openssl/crypto.h.in +++ b/include/openssl/crypto.h.in @@ -37,6 +37,7 @@ use OpenSSL::stackhash qw(generate_stack_macros); # include # include # include +# include # ifdef CHARSET_EBCDIC # include @@ -517,7 +518,10 @@ CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); OSSL_LIB_CTX *OSSL_LIB_CTX_new(void); -OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in); +OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in); +OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in); int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file); void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void); diff --git a/include/openssl/provider.h b/include/openssl/provider.h index 56b430710f..e66d5324af 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -44,6 +44,7 @@ const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov, void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov, int operation_id, const OSSL_ALGORITHM *algs); void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov); +const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov); /* Add a built in providers */ int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *, const char *name, diff --git a/test/bio_core_test.c b/test/bio_core_test.c index 9ec8af9b8f..ae326cef92 100644 --- a/test/bio_core_test.c +++ b/test/bio_core_test.c @@ -55,7 +55,7 @@ static const OSSL_DISPATCH biocbs[] = { static int test_bio_core(void) { BIO *cbio = NULL, *cbiobad = NULL; - OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_from_dispatch(biocbs); + OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_from_dispatch(NULL, biocbs); int testresult = 0; OSSL_CORE_BIO corebio; const char *msg = "Hello world"; diff --git a/util/libcrypto.num b/util/libcrypto.num index 1820baf4ad..a99b5aa047 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5402,3 +5402,5 @@ BIO_new_from_core_bio ? 3_0_0 EXIST::FUNCTION: BIO_new_ex ? 3_0_0 EXIST::FUNCTION: BIO_s_core ? 3_0_0 EXIST::FUNCTION: OSSL_LIB_CTX_new_from_dispatch ? 3_0_0 EXIST::FUNCTION: +OSSL_LIB_CTX_new_child ? 3_0_0 EXIST::FUNCTION: +OSSL_PROVIDER_get0_dispatch ? 3_0_0 EXIST::FUNCTION: