Always try to construct methods as new provider might be added

Otherwise optional properties can be incorrectly ignored.

Fixes #18262

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18269)
diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c
index 6b25379..faa6ebd 100644
--- a/crypto/core_fetch.c
+++ b/crypto/core_fetch.c
@@ -123,31 +123,38 @@
                             OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data)
 {
     void *method = NULL;
+    OSSL_PROVIDER *provider = provider_rw != NULL ? *provider_rw : NULL;
+    struct construct_data_st cbdata;
 
-    if ((method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw,
-                           mcm_data)) == NULL) {
-        OSSL_PROVIDER *provider = provider_rw != NULL ? *provider_rw : NULL;
-        struct construct_data_st cbdata;
+    /*
+     * We might be tempted to try to look into the method store without
+     * constructing to see if we can find our method there already.
+     * Unfortunately that does not work well if the query contains
+     * optional properties as newly loaded providers can match them better.
+     * We trust that ossl_method_construct_precondition() and
+     * ossl_method_construct_postcondition() make sure that the
+     * ossl_algorithm_do_all() does very little when methods from
+     * a provider have already been constructed.
+     */
 
-        cbdata.store = NULL;
-        cbdata.force_store = force_store;
-        cbdata.mcm = mcm;
-        cbdata.mcm_data = mcm_data;
-        ossl_algorithm_do_all(libctx, operation_id, provider,
-                              ossl_method_construct_precondition,
-                              ossl_method_construct_this,
-                              ossl_method_construct_postcondition,
-                              &cbdata);
+    cbdata.store = NULL;
+    cbdata.force_store = force_store;
+    cbdata.mcm = mcm;
+    cbdata.mcm_data = mcm_data;
+    ossl_algorithm_do_all(libctx, operation_id, provider,
+                          ossl_method_construct_precondition,
+                          ossl_method_construct_this,
+                          ossl_method_construct_postcondition,
+                          &cbdata);
 
-        /* If there is a temporary store, try there first */
-        if (cbdata.store != NULL)
-            method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw,
-                              mcm_data);
+    /* If there is a temporary store, try there first */
+    if (cbdata.store != NULL)
+        method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw,
+                          mcm_data);
 
-        /* If no method was found yet, try the global store */
-        if (method == NULL)
-            method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);
-    }
+    /* If no method was found yet, try the global store */
+    if (method == NULL)
+        method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);
 
     return method;
 }