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