provider: disable fall-backs if OSSL_PROVIDER_load() fails.
authorPauli <paul.dale@oracle.com>
Thu, 13 Aug 2020 00:02:01 +0000 (10:02 +1000)
committerPauli <paul.dale@oracle.com>
Fri, 14 Aug 2020 08:17:47 +0000 (18:17 +1000)
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 <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12625)

crypto/provider.c
crypto/provider_core.c
doc/man3/OSSL_PROVIDER.pod
include/internal/provider.h
include/openssl/provider.h
util/libcrypto.num

index 40c837d8c0fe3271faefd94547508e6adae52e0a..e05279b89d0609cf59418427ab37c0e1ebc06148 100644 (file)
@@ -13,7 +13,7 @@
 #include <openssl/core_names.h>
 #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);
index 4b5b0136080ba278162e95c55a9dd1ec52d1326b..a714a71681bd572d84426932882c92de51692c28 100644 (file)
@@ -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)
 {
index 6a1fdd204e31d6444b5f401ed2c9b9167107e377..7fe8feb9dda491f2863052dada27acb012185234 100644 (file)
@@ -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_init>.
 
+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<provider-base(7)/CAPABILTIIES>.
 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<NULL> on error.
+OSSL_PROVIDER_load() and OSSL_PROVIDER_try_load() return a pointer to a
+provider object on success, or B<NULL> on error.
 
 OSSL_PROVIDER_available() returns 1 if the named provider is available,
 otherwise 0.
index 38bbd3bbefbf73c9a0cf1ab3e41f9927b2e1b234..0930e5674403bd3770b7e064aed5bb1bcf39fdc1 100644 (file)
@@ -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
index 5470984e133bf17cbf55ae471ac3aba2e0405fb7..ad9d8e65690f58dda627e429ea0bca674da7c674 100644 (file)
@@ -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,
index a2b5a5c6ff816bf6bde793d6cd2342345ab98fc3..838d1e686d51892979c888e56dbb06705497e596 100644 (file)
@@ -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: