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)
This commit is contained in:
Richard Levitte 2019-03-21 08:44:06 +01:00
parent 5516c19b03
commit ac1055ef13
5 changed files with 92 additions and 22 deletions

View file

@ -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"},

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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