Commit ac1055ef authored by Richard Levitte's avatar Richard Levitte
Browse files

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: default avatarPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8549)
parent 5516c19b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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"},
+2 −0
Original line number Diff line number Diff line
@@ -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
+81 −21
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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