]>
Commit | Line | Data |
---|---|---|
a883c02f | 1 | /* |
00c405b3 | 2 | * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. |
a883c02f RL |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <openssl/core.h> | |
23c48d94 | 11 | #include <openssl/core_dispatch.h> |
a883c02f RL |
12 | #include "internal/core.h" |
13 | #include "internal/property.h" | |
14 | #include "internal/provider.h" | |
15 | ||
16 | struct algorithm_data_st { | |
17 | OPENSSL_CTX *libctx; | |
18 | int operation_id; /* May be zero for finding them all */ | |
5a29b628 | 19 | int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result); |
a883c02f RL |
20 | void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, |
21 | void *data); | |
5a29b628 RL |
22 | int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, |
23 | int *result); | |
a883c02f RL |
24 | void *data; |
25 | }; | |
26 | ||
27 | static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) | |
28 | { | |
29 | struct algorithm_data_st *data = cbdata; | |
30 | int no_store = 0; /* Assume caching is ok */ | |
31 | int first_operation = 1; | |
32 | int last_operation = OSSL_OP__HIGHEST; | |
33 | int cur_operation; | |
1010e4ac | 34 | int ok = 1; |
a883c02f RL |
35 | |
36 | if (data->operation_id != 0) | |
37 | first_operation = last_operation = data->operation_id; | |
38 | ||
39 | for (cur_operation = first_operation; | |
40 | cur_operation <= last_operation; | |
41 | cur_operation++) { | |
5a29b628 RL |
42 | const OSSL_ALGORITHM *map = NULL; |
43 | int ret; | |
a883c02f | 44 | |
5a29b628 RL |
45 | /* Do we fulfill pre-conditions? */ |
46 | if (data->pre == NULL) { | |
47 | /* If there is no pre-condition function, assume "yes" */ | |
48 | ret = 1; | |
49 | } else { | |
50 | if (!data->pre(provider, cur_operation, data->data, &ret)) | |
51 | /* Error, bail out! */ | |
52 | return 0; | |
53 | } | |
54 | ||
55 | /* If pre-condition not fulfilled, go to the next operation */ | |
56 | if (!ret) | |
57 | continue; | |
58 | ||
59 | map = ossl_provider_query_operation(provider, cur_operation, | |
60 | &no_store); | |
dd76b90e RL |
61 | if (map != NULL) { |
62 | while (map->algorithm_names != NULL) { | |
63 | const OSSL_ALGORITHM *thismap = map++; | |
a883c02f | 64 | |
dd76b90e RL |
65 | data->fn(provider, thismap, no_store, data->data); |
66 | } | |
a883c02f | 67 | } |
5a29b628 RL |
68 | |
69 | /* Do we fulfill post-conditions? */ | |
70 | if (data->post == NULL) { | |
71 | /* If there is no post-condition function, assume "yes" */ | |
72 | ret = 1; | |
73 | } else { | |
74 | if (!data->post(provider, cur_operation, no_store, data->data, | |
75 | &ret)) | |
76 | /* Error, bail out! */ | |
77 | return 0; | |
78 | } | |
79 | ||
1010e4ac TS |
80 | /* If post-condition not fulfilled, set general failure */ |
81 | if (!ret) | |
82 | ok = 0; | |
a883c02f RL |
83 | } |
84 | ||
85 | return ok; | |
86 | } | |
87 | ||
88 | void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, | |
89 | OSSL_PROVIDER *provider, | |
5a29b628 RL |
90 | int (*pre)(OSSL_PROVIDER *, int operation_id, |
91 | void *data, int *result), | |
a883c02f RL |
92 | void (*fn)(OSSL_PROVIDER *provider, |
93 | const OSSL_ALGORITHM *algo, | |
94 | int no_store, void *data), | |
5a29b628 RL |
95 | int (*post)(OSSL_PROVIDER *, int operation_id, |
96 | int no_store, void *data, int *result), | |
a883c02f RL |
97 | void *data) |
98 | { | |
5a29b628 | 99 | struct algorithm_data_st cbdata = { 0, }; |
a883c02f RL |
100 | |
101 | cbdata.libctx = libctx; | |
102 | cbdata.operation_id = operation_id; | |
5a29b628 | 103 | cbdata.pre = pre; |
a883c02f | 104 | cbdata.fn = fn; |
5a29b628 | 105 | cbdata.post = post; |
a883c02f RL |
106 | cbdata.data = data; |
107 | ||
108 | if (provider == NULL) | |
109 | ossl_provider_forall_loaded(libctx, algorithm_do_this, &cbdata); | |
110 | else | |
111 | algorithm_do_this(provider, &cbdata); | |
112 | } |