diff options
Diffstat (limited to 'crypto/core_algorithm.c')
-rw-r--r-- | crypto/core_algorithm.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/crypto/core_algorithm.c b/crypto/core_algorithm.c index 79625fdea6..5c019f0405 100644 --- a/crypto/core_algorithm.c +++ b/crypto/core_algorithm.c @@ -16,8 +16,11 @@ struct algorithm_data_st { OPENSSL_CTX *libctx; int operation_id; /* May be zero for finding them all */ + int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result); void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, void *data); + int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, + int *result); void *data; }; @@ -36,19 +39,48 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) for (cur_operation = first_operation; cur_operation <= last_operation; cur_operation++) { - const OSSL_ALGORITHM *map = - ossl_provider_query_operation(provider, cur_operation, - &no_store); + const OSSL_ALGORITHM *map = NULL; + int ret; + /* Do we fulfill pre-conditions? */ + if (data->pre == NULL) { + /* If there is no pre-condition function, assume "yes" */ + ret = 1; + } else { + if (!data->pre(provider, cur_operation, data->data, &ret)) + /* Error, bail out! */ + return 0; + } + + /* If pre-condition not fulfilled, go to the next operation */ + if (!ret) + continue; + + map = ossl_provider_query_operation(provider, cur_operation, + &no_store); if (map == NULL) continue; - ok = 1; /* As long as we've found *something* */ while (map->algorithm_names != NULL) { const OSSL_ALGORITHM *thismap = map++; data->fn(provider, thismap, no_store, data->data); } + + /* Do we fulfill post-conditions? */ + if (data->post == NULL) { + /* If there is no post-condition function, assume "yes" */ + ret = 1; + } else { + if (!data->post(provider, cur_operation, no_store, data->data, + &ret)) + /* Error, bail out! */ + return 0; + } + + /* If post-condition fulfilled, set general success */ + if (ret) + ok = 1; } return ok; @@ -56,16 +88,22 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, OSSL_PROVIDER *provider, + int (*pre)(OSSL_PROVIDER *, int operation_id, + void *data, int *result), void (*fn)(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, int no_store, void *data), + int (*post)(OSSL_PROVIDER *, int operation_id, + int no_store, void *data, int *result), void *data) { - struct algorithm_data_st cbdata; + struct algorithm_data_st cbdata = { 0, }; cbdata.libctx = libctx; cbdata.operation_id = operation_id; + cbdata.pre = pre; cbdata.fn = fn; + cbdata.post = post; cbdata.data = data; if (provider == NULL) |