diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 82f6e5d970..5c100dd1eb 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -236,3 +236,41 @@ int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) EVPerr(EVP_F_EVP_SET_DEFAULT_PROPERTIES, ERR_R_INTERNAL_ERROR); return 0; } + +struct do_all_data_st { + void (*user_fn)(void *method, void *arg); + void *user_arg; + void *(*new_method)(const char *name, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov); + void (*free_method)(void *); +}; + +static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, + int no_store, void *vdata) +{ + struct do_all_data_st *data = vdata; + void *method = data->new_method(algo->algorithm_name, + algo->implementation, provider); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + data->free_method(method); + } +} + +void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg, + void *(*new_method)(const char *name, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov), + void (*free_method)(void *)) +{ + struct do_all_data_st data; + + data.new_method = new_method; + data.free_method = free_method; + data.user_fn = user_fn; + data.user_arg = user_arg; + ossl_algorithm_do_all(libctx, operation_id, NULL, do_one, &data); +} diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index d557e9c633..ce46163140 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -139,6 +139,13 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)); +void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg, + void *(*new_method)(const char *name, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov), + void (*free_method)(void *)); /* Helper functions to avoid duplicating code */