diff options
author | Matt Caswell <matt@openssl.org> | 2021-06-18 15:56:54 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-06-24 14:48:14 +0100 |
commit | 352d482a2990cc04adff48aeda9c080d4a839f1e (patch) | |
tree | bee0041c8a4b777653125cab5ed8280b19def1b0 /crypto/provider_conf.c | |
parent | 1d74203cf5d8542d349fbb2d5f35ad40994dec9f (diff) |
Instantiate configuration supplied providers when we need them
If provider specified in a config file are not "activated" then we defer
instantiating the provider object until it is actually needed.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Diffstat (limited to 'crypto/provider_conf.c')
-rw-r--r-- | crypto/provider_conf.c | 83 |
1 files changed, 59 insertions, 24 deletions
diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 977d469808..d53e1be2dc 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -14,6 +14,7 @@ #include <openssl/safestack.h> #include "internal/provider.h" #include "internal/cryptlib.h" +#include "provider_local.h" DEFINE_STACK_OF(OSSL_PROVIDER) @@ -61,6 +62,7 @@ static const char *skip_dot(const char *name) } static int provider_conf_params(OSSL_PROVIDER *prov, + struct provider_info_st *provinfo, const char *name, const char *value, const CONF *cnf) { @@ -88,14 +90,18 @@ static int provider_conf_params(OSSL_PROVIDER *prov, return 0; buffer[buffer_len] = '\0'; OPENSSL_strlcat(buffer, sectconf->name, sizeof(buffer)); - if (!provider_conf_params(prov, buffer, sectconf->value, cnf)) + if (!provider_conf_params(prov, provinfo, buffer, sectconf->value, + cnf)) return 0; } OSSL_TRACE1(CONF, "Provider params: finish section %s\n", value); } else { OSSL_TRACE2(CONF, "Provider params: %s = %s\n", name, value); - ok = ossl_provider_add_parameter(prov, name, value); + if (prov != NULL) + ok = ossl_provider_add_parameter(prov, name, value); + else + ok = ossl_provider_info_add_parameter(provinfo, name, value); } return ok; @@ -149,33 +155,62 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, activate = 1; } - prov = ossl_provider_find(libctx, name, 1); - if (prov == NULL) - prov = ossl_provider_new(libctx, name, NULL, 1); - if (prov == NULL) { - if (soft) - ERR_clear_error(); - return 0; - } + if (activate) { + prov = ossl_provider_find(libctx, name, 1); + if (prov == NULL) + prov = ossl_provider_new(libctx, name, NULL, 1); + if (prov == NULL) { + if (soft) + ERR_clear_error(); + return 0; + } - if (path != NULL) - ossl_provider_set_module_path(prov, path); + if (path != NULL) + ossl_provider_set_module_path(prov, path); - ok = provider_conf_params(prov, NULL, value, cnf); + ok = provider_conf_params(prov, NULL, NULL, value, cnf); - if (ok && activate) { - if (!ossl_provider_activate(prov, 0, 1)) { - ok = 0; - } else { - if (pcgbl->activated_providers == NULL) - pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); - sk_OSSL_PROVIDER_push(pcgbl->activated_providers, prov); - ok = 1; + if (ok) { + if (!ossl_provider_activate(prov, 0, 1)) { + ok = 0; + } else { + if (pcgbl->activated_providers == NULL) + pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); + sk_OSSL_PROVIDER_push(pcgbl->activated_providers, prov); + ok = 1; + } } - } - if (!(activate && ok)) - ossl_provider_free(prov); + if (!(activate && ok)) + ossl_provider_free(prov); + } else { + struct provider_info_st entry; + + memset(&entry, 0, sizeof(entry)); + ok = 1; + if (name != NULL) { + entry.name = OPENSSL_strdup(name); + if (entry.name == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ok = 0; + } + } + if (ok && path != NULL) { + entry.path = OPENSSL_strdup(path); + if (entry.path == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ok = 0; + } + } + if (ok) + ok = provider_conf_params(NULL, &entry, NULL, value, cnf); + if (ok && (entry.path != NULL || entry.parameters != NULL)) + ok = ossl_provider_info_add_to_store(libctx, &entry); + if (!ok || (entry.path == NULL && entry.parameters == NULL)) { + ossl_provider_info_clear(&entry); + } + + } return ok; } |