summaryrefslogtreecommitdiff
path: root/crypto/provider_core.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-03-21 08:44:06 +0100
committerRichard Levitte <levitte@openssl.org>2019-04-03 11:42:48 +0200
commitac1055ef13ccb5789e2bed7b9688c8eb16dd05ce (patch)
tree732d10768e106db34e3d36b112c68500743080ad /crypto/provider_core.c
parent5516c19b0314ef9416c5b02ae6347c4f52209e6a (diff)
downloadopenssl-new-ac1055ef13ccb5789e2bed7b9688c8eb16dd05ce.tar.gz
Replumbing: add functionality to set provider parameters
Provider parameters are parameters set by the core that the provider can retrieve. The primary use it to support making OpenSSL configuration data available to the provider. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8549)
Diffstat (limited to 'crypto/provider_core.c')
-rw-r--r--crypto/provider_core.c102
1 files changed, 81 insertions, 21 deletions
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 7a184a7d67..9f4c017045 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -9,6 +9,7 @@
#include <openssl/core.h>
#include <openssl/core_numbers.h>
+#include <openssl/params.h>
#include <openssl/opensslv.h>
#include "internal/cryptlib.h"
#include "internal/nelem.h"
@@ -25,6 +26,12 @@ static OSSL_PROVIDER *provider_new(const char *name,
* =========================
*/
+typedef struct {
+ char *name;
+ char *value;
+} INFOPAIR;
+DEFINE_STACK_OF(INFOPAIR)
+
struct provider_store_st; /* Forward declaration */
struct ossl_provider_st {
@@ -36,8 +43,10 @@ struct ossl_provider_st {
CRYPTO_REF_COUNT refcnt;
CRYPTO_RWLOCK *refcnt_lock; /* For the ref counter */
char *name;
+ char *path;
DSO *module;
OSSL_provider_init_fn *init_function;
+ STACK_OF(INFOPAIR) *parameters;
struct provider_store_st *store; /* The store this instance belongs to */
/* Provider side functions */
@@ -243,6 +252,13 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
return prov;
}
+static void free_infopair(INFOPAIR *pair)
+{
+ OPENSSL_free(pair->name);
+ OPENSSL_free(pair->value);
+ OPENSSL_free(pair);
+}
+
void ossl_provider_free(OSSL_PROVIDER *prov)
{
if (prov != NULL) {
@@ -270,6 +286,8 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
if (ref == 0) {
DSO_free(prov->module);
OPENSSL_free(prov->name);
+ OPENSSL_free(prov->path);
+ sk_INFOPAIR_pop_free(prov->parameters, free_infopair);
#ifndef HAVE_ATOMICS
CRYPTO_THREAD_lock_free(prov->refcnt_lock);
#endif
@@ -278,6 +296,40 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
}
}
+/* Setters */
+int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path)
+{
+ OPENSSL_free(prov->path);
+ if (module_path == NULL)
+ return 1;
+ if ((prov->path = OPENSSL_strdup(module_path)) != NULL)
+ return 1;
+ CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+int ossl_provider_add_parameter(OSSL_PROVIDER *prov,
+ const char *name, const char *value)
+{
+ INFOPAIR *pair = NULL;
+
+ if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL
+ && (prov->parameters != NULL
+ || (prov->parameters = sk_INFOPAIR_new_null()) != NULL)
+ && (pair->name = OPENSSL_strdup(name)) != NULL
+ && (pair->value = OPENSSL_strdup(value)) != NULL
+ && sk_INFOPAIR_push(prov->parameters, pair) > 0)
+ return 1;
+
+ if (pair != NULL) {
+ OPENSSL_free(pair->name);
+ OPENSSL_free(pair->value);
+ OPENSSL_free(pair);
+ }
+ CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
/*
* Provider activation.
*
@@ -310,8 +362,9 @@ static int provider_activate(OSSL_PROVIDER *prov)
*/
if (prov->init_function == NULL) {
if (prov->module == NULL) {
- char *platform_module_name = NULL;
- char *module_path = NULL;
+ char *allocated_path = NULL;
+ const char *module_path = NULL;
+ char *merged_path = NULL;
const char *load_dir = ossl_safe_getenv("OPENSSL_MODULES");
if ((prov->module = DSO_new()) == NULL) {
@@ -324,19 +377,22 @@ static int provider_activate(OSSL_PROVIDER *prov)
DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS,
DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL);
- if ((platform_module_name =
- DSO_convert_filename(prov->module, prov->name)) == NULL
- || (module_path =
- DSO_merge(prov->module, platform_module_name,
- load_dir)) == NULL
- || DSO_load(prov->module, module_path, NULL,
- DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == NULL) {
+
+ module_path = prov->path;
+ if (module_path == NULL)
+ module_path = allocated_path =
+ DSO_convert_filename(prov->module, prov->name);
+ if (module_path != NULL)
+ merged_path = DSO_merge(prov->module, module_path, load_dir);
+
+ if (merged_path == NULL
+ || (DSO_load(prov->module, merged_path, NULL, 0)) == NULL) {
DSO_free(prov->module);
prov->module = NULL;
}
- OPENSSL_free(platform_module_name);
- OPENSSL_free(module_path);
+ OPENSSL_free(merged_path);
+ OPENSSL_free(allocated_path);
}
if (prov->module != NULL)
@@ -565,17 +621,21 @@ static const OSSL_ITEM *core_get_param_types(const OSSL_PROVIDER *prov)
static int core_get_params(const OSSL_PROVIDER *prov, const OSSL_PARAM params[])
{
int i;
+ const OSSL_PARAM *p;
- for (i = 0; params[i].key != NULL; i++) {
- if (strcmp(params[i].key, "openssl-version") == 0) {
- *(void **)params[i].data = OPENSSL_VERSION_STR;
- if (params[i].return_size)
- *params[i].return_size = sizeof(OPENSSL_VERSION_STR);
- } else if (strcmp(params[i].key, "provider-name") == 0) {
- *(void **)params[i].data = prov->name;
- if (params[i].return_size)
- *params[i].return_size = strlen(prov->name) + 1;
- }
+ if ((p = OSSL_PARAM_locate(params, "openssl-version")) != NULL)
+ OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR);
+ if ((p = OSSL_PARAM_locate(params, "provider-name")) != NULL)
+ OSSL_PARAM_set_utf8_ptr(p, prov->name);
+
+ if (prov->parameters == NULL)
+ return 1;
+
+ for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) {
+ INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i);
+
+ if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL)
+ OSSL_PARAM_set_utf8_ptr(p, pair->value);
}
return 1;