From 3d96a51c09296cb5c283efb5681105a7691e6fbc Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sat, 13 Jul 2019 06:53:44 +0200 Subject: [PATCH] Add internal function evp_generic_do_all() This function is used to traverse all algorithm implementations for a given operation type, and execute the given function for each of them. For each algorithm implementation, a method is created and passed to the given function, and then freed after that function's return. If the caller wishes to keep the method for longer, they must call the appropriate up_ref function on the method, and they must also make sure to free the passed methods at some point. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/9356) --- crypto/evp/evp_fetch.c | 38 ++++++++++++++++++++++++++++++++++++++ crypto/evp/evp_locl.h | 7 +++++++ 2 files changed, 45 insertions(+) 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 */ -- 2.25.1