summaryrefslogtreecommitdiffstats
path: root/crypto/provider_conf.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-06-18 15:56:54 +0100
committerMatt Caswell <matt@openssl.org>2021-06-24 14:48:14 +0100
commit352d482a2990cc04adff48aeda9c080d4a839f1e (patch)
treebee0041c8a4b777653125cab5ed8280b19def1b0 /crypto/provider_conf.c
parent1d74203cf5d8542d349fbb2d5f35ad40994dec9f (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.c83
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;
}