From: Pauli Date: Wed, 17 Feb 2021 23:16:26 +0000 (+1000) Subject: provider: add option to load a provider without disabling the fallbacks. X-Git-Tag: openssl-3.0.0-alpha13~213 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=299f5ff3b5f2a5a9b5666e36a6a01fc430de9198;p=thirdparty%2Fopenssl.git provider: add option to load a provider without disabling the fallbacks. Add an argument to PROVIDER_try_load() that permits a provider to be loaded without changing the fallback status. This is useful when an additional provider needs to be loaded without perturbing any other setup. E.g. adding mock providers as part of unit testing. Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/13652) --- diff --git a/crypto/provider.c b/crypto/provider.c index bd8f75a2c1d..90c31f3ac53 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -13,7 +13,8 @@ #include #include "internal/provider.h" -OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name) +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, + int retain_fallbacks) { OSSL_PROVIDER *prov = NULL; @@ -22,7 +23,7 @@ OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name) && (prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL) return NULL; - if (!ossl_provider_activate(prov)) { + if (!ossl_provider_activate(prov, retain_fallbacks)) { ossl_provider_free(prov); return NULL; } @@ -34,7 +35,7 @@ OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) { /* 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); + return OSSL_PROVIDER_try_load(libctx, name, 0); return NULL; } diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 709e7a1c515..cbae99a4745 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -130,7 +130,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, ok = provider_conf_params(prov, NULL, value, cnf); if (ok && activate) { - if (!ossl_provider_activate(prov)) { + if (!ossl_provider_activate(prov, 0)) { ok = 0; } else { if (activated_providers == NULL) diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 627ff384e14..da751e60cef 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -667,14 +667,16 @@ static int provider_activate(OSSL_PROVIDER *prov) return 0; } -int ossl_provider_activate(OSSL_PROVIDER *prov) +int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks) { if (prov == NULL) return 0; if (provider_activate(prov)) { - CRYPTO_THREAD_write_lock(prov->store->lock); - prov->store->use_fallbacks = 0; - CRYPTO_THREAD_unlock(prov->store->lock); + if (!retain_fallbacks) { + CRYPTO_THREAD_write_lock(prov->store->lock); + prov->store->use_fallbacks = 0; + CRYPTO_THREAD_unlock(prov->store->lock); + } return 1; } return 0; diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index d01673e7674..d74ce57fef2 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -40,7 +40,7 @@ ossl_provider_get_capabilities * Activate the Provider * If the Provider is a module, the module will be loaded */ - int ossl_provider_activate(OSSL_PROVIDER *prov); + int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks); int ossl_provider_deactivate(OSSL_PROVIDER *prov); /* Check if provider is available (activated) */ int ossl_provider_available(OSSL_PROVIDER *prov); @@ -178,6 +178,9 @@ be located in that module, and called. =back +If I is zero, fallbacks are disabled. If it is nonzero, +fallbacks are left unchanged. + ossl_provider_deactivate() "deactivates" the provider for the given provider object I by decrementing its activation count. When that count reaches zero, the activation flag is cleared. @@ -277,8 +280,8 @@ it has been incremented. ossl_provider_free() doesn't return any value. ossl_provider_set_module_path(), ossl_provider_set_fallback(), -ossl_provider_activate() and ossl_provider_deactivate() return 1 on -success, or 0 on error. +ossl_provider_activate(), ossl_provider_activate_leave_fallbacks() and +ossl_provider_deactivate() return 1 on success, or 0 on error. ossl_provider_available() return 1 if the provider is available, otherwise 0. diff --git a/doc/man3/OSSL_PROVIDER.pod b/doc/man3/OSSL_PROVIDER.pod index 81a2ac2bcb9..e5c451259a9 100644 --- a/doc/man3/OSSL_PROVIDER.pod +++ b/doc/man3/OSSL_PROVIDER.pod @@ -21,7 +21,8 @@ OSSL_PROVIDER_get_capabilities, OSSL_PROVIDER_self_test const char *path); 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); + OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, + 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, @@ -79,9 +80,9 @@ entry point, C. OSSL_PROVIDER_try_load() functions like OSSL_PROVIDER_load(), except that it does not disable the fallback providers if the provider cannot be -loaded and initialized. -If the provider loads successfully, however, the fallback providers are -disabled. +loaded and initialized or if I is zero. +If the provider loads successfully and I is nonzero, the +fallback providers are disabled. OSSL_PROVIDER_unload() unloads the given provider. For a provider added with OSSL_PROVIDER_add_builtin(), this simply diff --git a/include/internal/provider.h b/include/internal/provider.h index a91c515f04d..fbe3154b53c 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -49,7 +49,7 @@ int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx); * Activate the Provider * If the Provider is a module, the module will be loaded */ -int ossl_provider_activate(OSSL_PROVIDER *prov); +int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks); int ossl_provider_deactivate(OSSL_PROVIDER *prov); /* Check if the provider is available (activated) */ int ossl_provider_available(OSSL_PROVIDER *prov); diff --git a/include/openssl/provider.h b/include/openssl/provider.h index 723201e1c58..a8720aaa7ee 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -22,7 +22,8 @@ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *, const char *path); /* Load and unload a provider */ OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *, const char *name); -OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *, const char *name); +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *, const char *name, + 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/test/provider_internal_test.c b/test/provider_internal_test.c index 4b2b6d5349f..fc04d2d9252 100644 --- a/test/provider_internal_test.c +++ b/test/provider_internal_test.c @@ -26,7 +26,7 @@ static int test_provider(OSSL_PROVIDER *prov, const char *expected_greeting) int ret = 0; ret = - TEST_true(ossl_provider_activate(prov)) + TEST_true(ossl_provider_activate(prov, 0)) && TEST_true(ossl_provider_get_params(prov, greeting_request)) && TEST_ptr(greeting = greeting_request[0].data) && TEST_size_t_gt(greeting_request[0].data_size, 0)