Replumbing: add a configuration module for providers
This configuration module supports a configuration structure pretty much like the engine configuration module, i.e. something like this: openssl_conf = openssl_init [openssl_init] providers = provider_section [provider_section] # Configure the provider named "foo" foo = foo_section # Configure the provider named "bar" bar = bar_section [foo_section] # Override name given in the provider section identity = myfoo # The exact path of the module. This is platform specific module_path = /opt/openssl/modules/foo.so # Whether it should be automatically activated. Value is unimportant activate = whatever # Anything else goes as well, and becomes parameters that the # provider can get what = 1 # sub-sections will be followed as well ever = ever_section [ever_section] cookie = monster All the configurations in a provider section and its sub-sections become parameters for the provider to get, i.e. the "foo" provider will be able to get values for the following keys (with associated values shown): identity => myfoo module_path => /opt/openssl/modules/foo.so activate => whatever what => 1 ever.cookie => monster Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8549)
This commit is contained in:
parent
ac1055ef13
commit
abbc2c4083
7 changed files with 198 additions and 1 deletions
|
@ -9,7 +9,8 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
|||
|
||||
LIBS=../libcrypto
|
||||
# The Core
|
||||
SOURCE[../libcrypto]=provider_core.c provider_predefined.c core_fetch.c
|
||||
SOURCE[../libcrypto]=provider_core.c provider_predefined.c provider_conf.c \
|
||||
core_fetch.c
|
||||
|
||||
# Central utilities
|
||||
SOURCE[../libcrypto]=\
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "internal/provider.h"
|
||||
#include "conf_lcl.h"
|
||||
|
||||
/* Load all OpenSSL builtin modules */
|
||||
|
@ -28,4 +29,5 @@ void OPENSSL_load_builtin_modules(void)
|
|||
#endif
|
||||
EVP_add_alg_module();
|
||||
conf_add_ssl_module();
|
||||
ossl_provider_add_conf_module();
|
||||
}
|
||||
|
|
|
@ -63,6 +63,10 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
|
|||
"pkey_siphash_init"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_ACTIVATE, 0),
|
||||
"provider_activate"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_CONF_INIT, 0),
|
||||
"provider_conf_init"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_CONF_LOAD, 0),
|
||||
"provider_conf_load"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_NEW, 0), "provider_new"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_STORE_NEW, 0),
|
||||
"provider_store_new"},
|
||||
|
@ -79,6 +83,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = {
|
|||
"odd number of digits"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_ALREADY_EXISTS),
|
||||
"provider already exists"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR),
|
||||
"provider section error"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -399,6 +399,8 @@ 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
|
||||
CRYPTO_F_PROVIDER_ACTIVATE:134:provider_activate
|
||||
CRYPTO_F_PROVIDER_CONF_INIT:137:provider_conf_init
|
||||
CRYPTO_F_PROVIDER_CONF_LOAD:138:provider_conf_load
|
||||
CRYPTO_F_PROVIDER_NEW:135:provider_new
|
||||
CRYPTO_F_PROVIDER_STORE_NEW:136:provider_store_new
|
||||
CRYPTO_F_SK_RESERVE:129:sk_reserve
|
||||
|
@ -2162,6 +2164,7 @@ CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
|
|||
CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit
|
||||
CRYPTO_R_ODD_NUMBER_OF_DIGITS:103:odd number of digits
|
||||
CRYPTO_R_PROVIDER_ALREADY_EXISTS:104:provider already exists
|
||||
CRYPTO_R_PROVIDER_SECTION_ERROR:105:provider section error
|
||||
CT_R_BASE64_DECODE_ERROR:108:base64 decode error
|
||||
CT_R_INVALID_LOG_ID_LENGTH:100:invalid log id length
|
||||
CT_R_LOG_CONF_INVALID:109:log conf invalid
|
||||
|
|
179
crypto/provider_conf.c
Normal file
179
crypto/provider_conf.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/trace.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/safestack.h>
|
||||
#include "internal/provider.h"
|
||||
|
||||
/* PROVIDER config module */
|
||||
|
||||
DEFINE_STACK_OF(OSSL_PROVIDER)
|
||||
static STACK_OF(OSSL_PROVIDER) *activated_providers = NULL;
|
||||
|
||||
static const char *skip_dot(const char *name)
|
||||
{
|
||||
const char *p = strchr(name, '.');
|
||||
|
||||
if (p != NULL)
|
||||
return p + 1;
|
||||
return name;
|
||||
}
|
||||
|
||||
static int provider_conf_params(OSSL_PROVIDER *prov,
|
||||
const char *name, const char *value,
|
||||
const CONF *cnf)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *sect;
|
||||
int ok = 1;
|
||||
|
||||
OSSL_TRACE2(PROVIDER_CONF, "PROVIDER conf: %s = %s\n", name, value);
|
||||
|
||||
sect = NCONF_get_section(cnf, value);
|
||||
if (sect != NULL) {
|
||||
int i;
|
||||
char buffer[512];
|
||||
size_t buffer_len = 0;
|
||||
|
||||
if (name != NULL) {
|
||||
OPENSSL_strlcpy(buffer, name, sizeof(buffer));
|
||||
OPENSSL_strlcat(buffer, ".", sizeof(buffer));
|
||||
buffer_len = strlen(buffer);
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
|
||||
CONF_VALUE *sectconf = sk_CONF_VALUE_value(sect, i);
|
||||
|
||||
if (buffer_len + strlen(sectconf->name) >= sizeof(buffer))
|
||||
return 0;
|
||||
buffer[buffer_len] = '\0';
|
||||
OPENSSL_strlcat(buffer, sectconf->name, sizeof(buffer));
|
||||
if (!provider_conf_params(prov, buffer, sectconf->value, cnf))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ok = ossl_provider_add_parameter(prov, name, value);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int provider_conf_load(OPENSSL_CTX *libctx, const char *name,
|
||||
const char *value, const CONF *cnf)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(CONF_VALUE) *ecmds;
|
||||
int soft = 0;
|
||||
OSSL_PROVIDER *prov = NULL;
|
||||
const char *path = NULL;
|
||||
long activate = 0;
|
||||
int ok = 0;
|
||||
|
||||
name = skip_dot(name);
|
||||
OSSL_TRACE1(PROVIDER_CONF, "Configuring provider %s\n", name);
|
||||
/* Value is a section containing PROVIDER commands */
|
||||
ecmds = NCONF_get_section(cnf, value);
|
||||
|
||||
if (!ecmds) {
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_CONF_LOAD, CRYPTO_R_PROVIDER_SECTION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the needed data first */
|
||||
for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
|
||||
CONF_VALUE *ecmd = sk_CONF_VALUE_value(ecmds, i);
|
||||
const char *confname = skip_dot(ecmd->name);
|
||||
const char *confvalue = ecmd->value;
|
||||
|
||||
OSSL_TRACE2(PROVIDER_CONF, "PROVIDER conf: %s = %s\n",
|
||||
confname, confvalue);
|
||||
|
||||
/* First handle some special pseudo confs */
|
||||
|
||||
/* Override provider name to use */
|
||||
if (strcmp(confname, "identity") == 0)
|
||||
name = confvalue;
|
||||
else if (strcmp(confname, "soft_load") == 0)
|
||||
soft = 1;
|
||||
/* Load a dynamic PROVIDER */
|
||||
else if (strcmp(confname, "module") == 0)
|
||||
path = confvalue;
|
||||
else if (strcmp(confname, "activate") == 0)
|
||||
activate = 1;
|
||||
}
|
||||
|
||||
prov = ossl_provider_new(libctx, name, NULL);
|
||||
if (prov == NULL) {
|
||||
if (soft)
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (path != NULL)
|
||||
ossl_provider_set_module_path(prov, path);
|
||||
|
||||
ok = provider_conf_params(prov, NULL, value, cnf);
|
||||
|
||||
if (ok && activate) {
|
||||
if (!ossl_provider_activate(prov)) {
|
||||
ok = 0;
|
||||
} else {
|
||||
if (activated_providers == NULL)
|
||||
activated_providers = sk_OSSL_PROVIDER_new_null();
|
||||
sk_OSSL_PROVIDER_push(activated_providers, prov);
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(activate && ok))
|
||||
ossl_provider_free(prov);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int provider_conf_init(CONF_IMODULE *md, const CONF *cnf)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *elist;
|
||||
CONF_VALUE *cval;
|
||||
int i;
|
||||
|
||||
OSSL_TRACE2(PROVIDER_CONF, "Loading provider module: name %s, value %s\n",
|
||||
CONF_imodule_get_name(md), CONF_imodule_get_value(md));
|
||||
/* Value is a section containing PROVIDERs to configure */
|
||||
elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
|
||||
|
||||
if (!elist) {
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_CONF_INIT,
|
||||
CRYPTO_R_PROVIDER_SECTION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
|
||||
cval = sk_CONF_VALUE_value(elist, i);
|
||||
if (!provider_conf_load(NULL, cval->name, cval->value, cnf))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void provider_conf_deinit(CONF_IMODULE *md)
|
||||
{
|
||||
sk_OSSL_PROVIDER_pop_free(activated_providers, ossl_provider_free);
|
||||
activated_providers = NULL;
|
||||
OSSL_TRACE(PROVIDER_CONF, "Cleaned up providers\n");
|
||||
}
|
||||
|
||||
void ossl_provider_add_conf_module(void)
|
||||
{
|
||||
CONF_module_add("providers", provider_conf_init, provider_conf_deinit);
|
||||
}
|
|
@ -66,6 +66,9 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
|
|||
int operation_id,
|
||||
int *no_cache);
|
||||
|
||||
/* Configuration */
|
||||
void ossl_provider_add_conf_module(void);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -52,6 +52,8 @@ int ERR_load_CRYPTO_strings(void);
|
|||
# define CRYPTO_F_PKEY_POLY1305_INIT 124
|
||||
# define CRYPTO_F_PKEY_SIPHASH_INIT 125
|
||||
# define CRYPTO_F_PROVIDER_ACTIVATE 134
|
||||
# define CRYPTO_F_PROVIDER_CONF_INIT 137
|
||||
# define CRYPTO_F_PROVIDER_CONF_LOAD 138
|
||||
# define CRYPTO_F_PROVIDER_NEW 135
|
||||
# define CRYPTO_F_PROVIDER_STORE_NEW 136
|
||||
# define CRYPTO_F_SK_RESERVE 129
|
||||
|
@ -63,5 +65,6 @@ int ERR_load_CRYPTO_strings(void);
|
|||
# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102
|
||||
# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103
|
||||
# define CRYPTO_R_PROVIDER_ALREADY_EXISTS 104
|
||||
# define CRYPTO_R_PROVIDER_SECTION_ERROR 105
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue