provider: add option to load a provider without disabling the fallbacks.
authorPauli <ppzgs1@gmail.com>
Wed, 17 Feb 2021 23:16:26 +0000 (09:16 +1000)
committerPauli <ppzgs1@gmail.com>
Tue, 23 Feb 2021 13:24:41 +0000 (23:24 +1000)
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 <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13652)

crypto/provider.c
crypto/provider_conf.c
crypto/provider_core.c
doc/internal/man3/ossl_provider_new.pod
doc/man3/OSSL_PROVIDER.pod
include/internal/provider.h
include/openssl/provider.h
test/provider_internal_test.c

index bd8f75a2c1da820ea01921c22ab3cfde86bc2ac4..90c31f3ac53bd37251d092672fed4f1d9137936c 100644 (file)
@@ -13,7 +13,8 @@
 #include <openssl/core_names.h>
 #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;
 }
 
index 709e7a1c515a22351a2a191fd72e495060e5ceb3..cbae99a47453a72af1f2af5073c8a150472c7d46 100644 (file)
@@ -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)
index 627ff384e1406f40e7216850459aa99e03b0759f..da751e60cef6525e0e02103d88b8889ad95e317c 100644 (file)
@@ -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;
index d01673e7674c369034e43c63b5797c38622e3d1b..d74ce57fef225502528f7ed49b8ab514f69d00a1 100644 (file)
@@ -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<retain_fallbacks> 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<prov> 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.
index 81a2ac2bcb9ee5f306c9483904eb5602bff42ae5..e5c451259a9ee558a4328f132d37e44d5ecc5553 100644 (file)
@@ -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_init>.
 
 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<retain_fallbacks> is zero.
+If the provider loads successfully and I<retain_fallbacks> 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
index a91c515f04d1cc0fd24265c07ffce939ff78819d..fbe3154b53ca2e752b8c7baf6bca6fee03b2c171 100644 (file)
@@ -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);
index 723201e1c589e4530e6cbef2de68c3cf6aca970a..a8720aaa7ee4904b5ba53f6ceec02392e6350f76 100644 (file)
@@ -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,
index 4b2b6d5349fe6c9f54bf2491cf51575445f1e085..fc04d2d9252f6c021b7c5aeb9870cf9aca326d14 100644 (file)
@@ -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)