mirror of
https://github.com/openssl/openssl.git
synced 2025-02-23 14:42:15 +08:00
Support CLI and API setting of provider configuration parameters
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/26427)
This commit is contained in:
parent
42aced5c9f
commit
38a0926528
@ -295,6 +295,7 @@
|
||||
# define OPT_PROV_ENUM \
|
||||
OPT_PROV__FIRST=1600, \
|
||||
OPT_PROV_PROVIDER, OPT_PROV_PROVIDER_PATH, OPT_PROV_PROPQUERY, \
|
||||
OPT_PROV_PARAM, \
|
||||
OPT_PROV__LAST
|
||||
|
||||
# define OPT_CONFIG_OPTION \
|
||||
@ -304,12 +305,14 @@
|
||||
OPT_SECTION("Provider"), \
|
||||
{ "provider-path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \
|
||||
{ "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" }, \
|
||||
{ "provparam", OPT_PROV_PARAM, 's', "Set a provider key-value parameter" }, \
|
||||
{ "propquery", OPT_PROV_PROPQUERY, 's', "Property query used when fetching algorithms" }
|
||||
|
||||
# define OPT_PROV_CASES \
|
||||
OPT_PROV__FIRST: case OPT_PROV__LAST: break; \
|
||||
case OPT_PROV_PROVIDER: \
|
||||
case OPT_PROV_PROVIDER_PATH: \
|
||||
case OPT_PROV_PARAM: \
|
||||
case OPT_PROV_PROPQUERY
|
||||
|
||||
/*
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "apps.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/provider.h>
|
||||
@ -65,6 +66,78 @@ static int opt_provider_path(const char *path)
|
||||
return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path);
|
||||
}
|
||||
|
||||
struct prov_param_st {
|
||||
char *name;
|
||||
char *key;
|
||||
char *val;
|
||||
int found;
|
||||
};
|
||||
|
||||
static int set_prov_param(OSSL_PROVIDER *prov, void *vp)
|
||||
{
|
||||
struct prov_param_st *p = (struct prov_param_st *)vp;
|
||||
|
||||
if (p->name != NULL && strcmp(OSSL_PROVIDER_get0_name(prov), p->name) != 0)
|
||||
return 1;
|
||||
p->found = 1;
|
||||
return OSSL_PROVIDER_add_conf_parameter(prov, p->key, p->val);
|
||||
}
|
||||
|
||||
static int opt_provider_param(const char *arg)
|
||||
{
|
||||
struct prov_param_st p;
|
||||
char *copy, *tmp;
|
||||
int ret = 0;
|
||||
|
||||
if ((copy = OPENSSL_strdup(arg)) == NULL
|
||||
|| (p.val = strchr(copy, '=')) == NULL) {
|
||||
opt_printf_stderr("%s: malformed '-provparam' option value: '%s'\n",
|
||||
opt_getprog(), arg);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Drop whitespace on both sides of the '=' sign */
|
||||
*(tmp = p.val++) = '\0';
|
||||
while (tmp > copy && isspace(_UC(*--tmp)))
|
||||
*tmp = '\0';
|
||||
while (isspace(_UC(*p.val)))
|
||||
++p.val;
|
||||
|
||||
/*
|
||||
* Split the key on ':', to get the optional provider, empty or missing
|
||||
* means all.
|
||||
*/
|
||||
if ((p.key = strchr(copy, ':')) != NULL) {
|
||||
*p.key++ = '\0';
|
||||
p.name = *copy != '\0' ? copy : NULL;
|
||||
} else {
|
||||
p.name = NULL;
|
||||
p.key = copy;
|
||||
}
|
||||
|
||||
/* The key must not be empty */
|
||||
if (*p.key == '\0') {
|
||||
opt_printf_stderr("%s: malformed '-provparam' option value: '%s'\n",
|
||||
opt_getprog(), arg);
|
||||
goto end;
|
||||
}
|
||||
|
||||
p.found = 0;
|
||||
ret = OSSL_PROVIDER_do_all(app_get0_libctx(), set_prov_param, (void *)&p);
|
||||
if (ret == 0) {
|
||||
opt_printf_stderr("%s: Error setting provider '%s' parameter '%s'\n",
|
||||
opt_getprog(), p.name, p.key);
|
||||
} else if (p.found == 0) {
|
||||
opt_printf_stderr("%s: No provider named '%s' is loaded\n",
|
||||
opt_getprog(), p.name);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
OPENSSL_free(copy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int opt_provider(int opt)
|
||||
{
|
||||
const int given = provider_option_given;
|
||||
@ -78,6 +151,8 @@ int opt_provider(int opt)
|
||||
return app_provider_load(app_get0_libctx(), opt_arg());
|
||||
case OPT_PROV_PROVIDER_PATH:
|
||||
return opt_provider_path(opt_arg());
|
||||
case OPT_PROV_PARAM:
|
||||
return opt_provider_param(opt_arg());
|
||||
case OPT_PROV_PROPQUERY:
|
||||
return app_set_propq(opt_arg());
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ static int provider_conf_params_internal(OSSL_PROVIDER *prov,
|
||||
} else {
|
||||
OSSL_TRACE2(CONF, "Provider params: %s = %s\n", name, value);
|
||||
if (prov != NULL)
|
||||
ok = ossl_provider_add_parameter(prov, name, value);
|
||||
ok = OSSL_PROVIDER_add_conf_parameter(prov, name, value);
|
||||
else
|
||||
ok = ossl_provider_info_add_parameter(provinfo, name, value);
|
||||
}
|
||||
|
@ -800,12 +800,30 @@ static int infopair_add(STACK_OF(INFOPAIR) **infopairsk, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_provider_add_parameter(OSSL_PROVIDER *prov,
|
||||
const char *name, const char *value)
|
||||
int OSSL_PROVIDER_add_conf_parameter(OSSL_PROVIDER *prov,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
return infopair_add(&prov->parameters, name, value);
|
||||
}
|
||||
|
||||
int OSSL_PROVIDER_get_conf_parameters(OSSL_PROVIDER *prov, OSSL_PARAM params[])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prov->parameters == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) {
|
||||
INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i);
|
||||
OSSL_PARAM *p = OSSL_PARAM_locate(params, pair->name);
|
||||
|
||||
if (p != NULL
|
||||
&& !OSSL_PARAM_set_utf8_ptr(p, pair->value))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_provider_info_add_parameter(OSSL_PROVIDER_INFO *provinfo,
|
||||
const char *name,
|
||||
const char *value)
|
||||
@ -2203,7 +2221,6 @@ static const OSSL_PARAM *core_gettable_params(const OSSL_CORE_HANDLE *handle)
|
||||
|
||||
static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[])
|
||||
{
|
||||
int i;
|
||||
OSSL_PARAM *p;
|
||||
/*
|
||||
* We created this object originally and we know it is actually an
|
||||
@ -2222,16 +2239,7 @@ static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[])
|
||||
OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov));
|
||||
#endif
|
||||
|
||||
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;
|
||||
return OSSL_PROVIDER_get_conf_parameters(prov, params);
|
||||
}
|
||||
|
||||
static OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle)
|
||||
|
@ -3,9 +3,8 @@
|
||||
=head1 NAME
|
||||
|
||||
ossl_provider_find, ossl_provider_new, ossl_provider_up_ref,
|
||||
ossl_provider_free,
|
||||
ossl_provider_set_module_path,
|
||||
ossl_provider_add_parameter, ossl_provider_set_child, ossl_provider_get_parent,
|
||||
ossl_provider_free, ossl_provider_set_module_path,
|
||||
ossl_provider_set_child, ossl_provider_get_parent,
|
||||
ossl_provider_up_ref_parent, ossl_provider_free_parent,
|
||||
ossl_provider_default_props_update, ossl_provider_get0_dispatch,
|
||||
ossl_provider_init_as_child, ossl_provider_deinit_child,
|
||||
@ -36,8 +35,6 @@ ossl_provider_get_capabilities
|
||||
|
||||
/* Setters */
|
||||
int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *path);
|
||||
int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name,
|
||||
const char *value);
|
||||
|
||||
/* Child Providers */
|
||||
int ossl_provider_set_child(OSSL_PROVIDER *prov,
|
||||
@ -167,13 +164,6 @@ on this in L</NOTES>).
|
||||
ossl_provider_libctx() returns the library context the given
|
||||
provider I<prov> is registered in.
|
||||
|
||||
ossl_provider_add_parameter() adds a global parameter for the provider
|
||||
to retrieve as it sees fit.
|
||||
The parameters are a combination of I<name> and I<value>, and the
|
||||
provider will use the name to find the value it wants.
|
||||
Only text parameters can be given, and it's up to the provider to
|
||||
interpret them.
|
||||
|
||||
ossl_provider_set_child() marks this provider as a child of a provider in the
|
||||
parent library context. I<handle> is the B<OSSL_CORE_HANDLE> object passed to
|
||||
the provider's B<OSSL_provider_init> function.
|
||||
|
@ -681,6 +681,21 @@ See L<provider(7)> for a more detailed description.
|
||||
Specifies the search path that is to be used for looking for providers.
|
||||
Equivalently, the B<OPENSSL_MODULES> environment variable may be set.
|
||||
|
||||
=item B<-provparam> I<[name:]key=value>
|
||||
|
||||
Set configuration parameter I<key> to value I<val> in provider I<name>
|
||||
(optional), if I<name> is not specified, the setting will be applied to all
|
||||
loaded providers.
|
||||
This option can be specified multiple times, to set multiple parameters.
|
||||
Options that specify nondefault providers to load should precede this option
|
||||
if the setting is intended to apply to the to be loaded providers.
|
||||
Parameters that only affect provider initialisation must, for now, be set in
|
||||
the configuration file, only parameters that are also queried as needed later
|
||||
have any affect when set via this interface.
|
||||
Only UTF8-string-valued parameters are supported.
|
||||
See the documentation of the specific provider and associated algorithms for
|
||||
any supported parameters.
|
||||
|
||||
=item B<-propquery> I<propq>
|
||||
|
||||
Specifies the I<property query clause> to be used when fetching algorithms
|
||||
|
@ -11,6 +11,7 @@ OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params,
|
||||
OSSL_PROVIDER_query_operation, OSSL_PROVIDER_unquery_operation,
|
||||
OSSL_PROVIDER_get0_provider_ctx, OSSL_PROVIDER_get0_dispatch,
|
||||
OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_get0_name, OSSL_PROVIDER_get_capabilities,
|
||||
OSSL_PROVIDER_add_conf_parameter, OSSL_PROVIDER_get_conf_parameters,
|
||||
OSSL_PROVIDER_self_test
|
||||
- provider routines
|
||||
|
||||
@ -59,6 +60,10 @@ OSSL_PROVIDER_self_test
|
||||
const char *capability,
|
||||
OSSL_CALLBACK *cb,
|
||||
void *arg);
|
||||
int OSSL_PROVIDER_add_conf_parameter(OSSL_PROVIDER *prov, const char *name,
|
||||
const char *value);
|
||||
int OSSL_PROVIDER_get_conf_parameters(OSSL_PROVIDER *prov,
|
||||
OSSL_PARAM params[]);
|
||||
int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -137,6 +142,25 @@ The caller must prepare the L<OSSL_PARAM(3)> array before calling this
|
||||
function, and the variables acting as buffers for this parameter array
|
||||
should be filled with data when it returns successfully.
|
||||
|
||||
OSSL_PROVIDER_add_conf_parameter() sets the provider configuration parameter
|
||||
I<name> to B<value>.
|
||||
Provider configuration parameters are managed by the OpenSSL core and normally
|
||||
set in the configuration file, but can also be set early in the main program
|
||||
before a provider is in use by multiple threads.
|
||||
Parameters that only affect provider initialisation must, for now, be set in
|
||||
the configuration file, only parameters that are also queried later have any
|
||||
affect when set via this interface.
|
||||
Only text parameters can be given, and it's up to the provider to
|
||||
interpret them.
|
||||
|
||||
OSSL_PROVIDER_get_conf_parameters() retrieves global configuration parameters
|
||||
associated with B<prov>.
|
||||
These configuration parameters are stored for each provider by the OpenSSL core,
|
||||
not the provider itself, parameters managed by the provider are queried via
|
||||
B<OSSL_PROVIDER_get_params()> described above.
|
||||
The parameters are returned by reference, not as copies, and so the elements of
|
||||
the I<param> array must have B<OSSL_PARAM_UTF8_PTR> as their B<data_type>.
|
||||
|
||||
OSSL_PROVIDER_self_test() is used to run a provider's self tests on demand.
|
||||
If the self tests fail then the provider will fail to provide any further
|
||||
services and algorithms. L<OSSL_SELF_TEST_set_callback(3)> may be called
|
||||
@ -177,7 +201,9 @@ L<provider-base(7)/CAPABILTIIES>.
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_PROVIDER_set_default_search_path(), OSSL_PROVIDER_add(),
|
||||
OSSL_PROVIDER_unload(), OSSL_PROVIDER_get_params() and
|
||||
OSSL_PROVIDER_unload(), OSSL_PROVIDER_get_params(),
|
||||
OSSL_PROVIDER_add_conf_parameter(), OSSL_PROVIDER_get_conf_parameters()
|
||||
and
|
||||
OSSL_PROVIDER_get_capabilities() return 1 on success, or 0 on error.
|
||||
|
||||
OSSL_PROVIDER_get0_default_search_path() returns a pointer to a path on success,
|
||||
|
@ -94,12 +94,15 @@ $OpenSSL::safe::opt_r_item = ""
|
||||
$OpenSSL::safe::opt_provider_synopsis = ""
|
||||
. "[B<-provider> I<name>]\n"
|
||||
. "[B<-provider-path> I<path>]\n"
|
||||
. "[B<-provparam> I<[name:]key=value>]\n"
|
||||
. "[B<-propquery> I<propq>]";
|
||||
$OpenSSL::safe::opt_provider_item = ""
|
||||
. "=item B<-provider> I<name>\n"
|
||||
. "\n"
|
||||
. "=item B<-provider-path> I<path>\n"
|
||||
. "\n"
|
||||
. "=item B<-provparam> I<[name:]key=value>\n"
|
||||
. "\n"
|
||||
. "=item B<-propquery> I<propq>\n"
|
||||
. "\n"
|
||||
. "See L<openssl(1)/Provider Options>, L<provider(7)>, and L<property(7)>.";
|
||||
|
@ -38,8 +38,6 @@ void ossl_provider_free(OSSL_PROVIDER *prov);
|
||||
|
||||
/* Setters */
|
||||
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);
|
||||
|
||||
int ossl_provider_is_child(const OSSL_PROVIDER *prov);
|
||||
int ossl_provider_set_child(OSSL_PROVIDER *prov, const OSSL_CORE_HANDLE *handle);
|
||||
|
@ -44,6 +44,25 @@ int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov,
|
||||
OSSL_CALLBACK *cb,
|
||||
void *arg);
|
||||
|
||||
/*-
|
||||
* Provider configuration parameters are normally set in the configuration file,
|
||||
* but can also be set early in the main program before a provider is in use by
|
||||
* multiple threads.
|
||||
*
|
||||
* Only UTF8-string values are supported.
|
||||
*/
|
||||
int OSSL_PROVIDER_add_conf_parameter(OSSL_PROVIDER *prov, const char *name,
|
||||
const char *value);
|
||||
/*
|
||||
* Retrieves any of the requested configuration parameters for the given
|
||||
* provider that were set in the configuration file or via the above
|
||||
* OSSL_PROVIDER_add_parameter() function.
|
||||
*
|
||||
* The |params| array elements MUST have type OSSL_PARAM_UTF8_PTR, values are
|
||||
* returned by reference, not as copies.
|
||||
*/
|
||||
int OSSL_PROVIDER_get_conf_parameters(OSSL_PROVIDER *prov, OSSL_PARAM params[]);
|
||||
|
||||
const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov,
|
||||
int operation_id,
|
||||
int *no_cache);
|
||||
|
@ -5876,3 +5876,5 @@ i2d_OSSL_ALLOWED_ATTRIBUTES_SYNTAX ? 3_5_0 EXIST::FUNCTION:
|
||||
OSSL_ALLOWED_ATTRIBUTES_SYNTAX_free ? 3_5_0 EXIST::FUNCTION:
|
||||
OSSL_ALLOWED_ATTRIBUTES_SYNTAX_new ? 3_5_0 EXIST::FUNCTION:
|
||||
OSSL_ALLOWED_ATTRIBUTES_SYNTAX_it ? 3_5_0 EXIST::FUNCTION:
|
||||
OSSL_PROVIDER_add_conf_parameter ? 3_5_0 EXIST::FUNCTION:
|
||||
OSSL_PROVIDER_get_conf_parameters ? 3_5_0 EXIST::FUNCTION:
|
||||
|
Loading…
Reference in New Issue
Block a user