Browse Source

Correctly activate the provider in OSSL_PROVIDER_try_load

If during OSSL_PROVIDER_try_load() we attempt to load a provider, but
adding to the store gives back a different provider, then we need to
ensure this different provider has its activation count increased.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16980)
Matt Caswell 2 years ago
parent
commit
1e8ed3e596
2 changed files with 19 additions and 2 deletions
  1. 6 0
      crypto/provider.c
  2. 13 2
      crypto/provider_conf.c

+ 6 - 0
crypto/provider.c

@@ -39,6 +39,12 @@ OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name,
         ossl_provider_free(prov);
         return NULL;
     }
+    if (actual != prov) {
+        if (!ossl_provider_activate(actual, 1, 0)) {
+            ossl_provider_free(actual);
+            return NULL;
+        }
+    }
 
     return actual;
 }

+ 13 - 2
crypto/provider_conf.c

@@ -224,11 +224,22 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
                 } else if (!ossl_provider_add_to_store(prov, &actual, 0)) {
                     ossl_provider_deactivate(prov, 1);
                     ok = 0;
+                } else if (actual != prov
+                           && !ossl_provider_activate(actual, 1, 0)) {
+                    ossl_provider_free(actual);
+                    ok = 0;
                 } else {
                     if (pcgbl->activated_providers == NULL)
                         pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null();
-                    sk_OSSL_PROVIDER_push(pcgbl->activated_providers, actual);
-                    ok = 1;
+                    if (pcgbl->activated_providers == NULL
+                        || !sk_OSSL_PROVIDER_push(pcgbl->activated_providers,
+                                                  actual)) {
+                        ossl_provider_deactivate(actual, 1);
+                        ossl_provider_free(actual);
+                        ok = 0;
+                    } else {
+                        ok = 1;
+                    }
                 }
             }
             if (!ok)