mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
Add functions to see if a provider is available for use.
Public function OSSL_PROVIDER_available() takes a library context and a provider name, and returns 1 if it's available for use, i.e. if it's possible to fetch implementations from it, otherwise 0. Internal function ossl_provider_activated() returns 1 if the given OSSL_PROVIDER is activated, otherwise 0. To make this possible, the activation of fallbacks got refactored out to a separate function, which ended up simplifying the code. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9398)
This commit is contained in:
parent
166c0b98fd
commit
36f5ec55e6
5
CHANGES
5
CHANGES
@ -9,6 +9,11 @@
|
|||||||
|
|
||||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Introduced a new function, OSSL_PROVIDER_available(), which can be used
|
||||||
|
to check if a named provider is loaded and available. When called, it
|
||||||
|
will also activate all fallback providers if such are still present.
|
||||||
|
[Richard Levitte]
|
||||||
|
|
||||||
*) Enforce a minimum DH modulus size of 512 bits.
|
*) Enforce a minimum DH modulus size of 512 bits.
|
||||||
[Bernd Edlinger]
|
[Bernd Edlinger]
|
||||||
|
|
||||||
|
@ -35,6 +35,18 @@ int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name)
|
||||||
|
{
|
||||||
|
OSSL_PROVIDER *prov = NULL;
|
||||||
|
int available = 0;
|
||||||
|
|
||||||
|
/* Find it or create it */
|
||||||
|
prov = ossl_provider_find(libctx, name);
|
||||||
|
available = ossl_provider_available(prov);
|
||||||
|
ossl_provider_free(prov);
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
const OSSL_PARAM *OSSL_PROVIDER_get_param_types(const OSSL_PROVIDER *prov)
|
const OSSL_PARAM *OSSL_PROVIDER_get_param_types(const OSSL_PROVIDER *prov)
|
||||||
{
|
{
|
||||||
return ossl_provider_get_param_types(prov);
|
return ossl_provider_get_param_types(prov);
|
||||||
|
@ -572,67 +572,79 @@ static int provider_forall_loaded(struct provider_store_st *store,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function only does something once when store->use_fallbacks == 1,
|
||||||
|
* and then sets store->use_fallbacks = 0, so the second call and so on is
|
||||||
|
* effectively a no-op.
|
||||||
|
*/
|
||||||
|
static void provider_activate_fallbacks(struct provider_store_st *store)
|
||||||
|
{
|
||||||
|
if (store->use_fallbacks) {
|
||||||
|
int num_provs = sk_OSSL_PROVIDER_num(store->providers);
|
||||||
|
int activated_fallback_count = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_provs; i++) {
|
||||||
|
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that we don't care if the activation succeeds or not.
|
||||||
|
* If it doesn't succeed, then any attempt to use any of the
|
||||||
|
* fallback providers will fail anyway.
|
||||||
|
*/
|
||||||
|
if (prov->flag_fallback) {
|
||||||
|
activated_fallback_count++;
|
||||||
|
provider_activate(prov);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We assume that all fallbacks have been added to the store before
|
||||||
|
* any fallback is activated.
|
||||||
|
* TODO: We may have to reconsider this, IF we find ourselves adding
|
||||||
|
* fallbacks after any previous fallback has been activated.
|
||||||
|
*/
|
||||||
|
if (activated_fallback_count > 0)
|
||||||
|
store->use_fallbacks = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ossl_provider_forall_loaded(OPENSSL_CTX *ctx,
|
int ossl_provider_forall_loaded(OPENSSL_CTX *ctx,
|
||||||
int (*cb)(OSSL_PROVIDER *provider,
|
int (*cb)(OSSL_PROVIDER *provider,
|
||||||
void *cbdata),
|
void *cbdata),
|
||||||
void *cbdata)
|
void *cbdata)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
int i;
|
|
||||||
struct provider_store_st *store = get_provider_store(ctx);
|
struct provider_store_st *store = get_provider_store(ctx);
|
||||||
|
|
||||||
if (store != NULL) {
|
if (store != NULL) {
|
||||||
int found_activated = 0;
|
|
||||||
|
|
||||||
CRYPTO_THREAD_read_lock(store->lock);
|
CRYPTO_THREAD_read_lock(store->lock);
|
||||||
ret = provider_forall_loaded(store, &found_activated, cb, cbdata);
|
|
||||||
|
provider_activate_fallbacks(store);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's nothing activated ever in this store, try to activate
|
* Now, we sweep through all providers
|
||||||
* all fallbacks.
|
|
||||||
*/
|
*/
|
||||||
if (!found_activated && store->use_fallbacks) {
|
ret = provider_forall_loaded(store, NULL, cb, cbdata);
|
||||||
int num_provs = sk_OSSL_PROVIDER_num(store->providers);
|
|
||||||
int activated_fallback_count = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < num_provs; i++) {
|
|
||||||
OSSL_PROVIDER *prov =
|
|
||||||
sk_OSSL_PROVIDER_value(store->providers, i);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that we don't care if the activation succeeds or
|
|
||||||
* not. If it doesn't succeed, then the next loop will
|
|
||||||
* fail anyway.
|
|
||||||
*/
|
|
||||||
if (prov->flag_fallback) {
|
|
||||||
activated_fallback_count++;
|
|
||||||
provider_activate(prov);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activated_fallback_count > 0) {
|
|
||||||
/*
|
|
||||||
* We assume that all fallbacks have been added to the store
|
|
||||||
* before any fallback is activated.
|
|
||||||
* TODO: We may have to reconsider this, IF we find ourselves
|
|
||||||
* adding fallbacks after any previous fallback has been
|
|
||||||
* activated.
|
|
||||||
*/
|
|
||||||
store->use_fallbacks = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now that we've activated available fallbacks, try a
|
|
||||||
* second sweep
|
|
||||||
*/
|
|
||||||
ret = provider_forall_loaded(store, NULL, cb, cbdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CRYPTO_THREAD_unlock(store->lock);
|
CRYPTO_THREAD_unlock(store->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ossl_provider_available(OSSL_PROVIDER *prov)
|
||||||
|
{
|
||||||
|
if (prov != NULL) {
|
||||||
|
CRYPTO_THREAD_read_lock(prov->store->lock);
|
||||||
|
provider_activate_fallbacks(prov->store);
|
||||||
|
CRYPTO_THREAD_unlock(prov->store->lock);
|
||||||
|
|
||||||
|
return prov->flag_initialized;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setters of Provider Object data */
|
/* Setters of Provider Object data */
|
||||||
int ossl_provider_set_fallback(OSSL_PROVIDER *prov)
|
int ossl_provider_set_fallback(OSSL_PROVIDER *prov)
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@ ossl_provider_find, ossl_provider_new, ossl_provider_up_ref,
|
|||||||
ossl_provider_free,
|
ossl_provider_free,
|
||||||
ossl_provider_set_fallback, ossl_provider_set_module_path,
|
ossl_provider_set_fallback, ossl_provider_set_module_path,
|
||||||
ossl_provider_add_parameter,
|
ossl_provider_add_parameter,
|
||||||
ossl_provider_activate,
|
ossl_provider_activate, ossl_provider_available,
|
||||||
ossl_provider_ctx,
|
ossl_provider_ctx,
|
||||||
ossl_provider_forall_loaded,
|
ossl_provider_forall_loaded,
|
||||||
ossl_provider_name, ossl_provider_dso,
|
ossl_provider_name, ossl_provider_dso,
|
||||||
@ -33,6 +33,8 @@ ossl_provider_get_params, ossl_provider_query_operation
|
|||||||
|
|
||||||
/* Load and initialize the Provider */
|
/* Load and initialize the Provider */
|
||||||
int ossl_provider_activate(OSSL_PROVIDER *prov);
|
int ossl_provider_activate(OSSL_PROVIDER *prov);
|
||||||
|
/* Check if provider is available */
|
||||||
|
int ossl_provider_available(OSSL_PROVIDER *prov);
|
||||||
|
|
||||||
/* Return pointer to the provider's context */
|
/* Return pointer to the provider's context */
|
||||||
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
|
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
|
||||||
@ -148,6 +150,10 @@ be located in that module, and called.
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
ossl_provider_available() activates all fallbacks if no provider is
|
||||||
|
activated yet, then checks if given provider object I<prov> is
|
||||||
|
activated.
|
||||||
|
|
||||||
ossl_provider_ctx() returns a context created by the provider.
|
ossl_provider_ctx() returns a context created by the provider.
|
||||||
Outside of the provider, it's completely opaque, but it needs to be
|
Outside of the provider, it's completely opaque, but it needs to be
|
||||||
passed back to some of the provider functions.
|
passed back to some of the provider functions.
|
||||||
@ -228,6 +234,9 @@ ossl_provider_free() doesn't return any value.
|
|||||||
ossl_provider_set_module_path(), ossl_provider_set_fallback() and
|
ossl_provider_set_module_path(), ossl_provider_set_fallback() and
|
||||||
ossl_provider_activate() return 1 on success, or 0 on error.
|
ossl_provider_activate() return 1 on success, or 0 on error.
|
||||||
|
|
||||||
|
ossl_provider_available() return 1 if the provider is available,
|
||||||
|
otherwise 0.
|
||||||
|
|
||||||
ossl_provider_name(), ossl_provider_dso(),
|
ossl_provider_name(), ossl_provider_dso(),
|
||||||
ossl_provider_module_name(), and ossl_provider_module_path() return a
|
ossl_provider_module_name(), and ossl_provider_module_path() return a
|
||||||
pointer to their respective data if it's available, otherwise NULL
|
pointer to their respective data if it's available, otherwise NULL
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_unload,
|
OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_unload,
|
||||||
|
OSSL_PROVIDER_available,
|
||||||
OSSL_PROVIDER_get_param_types, OSSL_PROVIDER_get_params,
|
OSSL_PROVIDER_get_param_types, OSSL_PROVIDER_get_params,
|
||||||
OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name - provider routines
|
OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name - provider routines
|
||||||
|
|
||||||
@ -12,13 +13,14 @@ OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name - provider routines
|
|||||||
|
|
||||||
typedef struct ossl_provider_st OSSL_PROVIDER;
|
typedef struct ossl_provider_st OSSL_PROVIDER;
|
||||||
|
|
||||||
OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name);
|
OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name);
|
||||||
int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov);
|
int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov);
|
||||||
|
int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name);
|
||||||
|
|
||||||
const OSSL_PARAM *OSSL_PROVIDER_get_param_types(OSSL_PROVIDER *prov);
|
const OSSL_PARAM *OSSL_PROVIDER_get_param_types(OSSL_PROVIDER *prov);
|
||||||
int OSSL_PROVIDER_get_params(OSSL_PROVIDER *prov, OSSL_PARAM params[]);
|
int OSSL_PROVIDER_get_params(OSSL_PROVIDER *prov, OSSL_PARAM params[]);
|
||||||
|
|
||||||
int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *, const char *name,
|
int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name,
|
||||||
ossl_provider_init_fn *init_fn);
|
ossl_provider_init_fn *init_fn);
|
||||||
|
|
||||||
const char *OSSL_PROVIDER_name(const OSSL_PROVIDER *prov);
|
const char *OSSL_PROVIDER_name(const OSSL_PROVIDER *prov);
|
||||||
@ -32,6 +34,9 @@ A provider can be built in to the application or the OpenSSL
|
|||||||
libraries, or can be a loadable module.
|
libraries, or can be a loadable module.
|
||||||
The functions described here handle both forms.
|
The functions described here handle both forms.
|
||||||
|
|
||||||
|
Some of these functions operate within a library context, please see
|
||||||
|
L<OPENSSL_CTX(3)> for further details.
|
||||||
|
|
||||||
=head2 Functions
|
=head2 Functions
|
||||||
|
|
||||||
OSSL_PROVIDER_add_builtin() is used to add a built in provider to
|
OSSL_PROVIDER_add_builtin() is used to add a built in provider to
|
||||||
@ -49,6 +54,9 @@ OSSL_PROVIDER_unload() unloads the given provider.
|
|||||||
For a provider added with OSSL_PROVIDER_add_builtin(), this simply
|
For a provider added with OSSL_PROVIDER_add_builtin(), this simply
|
||||||
runs its teardown function.
|
runs its teardown function.
|
||||||
|
|
||||||
|
OSSL_PROVIDER_available() checks if a named provider is available
|
||||||
|
for use.
|
||||||
|
|
||||||
OSSL_PROVIDER_get_param_types() is used to get a provider parameter
|
OSSL_PROVIDER_get_param_types() is used to get a provider parameter
|
||||||
descriptor set as a constant B<OSSL_PARAM> array.
|
descriptor set as a constant B<OSSL_PARAM> array.
|
||||||
See L<OSSL_PARAM(3)> for more information.
|
See L<OSSL_PARAM(3)> for more information.
|
||||||
@ -69,6 +77,9 @@ success, or B<NULL> on error.
|
|||||||
|
|
||||||
OSSL_PROVIDER_unload() returns 1 on success, or 0 on error.
|
OSSL_PROVIDER_unload() returns 1 on success, or 0 on error.
|
||||||
|
|
||||||
|
OSSL_PROVIDER_available() returns 1 if the named provider is available,
|
||||||
|
otherwise 0.
|
||||||
|
|
||||||
OSSL_PROVIDER_get_param_types() returns a pointer to an array
|
OSSL_PROVIDER_get_param_types() returns a pointer to an array
|
||||||
of constant B<OSSL_PARAM>, or NULL if none is provided.
|
of constant B<OSSL_PARAM>, or NULL if none is provided.
|
||||||
|
|
||||||
@ -95,7 +106,7 @@ its build number.
|
|||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
L<openssl-core.h(7)>, L<provider(7)>
|
L<openssl-core.h(7)>, L<OPENSSL_CTX(3)>, L<provider(7)>
|
||||||
|
|
||||||
=head1 HISTORY
|
=head1 HISTORY
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name,
|
|||||||
* Inactivation is done by freeing the Provider
|
* Inactivation is done by freeing the Provider
|
||||||
*/
|
*/
|
||||||
int ossl_provider_activate(OSSL_PROVIDER *prov);
|
int ossl_provider_activate(OSSL_PROVIDER *prov);
|
||||||
|
/* Check if the provider is available */
|
||||||
|
int ossl_provider_available(OSSL_PROVIDER *prov);
|
||||||
|
|
||||||
/* Return pointer to the provider's context */
|
/* Return pointer to the provider's context */
|
||||||
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
|
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
# if defined(OPENSSL_SYS_VMS)
|
# if defined(OPENSSL_SYS_VMS)
|
||||||
|
|
||||||
|
/* ossl_provider_available vs OSSL_PROVIDER_available */
|
||||||
|
# undef ossl_provider_available
|
||||||
|
# define ossl_provider_available ossl_int_prov_available
|
||||||
/* ossl_provider_get_param_types vs OSSL_PROVIDER_get_param_types */
|
/* ossl_provider_get_param_types vs OSSL_PROVIDER_get_param_types */
|
||||||
# undef ossl_provider_get_param_types
|
# undef ossl_provider_get_param_types
|
||||||
# define ossl_provider_get_param_types ossl_int_prov_get_param_types
|
# define ossl_provider_get_param_types ossl_int_prov_get_param_types
|
||||||
|
@ -19,6 +19,7 @@ extern "C" {
|
|||||||
/* Load and unload a provider */
|
/* Load and unload a provider */
|
||||||
OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name);
|
OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name);
|
||||||
int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov);
|
int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov);
|
||||||
|
int OSSL_PROVIDER_available(OPENSSL_CTX *, const char *name);
|
||||||
|
|
||||||
const OSSL_PARAM *OSSL_PROVIDER_get_param_types(const OSSL_PROVIDER *prov);
|
const OSSL_PARAM *OSSL_PROVIDER_get_param_types(const OSSL_PROVIDER *prov);
|
||||||
int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]);
|
int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]);
|
||||||
|
@ -4699,3 +4699,4 @@ OSSL_PROVIDER_name 4804 3_0_0 EXIST::FUNCTION:
|
|||||||
EVP_CIPHER_do_all_ex 4805 3_0_0 EXIST::FUNCTION:
|
EVP_CIPHER_do_all_ex 4805 3_0_0 EXIST::FUNCTION:
|
||||||
EVP_MD_do_all_ex 4806 3_0_0 EXIST::FUNCTION:
|
EVP_MD_do_all_ex 4806 3_0_0 EXIST::FUNCTION:
|
||||||
EVP_KEYEXCH_provider 4807 3_0_0 EXIST::FUNCTION:
|
EVP_KEYEXCH_provider 4807 3_0_0 EXIST::FUNCTION:
|
||||||
|
OSSL_PROVIDER_available 4808 3_0_0 EXIST::FUNCTION:
|
||||||
|
Loading…
Reference in New Issue
Block a user