]>
Commit | Line | Data |
---|---|---|
a883c02f | 1 | /* |
8020d79b | 2 | * Copyright 2019-2021 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 { | |
b4250010 | 17 | OSSL_LIB_CTX *libctx; |
a883c02f | 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 | } |
b0001d0c | 68 | ossl_provider_unquery_operation(provider, cur_operation, map); |
5a29b628 RL |
69 | |
70 | /* Do we fulfill post-conditions? */ | |
71 | if (data->post == NULL) { | |
72 | /* If there is no post-condition function, assume "yes" */ | |
73 | ret = 1; | |
74 | } else { | |
75 | if (!data->post(provider, cur_operation, no_store, data->data, | |
76 | &ret)) | |
77 | /* Error, bail out! */ | |
78 | return 0; | |
79 | } | |
80 | ||
1010e4ac TS |
81 | /* If post-condition not fulfilled, set general failure */ |
82 | if (!ret) | |
83 | ok = 0; | |
a883c02f RL |
84 | } |
85 | ||
86 | return ok; | |
87 | } | |
88 | ||
b4250010 | 89 | void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, |
a883c02f | 90 | OSSL_PROVIDER *provider, |
5a29b628 RL |
91 | int (*pre)(OSSL_PROVIDER *, int operation_id, |
92 | void *data, int *result), | |
a883c02f RL |
93 | void (*fn)(OSSL_PROVIDER *provider, |
94 | const OSSL_ALGORITHM *algo, | |
95 | int no_store, void *data), | |
5a29b628 RL |
96 | int (*post)(OSSL_PROVIDER *, int operation_id, |
97 | int no_store, void *data, int *result), | |
a883c02f RL |
98 | void *data) |
99 | { | |
5a29b628 | 100 | struct algorithm_data_st cbdata = { 0, }; |
a883c02f RL |
101 | |
102 | cbdata.libctx = libctx; | |
103 | cbdata.operation_id = operation_id; | |
5a29b628 | 104 | cbdata.pre = pre; |
a883c02f | 105 | cbdata.fn = fn; |
5a29b628 | 106 | cbdata.post = post; |
a883c02f RL |
107 | cbdata.data = data; |
108 | ||
109 | if (provider == NULL) | |
8f089576 | 110 | ossl_provider_doall_activated(libctx, algorithm_do_this, &cbdata); |
a883c02f RL |
111 | else |
112 | algorithm_do_this(provider, &cbdata); | |
113 | } | |
6c9bc258 TM |
114 | |
115 | char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM *algo) | |
116 | { | |
117 | const char *first_name_end = NULL; | |
118 | size_t first_name_len = 0; | |
119 | char *ret; | |
120 | ||
121 | if (algo->algorithm_names == NULL) | |
122 | return NULL; | |
123 | ||
124 | first_name_end = strchr(algo->algorithm_names, ':'); | |
125 | if (first_name_end == NULL) | |
126 | first_name_len = strlen(algo->algorithm_names); | |
127 | else | |
128 | first_name_len = first_name_end - algo->algorithm_names; | |
129 | ||
130 | ret = OPENSSL_strndup(algo->algorithm_names, first_name_len); | |
131 | if (ret == NULL) | |
132 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); | |
133 | return ret; | |
134 | } |