Add a callback for providers to know about global properties changes

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)
This commit is contained in:
Matt Caswell 2021-05-07 17:59:47 +01:00
parent ad8570a8b6
commit 447588b69a
6 changed files with 92 additions and 3 deletions

View 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);

View 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;

View 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);

View 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);

View 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);

View 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))