Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/engine/eng_table.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||||||||
2 | * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. | - | ||||||||||||
3 | * | - | ||||||||||||
4 | * Licensed under the OpenSSL license (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 "internal/cryptlib.h" | - | ||||||||||||
11 | #include <openssl/evp.h> | - | ||||||||||||
12 | #include <openssl/lhash.h> | - | ||||||||||||
13 | #include "eng_int.h" | - | ||||||||||||
14 | - | |||||||||||||
15 | /* The type of the items in the table */ | - | ||||||||||||
16 | struct st_engine_pile { | - | ||||||||||||
17 | /* The 'nid' of this algorithm/mode */ | - | ||||||||||||
18 | int nid; | - | ||||||||||||
19 | /* ENGINEs that implement this algorithm/mode. */ | - | ||||||||||||
20 | STACK_OF(ENGINE) *sk; | - | ||||||||||||
21 | /* The default ENGINE to perform this algorithm/mode. */ | - | ||||||||||||
22 | ENGINE *funct; | - | ||||||||||||
23 | /* | - | ||||||||||||
24 | * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise | - | ||||||||||||
25 | */ | - | ||||||||||||
26 | int uptodate; | - | ||||||||||||
27 | }; | - | ||||||||||||
28 | - | |||||||||||||
29 | /* The type exposed in eng_int.h */ | - | ||||||||||||
30 | struct st_engine_table { | - | ||||||||||||
31 | LHASH_OF(ENGINE_PILE) piles; | - | ||||||||||||
32 | }; /* ENGINE_TABLE */ | - | ||||||||||||
33 | - | |||||||||||||
34 | typedef struct st_engine_pile_doall { | - | ||||||||||||
35 | engine_table_doall_cb *cb; | - | ||||||||||||
36 | void *arg; | - | ||||||||||||
37 | } ENGINE_PILE_DOALL; | - | ||||||||||||
38 | - | |||||||||||||
39 | /* Global flags (ENGINE_TABLE_FLAG_***). */ | - | ||||||||||||
40 | static unsigned int table_flags = 0; | - | ||||||||||||
41 | - | |||||||||||||
42 | /* API function manipulating 'table_flags' */ | - | ||||||||||||
43 | unsigned int ENGINE_get_table_flags(void) | - | ||||||||||||
44 | { | - | ||||||||||||
45 | return table_flags; never executed: return table_flags; | 0 | ||||||||||||
46 | } | - | ||||||||||||
47 | - | |||||||||||||
48 | void ENGINE_set_table_flags(unsigned int flags) | - | ||||||||||||
49 | { | - | ||||||||||||
50 | table_flags = flags; | - | ||||||||||||
51 | } never executed: end of block | 0 | ||||||||||||
52 | - | |||||||||||||
53 | /* Internal functions for the "piles" hash table */ | - | ||||||||||||
54 | static unsigned long engine_pile_hash(const ENGINE_PILE *c) | - | ||||||||||||
55 | { | - | ||||||||||||
56 | return c->nid; executed 20857 times by 1 test: return c->nid; Executed by:
| 20857 | ||||||||||||
57 | } | - | ||||||||||||
58 | - | |||||||||||||
59 | static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) | - | ||||||||||||
60 | { | - | ||||||||||||
61 | return a->nid - b->nid; executed 14801 times by 1 test: return a->nid - b->nid; Executed by:
| 14801 | ||||||||||||
62 | } | - | ||||||||||||
63 | - | |||||||||||||
64 | static int int_table_check(ENGINE_TABLE **t, int create) | - | ||||||||||||
65 | { | - | ||||||||||||
66 | LHASH_OF(ENGINE_PILE) *lh; | - | ||||||||||||
67 | - | |||||||||||||
68 | if (*t)
| 1101-12049 | ||||||||||||
69 | return 1; executed 12049 times by 1 test: return 1; Executed by:
| 12049 | ||||||||||||
70 | if (!create)
| 0-1101 | ||||||||||||
71 | return 0; never executed: return 0; | 0 | ||||||||||||
72 | if ((lh = lh_ENGINE_PILE_new(engine_pile_hash, engine_pile_cmp)) == NULL)
| 0-1101 | ||||||||||||
73 | return 0; never executed: return 0; | 0 | ||||||||||||
74 | *t = (ENGINE_TABLE *)lh; | - | ||||||||||||
75 | return 1; executed 1101 times by 1 test: return 1; Executed by:
| 1101 | ||||||||||||
76 | } | - | ||||||||||||
77 | - | |||||||||||||
78 | /* | - | ||||||||||||
79 | * Privately exposed (via eng_int.h) functions for adding and/or removing | - | ||||||||||||
80 | * ENGINEs from the implementation table | - | ||||||||||||
81 | */ | - | ||||||||||||
82 | int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, | - | ||||||||||||
83 | ENGINE *e, const int *nids, int num_nids, | - | ||||||||||||
84 | int setdefault) | - | ||||||||||||
85 | { | - | ||||||||||||
86 | int ret = 0, added = 0; | - | ||||||||||||
87 | ENGINE_PILE tmplate, *fnd; | - | ||||||||||||
88 | CRYPTO_THREAD_write_lock(global_engine_lock); | - | ||||||||||||
89 | if (!(*table))
| 0-1101 | ||||||||||||
90 | added = 1; executed 1101 times by 1 test: added = 1; Executed by:
| 1101 | ||||||||||||
91 | if (!int_table_check(table, 1))
| 0-1101 | ||||||||||||
92 | goto end; never executed: goto end; | 0 | ||||||||||||
93 | if (added)
| 0-1101 | ||||||||||||
94 | /* The cleanup callback needs to be added */ | - | ||||||||||||
95 | engine_cleanup_add_first(cleanup); executed 1101 times by 1 test: engine_cleanup_add_first(cleanup); Executed by:
| 1101 | ||||||||||||
96 | while (num_nids--) {
| 1101-2936 | ||||||||||||
97 | tmplate.nid = *nids; | - | ||||||||||||
98 | fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); | - | ||||||||||||
99 | if (!fnd) {
| 0-2936 | ||||||||||||
100 | fnd = OPENSSL_malloc(sizeof(*fnd)); | - | ||||||||||||
101 | if (fnd == NULL)
| 0-2936 | ||||||||||||
102 | goto end; never executed: goto end; | 0 | ||||||||||||
103 | fnd->uptodate = 1; | - | ||||||||||||
104 | fnd->nid = *nids; | - | ||||||||||||
105 | fnd->sk = sk_ENGINE_new_null(); | - | ||||||||||||
106 | if (!fnd->sk) {
| 0-2936 | ||||||||||||
107 | OPENSSL_free(fnd); | - | ||||||||||||
108 | goto end; never executed: goto end; | 0 | ||||||||||||
109 | } | - | ||||||||||||
110 | fnd->funct = NULL; | - | ||||||||||||
111 | (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); | - | ||||||||||||
112 | if (lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate) != fnd) {
| 0-2936 | ||||||||||||
113 | sk_ENGINE_free(fnd->sk); | - | ||||||||||||
114 | OPENSSL_free(fnd); | - | ||||||||||||
115 | goto end; never executed: goto end; | 0 | ||||||||||||
116 | } | - | ||||||||||||
117 | } executed 2936 times by 1 test: end of block Executed by:
| 2936 | ||||||||||||
118 | /* A registration shouldn't add duplicate entries */ | - | ||||||||||||
119 | (void)sk_ENGINE_delete_ptr(fnd->sk, e); | - | ||||||||||||
120 | /* | - | ||||||||||||
121 | * if 'setdefault', this ENGINE goes to the head of the list | - | ||||||||||||
122 | */ | - | ||||||||||||
123 | if (!sk_ENGINE_push(fnd->sk, e))
| 0-2936 | ||||||||||||
124 | goto end; never executed: goto end; | 0 | ||||||||||||
125 | /* "touch" this ENGINE_PILE */ | - | ||||||||||||
126 | fnd->uptodate = 0; | - | ||||||||||||
127 | if (setdefault) {
| 0-2936 | ||||||||||||
128 | if (!engine_unlocked_init(e)) {
| 0-2936 | ||||||||||||
129 | ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, | - | ||||||||||||
130 | ENGINE_R_INIT_FAILED); | - | ||||||||||||
131 | goto end; never executed: goto end; | 0 | ||||||||||||
132 | } | - | ||||||||||||
133 | if (fnd->funct)
| 0-2936 | ||||||||||||
134 | engine_unlocked_finish(fnd->funct, 0); never executed: engine_unlocked_finish(fnd->funct, 0); | 0 | ||||||||||||
135 | fnd->funct = e; | - | ||||||||||||
136 | fnd->uptodate = 1; | - | ||||||||||||
137 | } executed 2936 times by 1 test: end of block Executed by:
| 2936 | ||||||||||||
138 | nids++; | - | ||||||||||||
139 | } executed 2936 times by 1 test: end of block Executed by:
| 2936 | ||||||||||||
140 | ret = 1; | - | ||||||||||||
141 | end: code before this statement executed 1101 times by 1 test: end: Executed by:
| 1101 | ||||||||||||
142 | CRYPTO_THREAD_unlock(global_engine_lock); | - | ||||||||||||
143 | return ret; executed 1101 times by 1 test: return ret; Executed by:
| 1101 | ||||||||||||
144 | } | - | ||||||||||||
145 | - | |||||||||||||
146 | static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) | - | ||||||||||||
147 | { | - | ||||||||||||
148 | int n; | - | ||||||||||||
149 | /* Iterate the 'c->sk' stack removing any occurrence of 'e' */ | - | ||||||||||||
150 | while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) {
| 0 | ||||||||||||
151 | (void)sk_ENGINE_delete(pile->sk, n); | - | ||||||||||||
152 | pile->uptodate = 0; | - | ||||||||||||
153 | } never executed: end of block | 0 | ||||||||||||
154 | if (pile->funct == e) {
| 0 | ||||||||||||
155 | engine_unlocked_finish(e, 0); | - | ||||||||||||
156 | pile->funct = NULL; | - | ||||||||||||
157 | } never executed: end of block | 0 | ||||||||||||
158 | } never executed: end of block | 0 | ||||||||||||
159 | - | |||||||||||||
160 | IMPLEMENT_LHASH_DOALL_ARG(ENGINE_PILE, ENGINE); never executed: end of block | 0 | ||||||||||||
161 | - | |||||||||||||
162 | void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) | - | ||||||||||||
163 | { | - | ||||||||||||
164 | CRYPTO_THREAD_write_lock(global_engine_lock); | - | ||||||||||||
165 | if (int_table_check(table, 0))
| 0 | ||||||||||||
166 | lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e); never executed: lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e); | 0 | ||||||||||||
167 | CRYPTO_THREAD_unlock(global_engine_lock); | - | ||||||||||||
168 | } never executed: end of block | 0 | ||||||||||||
169 | - | |||||||||||||
170 | static void int_cleanup_cb_doall(ENGINE_PILE *p) | - | ||||||||||||
171 | { | - | ||||||||||||
172 | if (!p)
| 0-2936 | ||||||||||||
173 | return; never executed: return; | 0 | ||||||||||||
174 | sk_ENGINE_free(p->sk); | - | ||||||||||||
175 | if (p->funct)
| 0-2936 | ||||||||||||
176 | engine_unlocked_finish(p->funct, 0); executed 2936 times by 1 test: engine_unlocked_finish(p->funct, 0); Executed by:
| 2936 | ||||||||||||
177 | OPENSSL_free(p); | - | ||||||||||||
178 | } executed 2936 times by 1 test: end of block Executed by:
| 2936 | ||||||||||||
179 | - | |||||||||||||
180 | void engine_table_cleanup(ENGINE_TABLE **table) | - | ||||||||||||
181 | { | - | ||||||||||||
182 | CRYPTO_THREAD_write_lock(global_engine_lock); | - | ||||||||||||
183 | if (*table) {
| 0-1101 | ||||||||||||
184 | lh_ENGINE_PILE_doall(&(*table)->piles, int_cleanup_cb_doall); | - | ||||||||||||
185 | lh_ENGINE_PILE_free(&(*table)->piles); | - | ||||||||||||
186 | *table = NULL; | - | ||||||||||||
187 | } executed 1101 times by 1 test: end of block Executed by:
| 1101 | ||||||||||||
188 | CRYPTO_THREAD_unlock(global_engine_lock); | - | ||||||||||||
189 | } executed 1101 times by 1 test: end of block Executed by:
| 1101 | ||||||||||||
190 | - | |||||||||||||
191 | /* return a functional reference for a given 'nid' */ | - | ||||||||||||
192 | #ifndef ENGINE_TABLE_DEBUG | - | ||||||||||||
193 | ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) | - | ||||||||||||
194 | #else | - | ||||||||||||
195 | ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, | - | ||||||||||||
196 | int l) | - | ||||||||||||
197 | #endif | - | ||||||||||||
198 | { | - | ||||||||||||
199 | ENGINE *ret = NULL; | - | ||||||||||||
200 | ENGINE_PILE tmplate, *fnd = NULL; | - | ||||||||||||
201 | int initres, loop = 0; | - | ||||||||||||
202 | - | |||||||||||||
203 | if (!(*table)) {
| 12049-4142606 | ||||||||||||
204 | #ifdef ENGINE_TABLE_DEBUG | - | ||||||||||||
205 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " | - | ||||||||||||
206 | "registered!\n", f, l, nid); | - | ||||||||||||
207 | #endif | - | ||||||||||||
208 | return NULL; executed 4141226 times by 3 tests: return ((void *)0) ; Executed by:
| 4141226 | ||||||||||||
209 | } | - | ||||||||||||
210 | ERR_set_mark(); | - | ||||||||||||
211 | CRYPTO_THREAD_write_lock(global_engine_lock); | - | ||||||||||||
212 | /* | - | ||||||||||||
213 | * Check again inside the lock otherwise we could race against cleanup | - | ||||||||||||
214 | * operations. But don't worry about a fprintf(stderr). | - | ||||||||||||
215 | */ | - | ||||||||||||
216 | if (!int_table_check(table, 0))
| 0-12049 | ||||||||||||
217 | goto end; never executed: goto end; | 0 | ||||||||||||
218 | tmplate.nid = nid; | - | ||||||||||||
219 | fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); | - | ||||||||||||
220 | if (!fnd)
| 184-11865 | ||||||||||||
221 | goto end; executed 184 times by 1 test: goto end; Executed by:
| 184 | ||||||||||||
222 | if (fnd->funct && engine_unlocked_init(fnd->funct)) {
| 0-11865 | ||||||||||||
223 | #ifdef ENGINE_TABLE_DEBUG | - | ||||||||||||
224 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " | - | ||||||||||||
225 | "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); | - | ||||||||||||
226 | #endif | - | ||||||||||||
227 | ret = fnd->funct; | - | ||||||||||||
228 | goto end; executed 11865 times by 1 test: goto end; Executed by:
| 11865 | ||||||||||||
229 | } | - | ||||||||||||
230 | if (fnd->uptodate) {
| 0 | ||||||||||||
231 | ret = fnd->funct; | - | ||||||||||||
232 | goto end; never executed: goto end; | 0 | ||||||||||||
233 | } | - | ||||||||||||
234 | trynext: code before this statement never executed: trynext: | 0 | ||||||||||||
235 | ret = sk_ENGINE_value(fnd->sk, loop++); | - | ||||||||||||
236 | if (!ret) {
| 0 | ||||||||||||
237 | #ifdef ENGINE_TABLE_DEBUG | - | ||||||||||||
238 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " | - | ||||||||||||
239 | "registered implementations would initialise\n", f, l, nid); | - | ||||||||||||
240 | #endif | - | ||||||||||||
241 | goto end; never executed: goto end; | 0 | ||||||||||||
242 | } | - | ||||||||||||
243 | /* Try to initialise the ENGINE? */ | - | ||||||||||||
244 | if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
| 0 | ||||||||||||
245 | initres = engine_unlocked_init(ret); never executed: initres = engine_unlocked_init(ret); | 0 | ||||||||||||
246 | else | - | ||||||||||||
247 | initres = 0; never executed: initres = 0; | 0 | ||||||||||||
248 | if (initres) {
| 0 | ||||||||||||
249 | /* Update 'funct' */ | - | ||||||||||||
250 | if ((fnd->funct != ret) && engine_unlocked_init(ret)) {
| 0 | ||||||||||||
251 | /* If there was a previous default we release it. */ | - | ||||||||||||
252 | if (fnd->funct)
| 0 | ||||||||||||
253 | engine_unlocked_finish(fnd->funct, 0); never executed: engine_unlocked_finish(fnd->funct, 0); | 0 | ||||||||||||
254 | fnd->funct = ret; | - | ||||||||||||
255 | #ifdef ENGINE_TABLE_DEBUG | - | ||||||||||||
256 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " | - | ||||||||||||
257 | "setting default to '%s'\n", f, l, nid, ret->id); | - | ||||||||||||
258 | #endif | - | ||||||||||||
259 | } never executed: end of block | 0 | ||||||||||||
260 | #ifdef ENGINE_TABLE_DEBUG | - | ||||||||||||
261 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " | - | ||||||||||||
262 | "newly initialised '%s'\n", f, l, nid, ret->id); | - | ||||||||||||
263 | #endif | - | ||||||||||||
264 | goto end; never executed: goto end; | 0 | ||||||||||||
265 | } | - | ||||||||||||
266 | goto trynext; never executed: goto trynext; | 0 | ||||||||||||
267 | end: | - | ||||||||||||
268 | /* | - | ||||||||||||
269 | * If it failed, it is unlikely to succeed again until some future | - | ||||||||||||
270 | * registrations have taken place. In all cases, we cache. | - | ||||||||||||
271 | */ | - | ||||||||||||
272 | if (fnd)
| 184-11865 | ||||||||||||
273 | fnd->uptodate = 1; executed 11865 times by 1 test: fnd->uptodate = 1; Executed by:
| 11865 | ||||||||||||
274 | #ifdef ENGINE_TABLE_DEBUG | - | ||||||||||||
275 | if (ret) | - | ||||||||||||
276 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " | - | ||||||||||||
277 | "ENGINE '%s'\n", f, l, nid, ret->id); | - | ||||||||||||
278 | else | - | ||||||||||||
279 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " | - | ||||||||||||
280 | "'no matching ENGINE'\n", f, l, nid); | - | ||||||||||||
281 | #endif | - | ||||||||||||
282 | CRYPTO_THREAD_unlock(global_engine_lock); | - | ||||||||||||
283 | /* | - | ||||||||||||
284 | * Whatever happened, any failed init()s are not failures in this | - | ||||||||||||
285 | * context, so clear our error state. | - | ||||||||||||
286 | */ | - | ||||||||||||
287 | ERR_pop_to_mark(); | - | ||||||||||||
288 | return ret; executed 12049 times by 1 test: return ret; Executed by:
| 12049 | ||||||||||||
289 | } | - | ||||||||||||
290 | - | |||||||||||||
291 | /* Table enumeration */ | - | ||||||||||||
292 | - | |||||||||||||
293 | static void int_dall(const ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) | - | ||||||||||||
294 | { | - | ||||||||||||
295 | dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); | - | ||||||||||||
296 | } never executed: end of block | 0 | ||||||||||||
297 | - | |||||||||||||
298 | IMPLEMENT_LHASH_DOALL_ARG_CONST(ENGINE_PILE, ENGINE_PILE_DOALL); never executed: end of block | 0 | ||||||||||||
299 | - | |||||||||||||
300 | void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, | - | ||||||||||||
301 | void *arg) | - | ||||||||||||
302 | { | - | ||||||||||||
303 | ENGINE_PILE_DOALL dall; | - | ||||||||||||
304 | dall.cb = cb; | - | ||||||||||||
305 | dall.arg = arg; | - | ||||||||||||
306 | if (table)
| 0-9796 | ||||||||||||
307 | lh_ENGINE_PILE_doall_ENGINE_PILE_DOALL(&table->piles, int_dall, &dall); never executed: lh_ENGINE_PILE_doall_ENGINE_PILE_DOALL(&table->piles, int_dall, &dall); | 0 | ||||||||||||
308 | } executed 9796 times by 1 test: end of block Executed by:
| 9796 | ||||||||||||
Source code | Switch to Preprocessed file |