From: Matt Caswell Date: Fri, 7 May 2021 16:59:47 +0000 (+0100) Subject: Add a callback for providers to know about global properties changes X-Git-Tag: openssl-3.0.0-alpha17~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=447588b69aa6ba46e61302570df9d2d2a57960ed;p=thirdparty%2Fopenssl.git Add a callback for providers to know about global properties changes Where a child libctx is in use it needs to know what the current global properties are. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15242) --- diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index fdb6d90f4df..67e9ad878f8 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -389,12 +389,29 @@ static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx, OSSL_METHOD_STORE *store = get_evp_method_store(libctx); OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); - if (plp != NULL) { + if (plp != NULL && store != NULL) { + char *propstr = NULL; + size_t strsz; + + strsz = ossl_property_list_to_string(libctx, def_prop, NULL, 0); + if (strsz > 0) + propstr = OPENSSL_malloc(strsz); + if (propstr == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + if (ossl_property_list_to_string(libctx, def_prop, propstr, + strsz) == 0) { + OPENSSL_free(propstr); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } ossl_property_free(*plp); *plp = def_prop; + ossl_provider_default_props_update(libctx, propstr); + OPENSSL_free(propstr); if (store != NULL) return ossl_method_store_flush_cache(store, 0); - return 1; } ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); return 0; @@ -467,6 +484,30 @@ int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable) return evp_default_properties_merge(libctx, query); } +char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig) +{ + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); + char *propstr = NULL; + size_t sz; + + sz = ossl_property_list_to_string(libctx, *plp, NULL, 0); + if (sz == 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } + + propstr = OPENSSL_malloc(sz); + if (propstr == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (ossl_property_list_to_string(libctx, *plp, propstr, sz) == 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + OPENSSL_free(propstr); + return NULL; + } + return propstr; +} struct do_all_data_st { void (*user_fn)(void *method, void *arg); diff --git a/crypto/provider_child.c b/crypto/provider_child.c index 14d00546241..e4d586bf7d2 100644 --- a/crypto/provider_child.c +++ b/crypto/provider_child.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "internal/provider.h" #include "internal/cryptlib.h" @@ -198,6 +199,13 @@ static int provider_remove_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) return 1; } +static int provider_global_props_cb(const char *props, void *cbdata) +{ + OSSL_LIB_CTX *ctx = cbdata; + + return evp_set_default_properties_int(ctx, props, 0, 1); +} + int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in) @@ -265,6 +273,7 @@ int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, if (!gbl->c_provider_register_child_cb(gbl->handle, provider_create_child_cb, provider_remove_child_cb, + provider_global_props_cb, ctx)) return 0; diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 9d5248de0dc..3c2d1427758 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -47,6 +47,7 @@ typedef struct { OSSL_PROVIDER *prov; int (*create_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata); void (*remove_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata); + void (*global_props_cb)(const char *props, void *cbdata); void *cbdata; } OSSL_PROVIDER_CHILD_CB; DEFINE_STACK_OF(OSSL_PROVIDER_CHILD_CB) @@ -1363,6 +1364,30 @@ int ossl_provider_convert_to_child(OSSL_PROVIDER *prov, return 1; } +int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, const char *props) +{ +#ifndef FIPS_MODULE + struct provider_store_st *store = NULL; + int i, max; + OSSL_PROVIDER_CHILD_CB *child_cb; + + if ((store = get_provider_store(libctx)) == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(store->lock)) + return 0; + + max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); + for (i = 0; i < max; i++) { + child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); + child_cb->global_props_cb(props, child_cb->cbdata); + } + + CRYPTO_THREAD_unlock(store->lock); +#endif + return 1; +} + static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle, int (*create_cb)( const OSSL_CORE_HANDLE *provider, @@ -1370,6 +1395,9 @@ static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle, void (*remove_cb)( const OSSL_CORE_HANDLE *provider, void *cbdata), + void (*global_props_cb)( + const char *props, + void *cbdata), void *cbdata) { /* @@ -1382,6 +1410,7 @@ static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle, struct provider_store_st *store = NULL; int ret = 0, i, max; OSSL_PROVIDER_CHILD_CB *child_cb; + char *propsstr = NULL; if ((store = get_provider_store(libctx)) == NULL) return 0; @@ -1392,12 +1421,19 @@ static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle, child_cb->prov = thisprov; child_cb->create_cb = create_cb; child_cb->remove_cb = remove_cb; + child_cb->global_props_cb = global_props_cb; child_cb->cbdata = cbdata; if (!CRYPTO_THREAD_write_lock(store->lock)) { OPENSSL_free(child_cb); return 0; } + propsstr = evp_get_global_properties_str(libctx, 0); + + if (propsstr != NULL) { + global_props_cb(propsstr, cbdata); + OPENSSL_free(propsstr); + } max = sk_OSSL_PROVIDER_num(store->providers); for (i = 0; i < max; i++) { prov = sk_OSSL_PROVIDER_value(store->providers, i); diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 96a109e38b5..92a9f0fc29e 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -886,7 +886,8 @@ int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx); int evp_method_store_flush(OSSL_LIB_CTX *libctx); int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq, - int loadconfig); + int loadconfig, int mirrored); +char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig); void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force); diff --git a/include/internal/provider.h b/include/internal/provider.h index 020cbc8a9ee..df20c76f90e 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -50,6 +50,7 @@ int ossl_provider_convert_to_child(OSSL_PROVIDER *prov, const OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov); int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate); int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate); +int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, const char *props); /* Disable fallback loading */ int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx); diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 5c453eaac0f..458cbb1c9e2 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -196,6 +196,7 @@ OSSL_CORE_MAKE_FUNC(int, provider_register_child_cb, (const OSSL_CORE_HANDLE *handle, int (*create_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata), int (*remove_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata), + int (*global_props_cb)(const char *props, void *cbdata), void *cbdata)) OSSL_CORE_MAKE_FUNC(void, provider_deregister_child_cb, (const OSSL_CORE_HANDLE *handle))