and though bugs are the bane of my existence, rest assured the wretched thing will get the best of care here

...
 
Commits (3)
......@@ -107,7 +107,7 @@ void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id,
cbdata.data = data;
if (provider == NULL)
ossl_provider_forall_loaded(libctx, algorithm_do_this, &cbdata);
ossl_provider_doall_activated(libctx, algorithm_do_this, &cbdata);
else
algorithm_do_this(provider, &cbdata);
}
......@@ -134,5 +134,5 @@ int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx,
void *cbdata),
void *cbdata)
{
return ossl_provider_forall_loaded(ctx, cb, cbdata);
return ossl_provider_doall_activated(ctx, cb, cbdata);
}
......@@ -726,36 +726,6 @@ void *ossl_provider_ctx(const OSSL_PROVIDER *prov)
return prov->provctx;
}
static int provider_forall_loaded(struct provider_store_st *store,
int *found_activated,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata)
{
int i;
int ret = 1;
int num_provs;
num_provs = sk_OSSL_PROVIDER_num(store->providers);
if (found_activated != NULL)
*found_activated = 0;
for (i = 0; i < num_provs; i++) {
OSSL_PROVIDER *prov =
sk_OSSL_PROVIDER_value(store->providers, i);
if (prov->flag_activated) {
if (found_activated != NULL)
*found_activated = 1;
if (!(ret = cb(prov, cbdata)))
break;
}
}
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
......@@ -809,13 +779,14 @@ static void provider_activate_fallbacks(struct provider_store_st *store)
CRYPTO_THREAD_unlock(store->lock);
}
int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata)
int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata)
{
int ret = 1;
int ret = 0, i, j;
struct provider_store_st *store = get_provider_store(ctx);
STACK_OF(OSSL_PROVIDER) *provs = NULL;
#ifndef FIPS_MODULE
/*
......@@ -825,18 +796,46 @@ int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
if (store != NULL) {
provider_activate_fallbacks(store);
CRYPTO_THREAD_read_lock(store->lock);
/*
* Now, we sweep through all providers
*/
ret = provider_forall_loaded(store, NULL, cb, cbdata);
if (store == NULL)
return 1;
provider_activate_fallbacks(store);
/*
* Under lock, grab a copy of the provider list and up_ref each
* provider so that they don't disappear underneath us.
*/
CRYPTO_THREAD_read_lock(store->lock);
provs = sk_OSSL_PROVIDER_dup(store->providers);
if (provs == NULL) {
CRYPTO_THREAD_unlock(store->lock);
return 0;
}
j = sk_OSSL_PROVIDER_num(provs);
for (i = 0; i < j; i++)
if (!ossl_provider_up_ref(sk_OSSL_PROVIDER_value(provs, i)))
goto err_unlock;
CRYPTO_THREAD_unlock(store->lock);
/*
* Now, we sweep through all providers not under lock
*/
for (j = 0; j < i; j++) {
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, j);
if (prov->flag_activated && !cb(prov, cbdata))
goto finish;
}
ret = 1;
goto finish;
err_unlock:
CRYPTO_THREAD_unlock(store->lock);
finish:
/* The pop_free call doesn't do what we want on an error condition */
for (j = 0; j < i; j++)
ossl_provider_free(sk_OSSL_PROVIDER_value(provs, j));
sk_OSSL_PROVIDER_free(provs);
return ret;
}
......
......@@ -8,7 +8,7 @@ ossl_provider_set_fallback, ossl_provider_set_module_path,
ossl_provider_add_parameter,
ossl_provider_activate, ossl_provider_deactivate, ossl_provider_available,
ossl_provider_ctx,
ossl_provider_forall_loaded,
ossl_provider_doall_activated,
ossl_provider_name, ossl_provider_dso,
ossl_provider_module_name, ossl_provider_module_path,
ossl_provider_libctx,
......@@ -50,10 +50,10 @@ ossl_provider_get_capabilities
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
/* Iterate over all loaded providers */
int ossl_provider_forall_loaded(OSSL_LIB_CTX *,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata);
int ossl_provider_doall_activated(OSSL_LIB_CTX *,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata);
/* Getters for other library functions */
const char *ossl_provider_name(OSSL_PROVIDER *prov);
......@@ -197,10 +197,10 @@ ossl_provider_ctx() returns a context created by the provider.
Outside of the provider, it's completely opaque, but it needs to be
passed back to some of the provider functions.
ossl_provider_forall_loaded() iterates over all the currently
ossl_provider_doall_activated() iterates over all the currently
"activated" providers, and calls I<cb> for each of them.
If no providers have been "activated" yet, it tries to activate all
available fallback providers and tries another iteration.
available fallback providers before iterating over them.
ossl_provider_name() returns the name that was given with
ossl_provider_new().
......@@ -287,6 +287,10 @@ it has been incremented.
ossl_provider_free() doesn't return any value.
ossl_provider_doall_activated() returns 1 if the callback was called for all
activated providers. A return value of 0 means that the callback was not
called for any activated providers.
ossl_provider_set_module_path(), ossl_provider_set_fallback(),
ossl_provider_activate(), ossl_provider_activate_leave_fallbacks() and
ossl_provider_deactivate() return 1 on success, or 0 on error.
......
......@@ -58,10 +58,10 @@ int ossl_provider_available(OSSL_PROVIDER *prov);
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
/* Iterate over all loaded providers */
int ossl_provider_forall_loaded(OSSL_LIB_CTX *,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata);
int ossl_provider_doall_activated(OSSL_LIB_CTX *,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
void *cbdata);
/* Getters for other library functions */
const char *ossl_provider_name(const OSSL_PROVIDER *prov);
......