From ac1055ef13ccb5789e2bed7b9688c8eb16dd05ce Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 21 Mar 2019 08:44:06 +0100 Subject: [PATCH] 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 (Merged from https://github.com/openssl/openssl/pull/8549) --- crypto/cpt_err.c | 4 ++ crypto/err/openssl.txt | 2 + crypto/provider_core.c | 102 ++++++++++++++++++++++++++++-------- include/internal/provider.h | 4 +- include/openssl/cryptoerr.h | 2 + 5 files changed, 92 insertions(+), 22 deletions(-) diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c index 3c3265dce5..cca8037855 100644 --- a/crypto/cpt_err.c +++ b/crypto/cpt_err.c @@ -50,8 +50,12 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = { "OSSL_PROVIDER_add_builtin"}, {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ACTIVATE, 0), "ossl_provider_activate"}, + {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, 0), + "ossl_provider_add_parameter"}, {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_NEW, 0), "ossl_provider_new"}, + {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH, 0), + "ossl_provider_set_module_path"}, {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_HMAC_INIT, 0), "pkey_hmac_init"}, {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_POLY1305_INIT, 0), "pkey_poly1305_init"}, diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 8808b25f56..a3f3d48ce8 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -392,7 +392,9 @@ CRYPTO_F_OPENSSL_SK_DEEP_COPY:127:OPENSSL_sk_deep_copy CRYPTO_F_OPENSSL_SK_DUP:128:OPENSSL_sk_dup CRYPTO_F_OSSL_PROVIDER_ACTIVATE:130:ossl_provider_activate CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN:132:OSSL_PROVIDER_add_builtin +CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER:139:ossl_provider_add_parameter CRYPTO_F_OSSL_PROVIDER_NEW:131:ossl_provider_new +CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH:140:ossl_provider_set_module_path CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init 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 #include +#include #include #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; diff --git a/include/internal/provider.h b/include/internal/provider.h index 8af20a7cfe..abd5ec4392 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -33,8 +33,10 @@ int ossl_provider_upref(OSSL_PROVIDER *prov); void ossl_provider_free(OSSL_PROVIDER *prov); /* Setters */ -int ossl_provider_add_module_location(OSSL_PROVIDER *prov, const char *loc); int ossl_provider_set_fallback(OSSL_PROVIDER *prov); +int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path); +int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name, + const char *value); /* * Activate the Provider diff --git a/include/openssl/cryptoerr.h b/include/openssl/cryptoerr.h index b38b272a24..4d44a1ce09 100644 --- a/include/openssl/cryptoerr.h +++ b/include/openssl/cryptoerr.h @@ -45,7 +45,9 @@ int ERR_load_CRYPTO_strings(void); # define CRYPTO_F_OPENSSL_SK_DUP 128 # define CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN 132 # define CRYPTO_F_OSSL_PROVIDER_ACTIVATE 130 +# define CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER 139 # define CRYPTO_F_OSSL_PROVIDER_NEW 131 +# define CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH 140 # define CRYPTO_F_PKEY_HMAC_INIT 123 # define CRYPTO_F_PKEY_POLY1305_INIT 124 # define CRYPTO_F_PKEY_SIPHASH_INIT 125 -- 2.39.2