summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-05-11 16:50:27 +0100
committerMatt Caswell <matt@openssl.org>2021-05-20 09:35:41 +0100
commitb1c053acdaaee5e653949932f9999370edfc64db (patch)
tree7415bb7e2ab85cddc2f4e88c36d6924954908584
parent366bf9aedbbf719097a891dbf675f46dab8c9276 (diff)
Ensure mirroring of properties works for subsequent updates
If the global properties are updated after a provider with a child libctx has already started we need to make sure those updates are mirrored in that child. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15242)
-rw-r--r--crypto/evp/evp_cnf.c2
-rw-r--r--crypto/evp/evp_fetch.c28
-rw-r--r--crypto/property/property.c48
-rw-r--r--crypto/provider_child.c1
-rw-r--r--include/internal/property.h3
-rw-r--r--test/p_test.c16
-rw-r--r--test/provider_test.c20
7 files changed, 101 insertions, 17 deletions
diff --git a/crypto/evp/evp_cnf.c b/crypto/evp/evp_cnf.c
index 145f52fe1d..c13652ca0f 100644
--- a/crypto/evp/evp_cnf.c
+++ b/crypto/evp/evp_cnf.c
@@ -51,7 +51,7 @@ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
return 0;
}
} else if (strcmp(oval->name, "default_properties") == 0) {
- if (!evp_set_default_properties_int(cnf->libctx, oval->value, 0)) {
+ if (!evp_set_default_properties_int(cnf->libctx, oval->value, 0, 0)) {
ERR_raise(ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE);
return 0;
}
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index 67e9ad878f..e71d827d4b 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -384,15 +384,28 @@ int evp_method_store_flush(OSSL_LIB_CTX *libctx)
static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx,
OSSL_PROPERTY_LIST *def_prop,
- int loadconfig)
+ int loadconfig,
+ int mirrored)
{
OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig);
if (plp != NULL && store != NULL) {
+#ifndef FIPS_MODULE
char *propstr = NULL;
size_t strsz;
+ if (mirrored) {
+ if (ossl_global_properties_no_mirrored(libctx))
+ return 0;
+ } else {
+ /*
+ * These properties have been explicitly set on this libctx, so
+ * don't allow any mirroring from a parent libctx.
+ */
+ ossl_global_properties_stop_mirroring(libctx);
+ }
+
strsz = ossl_property_list_to_string(libctx, def_prop, NULL, 0);
if (strsz > 0)
propstr = OPENSSL_malloc(strsz);
@@ -406,10 +419,11 @@ static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx,
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);
+#endif
+ ossl_property_free(*plp);
+ *plp = def_prop;
if (store != NULL)
return ossl_method_store_flush_cache(store, 0);
}
@@ -418,7 +432,7 @@ static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx,
}
int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq,
- int loadconfig)
+ int loadconfig, int mirrored)
{
OSSL_PROPERTY_LIST *pl = NULL;
@@ -426,7 +440,7 @@ int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq,
ERR_raise(ERR_LIB_EVP, EVP_R_DEFAULT_QUERY_PARSE_ERROR);
return 0;
}
- if (!evp_set_parsed_default_properties(libctx, pl, loadconfig)) {
+ if (!evp_set_parsed_default_properties(libctx, pl, loadconfig, mirrored)) {
ossl_property_free(pl);
return 0;
}
@@ -435,7 +449,7 @@ int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq,
int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq)
{
- return evp_set_default_properties_int(libctx, propq, 1);
+ return evp_set_default_properties_int(libctx, propq, 1, 0);
}
static int evp_default_properties_merge(OSSL_LIB_CTX *libctx, const char *propq)
@@ -457,7 +471,7 @@ static int evp_default_properties_merge(OSSL_LIB_CTX *libctx, const char *propq)
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
- if (!evp_set_parsed_default_properties(libctx, pl2, 0)) {
+ if (!evp_set_parsed_default_properties(libctx, pl2, 0, 0)) {
ossl_property_free(pl2);
return 0;
}
diff --git a/crypto/property/property.c b/crypto/property/property.c
index da6bc84e27..a769a7307e 100644
--- a/crypto/property/property.c
+++ b/crypto/property/property.c
@@ -74,25 +74,31 @@ typedef struct {
DEFINE_SPARSE_ARRAY_OF(ALGORITHM);
+typedef struct ossl_global_properties_st {
+ OSSL_PROPERTY_LIST *list;
+#ifndef FIPS_MODULE
+ unsigned int no_mirrored : 1;
+#endif
+} OSSL_GLOBAL_PROPERTIES;
+
static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid);
/* Global properties are stored per library context */
-static void ossl_ctx_global_properties_free(void *vstore)
+static void ossl_ctx_global_properties_free(void *vglobp)
{
- OSSL_PROPERTY_LIST **plp = vstore;
+ OSSL_GLOBAL_PROPERTIES *globp = vglobp;
- if (plp != NULL) {
- ossl_property_free(*plp);
- OPENSSL_free(plp);
+ if (globp != NULL) {
+ ossl_property_free(globp->list);
+ OPENSSL_free(globp);
}
}
static void *ossl_ctx_global_properties_new(OSSL_LIB_CTX *ctx)
{
- return OPENSSL_zalloc(sizeof(OSSL_PROPERTY_LIST **));
+ return OPENSSL_zalloc(sizeof(OSSL_GLOBAL_PROPERTIES));
}
-
static const OSSL_LIB_CTX_METHOD ossl_ctx_global_properties_method = {
OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
ossl_ctx_global_properties_new,
@@ -102,13 +108,37 @@ static const OSSL_LIB_CTX_METHOD ossl_ctx_global_properties_method = {
OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OSSL_LIB_CTX *libctx,
int loadconfig)
{
+ OSSL_GLOBAL_PROPERTIES *globp;
+
#ifndef FIPS_MODULE
if (loadconfig && !OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL))
return NULL;
#endif
- return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES,
- &ossl_ctx_global_properties_method);
+ globp = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES,
+ &ossl_ctx_global_properties_method);
+
+ return &globp->list;
+}
+
+#ifndef FIPS_MODULE
+int ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx)
+{
+ OSSL_GLOBAL_PROPERTIES *globp
+ = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES,
+ &ossl_ctx_global_properties_method);
+
+ return globp->no_mirrored ? 1 : 0;
+}
+
+void ossl_global_properties_stop_mirroring(OSSL_LIB_CTX *libctx)
+{
+ OSSL_GLOBAL_PROPERTIES *globp
+ = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES,
+ &ossl_ctx_global_properties_method);
+
+ globp->no_mirrored = 1;
}
+#endif
static int ossl_method_up_ref(METHOD *method)
{
diff --git a/crypto/provider_child.c b/crypto/provider_child.c
index e4d586bf7d..7ab161b795 100644
--- a/crypto/provider_child.c
+++ b/crypto/provider_child.c
@@ -15,6 +15,7 @@
#include <openssl/evp.h>
#include "internal/provider.h"
#include "internal/cryptlib.h"
+#include "crypto/evp.h"
DEFINE_STACK_OF(OSSL_PROVIDER)
diff --git a/include/internal/property.h b/include/internal/property.h
index 85f602d1e5..856cd740ad 100644
--- a/include/internal/property.h
+++ b/include/internal/property.h
@@ -68,4 +68,7 @@ size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
const OSSL_PROPERTY_LIST *list, char *buf,
size_t bufsize);
+int ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx);
+void ossl_global_properties_stop_mirroring(OSSL_LIB_CTX *libctx);
+
#endif
diff --git a/test/p_test.c b/test/p_test.c
index d4e187f94a..80f0784dd9 100644
--- a/test/p_test.c
+++ b/test/p_test.c
@@ -183,6 +183,22 @@ static int p_get_params(void *provctx, OSSL_PARAM params[])
} else {
ok = 0;
}
+ } else if (strcmp(p->key, "stop-property-mirror") == 0) {
+ /*
+ * Setting the default properties explicitly should stop mirroring
+ * of properties from the parent libctx.
+ */
+ unsigned int stopsuccess = 0;
+
+#ifdef PROVIDER_INIT_FUNCTION_NAME
+ stopsuccess = EVP_set_default_properties(ctx->libctx, NULL);
+#endif
+ if (p->data_size >= sizeof(stopsuccess)) {
+ *(unsigned int *)p->data = stopsuccess;
+ p->return_size = sizeof(stopsuccess);
+ } else {
+ ok = 0;
+ }
}
}
return ok;
diff --git a/test/provider_test.c b/test/provider_test.c
index 79a1a375e8..807b8fcf22 100644
--- a/test/provider_test.c
+++ b/test/provider_test.c
@@ -26,6 +26,13 @@ static OSSL_PARAM digest_check[] = {
{ NULL, 0, NULL, 0, 0 }
};
+static unsigned int stopsuccess = 0;
+static OSSL_PARAM stop_property_mirror[] = {
+ { "stop-property-mirror", OSSL_PARAM_UNSIGNED_INTEGER, &stopsuccess,
+ sizeof(stopsuccess) },
+ { NULL, 0, NULL, 0, 0 }
+};
+
static int test_provider(OSSL_LIB_CTX **libctx, const char *name,
OSSL_PROVIDER *legacy)
{
@@ -66,6 +73,19 @@ static int test_provider(OSSL_LIB_CTX **libctx, const char *name,
if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
|| !TEST_true(digestsuccess))
goto err;
+
+ /*
+ * Check that a provider can prevent property mirroring if it sets its
+ * own properties explicitly
+ */
+ if (!TEST_true(OSSL_PROVIDER_get_params(prov, stop_property_mirror))
+ || !TEST_true(stopsuccess))
+ goto err;
+ EVP_set_default_properties(*libctx, "fips=yes");
+ if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
+ || !TEST_true(digestsuccess))
+ goto err;
+ EVP_set_default_properties(*libctx, "");
}
if (!TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
|| !TEST_ptr(greeting = greeting_request[0].data)