From: Pauli Date: Thu, 13 Aug 2020 00:02:01 +0000 (+1000) Subject: provider: disable fall-backs if OSSL_PROVIDER_load() fails. X-Git-Tag: openssl-3.0.0-alpha7~569 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=ebe3f24b3d53e503bd37a2a08a8b1f896014c30d provider: disable fall-backs if OSSL_PROVIDER_load() fails. If an attempt is made to load a provider and it fails, the fall-back mechanism should be disabled to prevent the user getting some weird happening. E.g. a failure to load the FIPS provider should not allow the default to load as a fall-back. The OSSL_PROVIDER_try_load() call has been added, to allow a provider to be loaded without disabling the fall-back mechanism if it fails. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/12625) --- diff --git a/crypto/provider.c b/crypto/provider.c index 40c837d8c0..e05279b89d 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -13,7 +13,7 @@ #include #include "internal/provider.h" -OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name) +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OPENSSL_CTX *libctx, const char *name) { OSSL_PROVIDER *prov = NULL; @@ -30,6 +30,14 @@ OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name) return prov; } +OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_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 NULL; +} + int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) { ossl_provider_free(prov); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 4b5b013608..a714a71681 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -195,6 +195,17 @@ static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx) return store; } +int ossl_provider_disable_fallback_loading(OPENSSL_CTX *libctx) +{ + struct provider_store_st *store; + + if ((store = get_provider_store(libctx)) != NULL) { + store->use_fallbacks = 0; + return 1; + } + return 0; +} + OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name, int noconfig) { diff --git a/doc/man3/OSSL_PROVIDER.pod b/doc/man3/OSSL_PROVIDER.pod index 6a1fdd204e..7fe8feb9dd 100644 --- a/doc/man3/OSSL_PROVIDER.pod +++ b/doc/man3/OSSL_PROVIDER.pod @@ -3,7 +3,7 @@ =head1 NAME OSSL_PROVIDER_set_default_search_path, -OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_unload, +OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_try_load, OSSL_PROVIDER_unload, OSSL_PROVIDER_available, OSSL_PROVIDER_do_all, OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params, OSSL_PROVIDER_query_operation, OSSL_PROVIDER_get0_provider_ctx, @@ -21,6 +21,7 @@ OSSL_PROVIDER_get_capabilities, OSSL_PROVIDER_self_test const char *path); OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name); + OSSL_PROVIDER *OSSL_PROVIDER_try_load(OPENSSL_CTX *libctx, const char *name); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name); int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, @@ -76,6 +77,12 @@ OSSL_PROVIDER_add_builtin() and run its given initialization function, or load a provider module with the given name and run its provider entry point, C. +OSSL_PROVIDER_try_load() functions like OSSL_PROVIDER_load(), except that +it does not disable the fall-back providers if the provider cannot be +loaded and initialized. +If the provider loads successfully, however, the fall-back providers are +disabled. + OSSL_PROVIDER_unload() unloads the given provider. For a provider added with OSSL_PROVIDER_add_builtin(), this simply runs its teardown function. @@ -130,8 +137,8 @@ L. OSSL_PROVIDER_add(), OSSL_PROVIDER_unload(), OSSL_PROVIDER_get_params() and OSSL_PROVIDER_get_capabilities() return 1 on success, or 0 on error. -OSSL_PROVIDER_load() returns a pointer to a provider object on -success, or B on error. +OSSL_PROVIDER_load() and OSSL_PROVIDER_try_load() return a pointer to a +provider object on success, or B on error. OSSL_PROVIDER_available() returns 1 if the named provider is available, otherwise 0. diff --git a/include/internal/provider.h b/include/internal/provider.h index 38bbd3bbef..0930e56744 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -41,6 +41,9 @@ 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); +/* Disable fallback loading */ +int ossl_provider_disable_fallback_loading(OPENSSL_CTX *libctx); + /* * Activate the Provider * If the Provider is a module, the module will be loaded diff --git a/include/openssl/provider.h b/include/openssl/provider.h index 5470984e13..ad9d8e6569 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -21,6 +21,7 @@ int OSSL_PROVIDER_set_default_search_path(OPENSSL_CTX *, const char *path); /* Load and unload a provider */ OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name); +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OPENSSL_CTX *, const char *name); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OPENSSL_CTX *, const char *name); int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, diff --git a/util/libcrypto.num b/util/libcrypto.num index a2b5a5c6ff..838d1e686d 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4487,6 +4487,7 @@ OSSL_trace_enabled ? 3_0_0 EXIST::FUNCTION: OSSL_trace_begin ? 3_0_0 EXIST::FUNCTION: OSSL_trace_end ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_load ? 3_0_0 EXIST::FUNCTION: +OSSL_PROVIDER_try_load ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_unload ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_add_builtin ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_gettable_params ? 3_0_0 EXIST::FUNCTION: