From 9d2f7e1f611f03e65f25adf08b76e08821b315da Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Wed, 2 Aug 2023 17:54:01 +0200 Subject: OSSL_PROVIDER_load_ex Reviewed-by: Matt Caswell Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/21604) --- crypto/provider.c | 21 ++++++++++++++++----- crypto/provider_child.c | 2 +- crypto/provider_conf.c | 2 +- crypto/provider_core.c | 27 ++++++++++++++++++++++++--- doc/man3/OSSL_PROVIDER.pod | 16 ++++++++++++++++ include/internal/provider.h | 2 +- include/openssl/provider.h | 5 +++++ util/libcrypto.num | 2 ++ 8 files changed, 66 insertions(+), 11 deletions(-) diff --git a/crypto/provider.c b/crypto/provider.c index 65f919aec2..9cc51d3ae7 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -15,15 +15,15 @@ #include "internal/provider.h" #include "provider_local.h" -OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, - int retain_fallbacks) +OSSL_PROVIDER *OSSL_PROVIDER_try_load_ex(OSSL_LIB_CTX *libctx, const char *name, + OSSL_PARAM *params, int retain_fallbacks) { OSSL_PROVIDER *prov = NULL, *actual; int isnew = 0; /* Find it or create it */ if ((prov = ossl_provider_find(libctx, name, 0)) == NULL) { - if ((prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL) + if ((prov = ossl_provider_new(libctx, name, NULL, params, 0)) == NULL) return NULL; isnew = 1; } @@ -49,14 +49,25 @@ OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, return actual; } -OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, + int retain_fallbacks) +{ + return OSSL_PROVIDER_try_load_ex(libctx, name, NULL, retain_fallbacks); +} + +OSSL_PROVIDER *OSSL_PROVIDER_load_ex(OSSL_LIB_CTX *libctx, const char *name, OSSL_PARAM *params) { /* Any attempt to load a provider disables auto-loading of defaults */ if (ossl_provider_disable_fallback_loading(libctx)) - return OSSL_PROVIDER_try_load(libctx, name, 0); + return OSSL_PROVIDER_try_load_ex(libctx, name, params, 0); return NULL; } +OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) +{ + return OSSL_PROVIDER_load_ex(libctx, name, NULL); +} + int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) { if (!ossl_provider_deactivate(prov, 1)) diff --git a/crypto/provider_child.c b/crypto/provider_child.c index 176a3a5cb2..ed8ee3b3a1 100644 --- a/crypto/provider_child.c +++ b/crypto/provider_child.c @@ -132,7 +132,7 @@ static int provider_create_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) * init children */ if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init, - 1)) == NULL) + NULL, 1)) == NULL) goto err; if (!ossl_provider_activate(cprov, 0, 0)) { diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 9751caac8e..11294b2996 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -158,7 +158,7 @@ static int provider_conf_activate(OSSL_LIB_CTX *libctx, const char *name, } prov = ossl_provider_find(libctx, name, 1); if (prov == NULL) - prov = ossl_provider_new(libctx, name, NULL, 1); + prov = ossl_provider_new(libctx, name, NULL, NULL, 1); if (prov == NULL) { CRYPTO_THREAD_unlock(pcgbl->lock); if (soft) diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 4cb3e21f69..2e2c597f37 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -518,7 +518,7 @@ static int provider_free_intern(OSSL_PROVIDER *prov, int deactivate) */ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_function, - int noconfig) + OSSL_PARAM *params, int noconfig) { struct provider_store_st *store = NULL; OSSL_PROVIDER_INFO template; @@ -540,7 +540,7 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, } } if (p->name == NULL) { - /* Check if this is a user added builtin provider */ + /* Check if this is a user added provider */ if (!CRYPTO_THREAD_read_lock(store->lock)) return NULL; for (i = 0, p = store->provinfo; i < store->numprovinfo; p++, i++) { @@ -555,8 +555,29 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, template.init = init_function; } + if (params != NULL) { + int i; + + template.parameters = sk_INFOPAIR_new_null(); + if (template.parameters == NULL) + return NULL; + + for (i = 0; params[i].key != NULL; i++) { + if (params[i].data_type != OSSL_PARAM_UTF8_STRING) + continue; + if (ossl_provider_info_add_parameter(&template, params[i].key, + (char *)params[i].data) <= 0) + return NULL; + } + } + /* provider_new() generates an error, so no need here */ - if ((prov = provider_new(name, template.init, template.parameters)) == NULL) + prov = provider_new(name, template.init, template.parameters); + + if (params != NULL) /* We copied the parameters, let's free them */ + sk_INFOPAIR_pop_free(template.parameters, infopair_free); + + if (prov == NULL) return NULL; prov->libctx = libctx; diff --git a/doc/man3/OSSL_PROVIDER.pod b/doc/man3/OSSL_PROVIDER.pod index 1790c0e678..12151021c5 100644 --- a/doc/man3/OSSL_PROVIDER.pod +++ b/doc/man3/OSSL_PROVIDER.pod @@ -5,6 +5,7 @@ OSSL_PROVIDER_set_default_search_path, OSSL_PROVIDER_get0_default_search_path, OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_try_load, OSSL_PROVIDER_unload, +OSSL_PROVIDER_load_ex, OSSL_PROVIDER_try_load_ex, OSSL_PROVIDER_available, OSSL_PROVIDER_do_all, OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params, OSSL_PROVIDER_query_operation, OSSL_PROVIDER_unquery_operation, @@ -24,8 +25,13 @@ OSSL_PROVIDER_self_test const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx); OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name); + OSSL_PROVIDER *OSSL_PROVIDER_load_ex(OSSL_LIB_CTX *, const char *name, + OSSL_PARAM *params); OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, int retain_fallbacks); + OSSL_PROVIDER *OSSL_PROVIDER_try_load_ex(OSSL_LIB_CTX *, const char *name, + OSSL_PARAM *params, + int retain_fallbacks); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name); int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, @@ -101,6 +107,13 @@ loaded and initialized or if I is nonzero. If the provider loads successfully and I is zero, the fallback providers are disabled. +OSSL_PROVIDER_load_ex() and OSSL_PROVIDER_try_load_ex() are the variants +of the previous functions accepting an C array of the parameters +that are passed as the configuration of the loaded provider. The parameters +of any type but C are silently ignored. If the +parameters are provided, they replace B the ones specified in the +configuration file. + OSSL_PROVIDER_unload() unloads the given provider. For a provider added with OSSL_PROVIDER_add_builtin(), this simply runs its teardown function. @@ -221,6 +234,9 @@ L, L, L The type and functions described here were added in OpenSSL 3.0. +The I and I functions were +added in OpenSSL 3.2. + =head1 COPYRIGHT Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/internal/provider.h b/include/internal/provider.h index 33750eba9c..88a16062c7 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -32,7 +32,7 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, int noconfig); OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_function, - int noconfig); + OSSL_PARAM *params, int noconfig); int ossl_provider_up_ref(OSSL_PROVIDER *prov); void ossl_provider_free(OSSL_PROVIDER *prov); diff --git a/include/openssl/provider.h b/include/openssl/provider.h index 088e74038e..80e6db7bb2 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -23,8 +23,13 @@ const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx); /* Load and unload a provider */ OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *, const char *name); +OSSL_PROVIDER *OSSL_PROVIDER_load_ex(OSSL_LIB_CTX *, const char *name, + OSSL_PARAM *params); OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *, const char *name, int retain_fallbacks); +OSSL_PROVIDER *OSSL_PROVIDER_try_load_ex(OSSL_LIB_CTX *, const char *name, + OSSL_PARAM *params, + int retain_fallbacks); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OSSL_LIB_CTX *, const char *name); int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, diff --git a/util/libcrypto.num b/util/libcrypto.num index 88ae4880ef..2656df5d90 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5529,6 +5529,8 @@ OSSL_ERR_STATE_save ? 3_2_0 EXIST::FUNCTION: OSSL_ERR_STATE_restore ? 3_2_0 EXIST::FUNCTION: OSSL_ERR_STATE_free ? 3_2_0 EXIST::FUNCTION: ERR_count_to_mark ? 3_2_0 EXIST::FUNCTION: +OSSL_PROVIDER_load_ex ? 3_2_0 EXIST::FUNCTION: +OSSL_PROVIDER_try_load_ex ? 3_2_0 EXIST::FUNCTION: OSSL_ERR_STATE_save_to_mark ? 3_2_0 EXIST::FUNCTION: X509_STORE_CTX_set_get_crl ? 3_2_0 EXIST::FUNCTION: X509_STORE_CTX_set_current_reasons ? 3_2_0 EXIST::FUNCTION: -- cgit v1.2.3