Add a callback for providers to know about global properties changes
authorMatt Caswell <matt@openssl.org>
Fri, 7 May 2021 16:59:47 +0000 (17:59 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 20 May 2021 08:32:40 +0000 (09:32 +0100)
Where a child libctx is in use it needs to know what the current global
properties are.

Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15242)

crypto/evp/evp_fetch.c
crypto/provider_child.c
crypto/provider_core.c
include/crypto/evp.h
include/internal/provider.h
include/openssl/core_dispatch.h

index fdb6d90f4dfdc8eab7d0d7206d27de53dd2cc5af..67e9ad878f8e58ff4a64889a292c40fa89b9316f 100644 (file)
@@ -389,12 +389,29 @@ static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx,
     OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
     OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig);
 
-    if (plp != NULL) {
+    if (plp != NULL && store != NULL) {
+        char *propstr = NULL;
+        size_t strsz;
+
+        strsz = ossl_property_list_to_string(libctx, def_prop, NULL, 0);
+        if (strsz > 0)
+            propstr = OPENSSL_malloc(strsz);
+        if (propstr == NULL) {
+            ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        if (ossl_property_list_to_string(libctx, def_prop, propstr,
+                                         strsz) == 0) {
+            OPENSSL_free(propstr);
+            ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
         ossl_property_free(*plp);
         *plp = def_prop;
+        ossl_provider_default_props_update(libctx, propstr);
+        OPENSSL_free(propstr);
         if (store != NULL)
             return ossl_method_store_flush_cache(store, 0);
-        return 1;
     }
     ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
     return 0;
@@ -467,6 +484,30 @@ int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable)
     return evp_default_properties_merge(libctx, query);
 }
 
+char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig)
+{
+    OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig);
+    char *propstr = NULL;
+    size_t sz;
+
+    sz = ossl_property_list_to_string(libctx, *plp, NULL, 0);
+    if (sz == 0) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
+        return NULL;
+    }
+
+    propstr = OPENSSL_malloc(sz);
+    if (propstr == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (ossl_property_list_to_string(libctx, *plp, propstr, sz) == 0) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
+        OPENSSL_free(propstr);
+        return NULL;
+    }
+    return propstr;
+}
 
 struct do_all_data_st {
     void (*user_fn)(void *method, void *arg);
index 14d005462419a1186f5229098d1c1161c0dedfe8..e4d586bf7d2d0f299af22b4c7f1846eb6a4dc3f3 100644 (file)
@@ -12,6 +12,7 @@
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.h>
 #include <openssl/provider.h>
+#include <openssl/evp.h>
 #include "internal/provider.h"
 #include "internal/cryptlib.h"
 
@@ -198,6 +199,13 @@ static int provider_remove_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata)
     return 1;
 }
 
+static int provider_global_props_cb(const char *props, void *cbdata)
+{
+    OSSL_LIB_CTX *ctx = cbdata;
+
+    return evp_set_default_properties_int(ctx, props, 0, 1);
+}
+
 int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
                                 const OSSL_CORE_HANDLE *handle,
                                 const OSSL_DISPATCH *in)
@@ -265,6 +273,7 @@ int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
     if (!gbl->c_provider_register_child_cb(gbl->handle,
                                            provider_create_child_cb,
                                            provider_remove_child_cb,
+                                           provider_global_props_cb,
                                            ctx))
         return 0;
 
index 9d5248de0dc63122c87d4a7fcc2056c82a74a866..3c2d14277581c50ed3463d45fb4aef8595f150d7 100644 (file)
@@ -47,6 +47,7 @@ typedef struct {
     OSSL_PROVIDER *prov;
     int (*create_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata);
     void (*remove_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata);
+    void (*global_props_cb)(const char *props, void *cbdata);
     void *cbdata;
 } OSSL_PROVIDER_CHILD_CB;
 DEFINE_STACK_OF(OSSL_PROVIDER_CHILD_CB)
@@ -1363,6 +1364,30 @@ int ossl_provider_convert_to_child(OSSL_PROVIDER *prov,
     return 1;
 }
 
+int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, const char *props)
+{
+#ifndef FIPS_MODULE
+    struct provider_store_st *store = NULL;
+    int i, max;
+    OSSL_PROVIDER_CHILD_CB *child_cb;
+
+    if ((store = get_provider_store(libctx)) == NULL)
+        return 0;
+
+    if (!CRYPTO_THREAD_read_lock(store->lock))
+        return 0;
+
+    max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs);
+    for (i = 0; i < max; i++) {
+        child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i);
+        child_cb->global_props_cb(props, child_cb->cbdata);
+    }
+
+    CRYPTO_THREAD_unlock(store->lock);
+#endif
+    return 1;
+}
+
 static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
                                            int (*create_cb)(
                                                const OSSL_CORE_HANDLE *provider,
@@ -1370,6 +1395,9 @@ static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
                                            void (*remove_cb)(
                                                const OSSL_CORE_HANDLE *provider,
                                                void *cbdata),
+                                           void (*global_props_cb)(
+                                               const char *props,
+                                               void *cbdata),
                                            void *cbdata)
 {
     /*
@@ -1382,6 +1410,7 @@ static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
     struct provider_store_st *store = NULL;
     int ret = 0, i, max;
     OSSL_PROVIDER_CHILD_CB *child_cb;
+    char *propsstr = NULL;
 
     if ((store = get_provider_store(libctx)) == NULL)
         return 0;
@@ -1392,12 +1421,19 @@ static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
     child_cb->prov = thisprov;
     child_cb->create_cb = create_cb;
     child_cb->remove_cb = remove_cb;
+    child_cb->global_props_cb = global_props_cb;
     child_cb->cbdata = cbdata;
 
     if (!CRYPTO_THREAD_write_lock(store->lock)) {
         OPENSSL_free(child_cb);
         return 0;
     }
+    propsstr = evp_get_global_properties_str(libctx, 0);
+
+    if (propsstr != NULL) {
+        global_props_cb(propsstr, cbdata);
+        OPENSSL_free(propsstr);
+    }
     max = sk_OSSL_PROVIDER_num(store->providers);
     for (i = 0; i < max; i++) {
         prov = sk_OSSL_PROVIDER_value(store->providers, i);
index 96a109e38b55c04af10cab63016a7a7784ebed1f..92a9f0fc29effe1e29e8e8a8afa4d6366b306be3 100644 (file)
@@ -886,7 +886,8 @@ int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx);
 
 int evp_method_store_flush(OSSL_LIB_CTX *libctx);
 int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq,
-                                   int loadconfig);
+                                   int loadconfig, int mirrored);
+char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig);
 
 void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force);
 
index 020cbc8a9ee066086950f9994b304fbbf404efe8..df20c76f90e823b5e8aada07f4c2e2b561884c87 100644 (file)
@@ -50,6 +50,7 @@ int ossl_provider_convert_to_child(OSSL_PROVIDER *prov,
 const OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov);
 int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate);
 int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate);
+int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, const char *props);
 
 /* Disable fallback loading */
 int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx);
index 5c453eaac0fe91d22a4fe4f790869183f7a8475f..458cbb1c9e2a865db5220e142614134d189e20b5 100644 (file)
@@ -196,6 +196,7 @@ OSSL_CORE_MAKE_FUNC(int, provider_register_child_cb,
                     (const OSSL_CORE_HANDLE *handle,
                      int (*create_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata),
                      int (*remove_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata),
+                     int (*global_props_cb)(const char *props, void *cbdata),
                      void *cbdata))
 OSSL_CORE_MAKE_FUNC(void, provider_deregister_child_cb,
                     (const OSSL_CORE_HANDLE *handle))