diff options
Diffstat (limited to 'src/lib/libcrypto/engine/eng_table.c')
-rw-r--r-- | src/lib/libcrypto/engine/eng_table.c | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c index 8879a267d1..4fde948185 100644 --- a/src/lib/libcrypto/engine/eng_table.c +++ b/src/lib/libcrypto/engine/eng_table.c | |||
@@ -70,12 +70,22 @@ typedef struct st_engine_pile | |||
70 | int uptodate; | 70 | int uptodate; |
71 | } ENGINE_PILE; | 71 | } ENGINE_PILE; |
72 | 72 | ||
73 | DECLARE_LHASH_OF(ENGINE_PILE); | ||
74 | |||
73 | /* The type exposed in eng_int.h */ | 75 | /* The type exposed in eng_int.h */ |
74 | struct st_engine_table | 76 | struct st_engine_table |
75 | { | 77 | { |
76 | LHASH piles; | 78 | LHASH_OF(ENGINE_PILE) piles; |
77 | }; /* ENGINE_TABLE */ | 79 | }; /* ENGINE_TABLE */ |
78 | 80 | ||
81 | |||
82 | typedef struct st_engine_pile_doall | ||
83 | { | ||
84 | engine_table_doall_cb *cb; | ||
85 | void *arg; | ||
86 | } ENGINE_PILE_DOALL; | ||
87 | |||
88 | |||
79 | /* Global flags (ENGINE_TABLE_FLAG_***). */ | 89 | /* Global flags (ENGINE_TABLE_FLAG_***). */ |
80 | static unsigned int table_flags = 0; | 90 | static unsigned int table_flags = 0; |
81 | 91 | ||
@@ -84,6 +94,7 @@ unsigned int ENGINE_get_table_flags(void) | |||
84 | { | 94 | { |
85 | return table_flags; | 95 | return table_flags; |
86 | } | 96 | } |
97 | |||
87 | void ENGINE_set_table_flags(unsigned int flags) | 98 | void ENGINE_set_table_flags(unsigned int flags) |
88 | { | 99 | { |
89 | table_flags = flags; | 100 | table_flags = flags; |
@@ -94,19 +105,21 @@ static unsigned long engine_pile_hash(const ENGINE_PILE *c) | |||
94 | { | 105 | { |
95 | return c->nid; | 106 | return c->nid; |
96 | } | 107 | } |
108 | |||
97 | static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) | 109 | static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) |
98 | { | 110 | { |
99 | return a->nid - b->nid; | 111 | return a->nid - b->nid; |
100 | } | 112 | } |
101 | static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) | 113 | static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE) |
102 | static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) | 114 | static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE) |
115 | |||
103 | static int int_table_check(ENGINE_TABLE **t, int create) | 116 | static int int_table_check(ENGINE_TABLE **t, int create) |
104 | { | 117 | { |
105 | LHASH *lh; | 118 | LHASH_OF(ENGINE_PILE) *lh; |
119 | |||
106 | if(*t) return 1; | 120 | if(*t) return 1; |
107 | if(!create) return 0; | 121 | if(!create) return 0; |
108 | if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), | 122 | if((lh = lh_ENGINE_PILE_new()) == NULL) |
109 | LHASH_COMP_FN(engine_pile_cmp))) == NULL) | ||
110 | return 0; | 123 | return 0; |
111 | *t = (ENGINE_TABLE *)lh; | 124 | *t = (ENGINE_TABLE *)lh; |
112 | return 1; | 125 | return 1; |
@@ -130,7 +143,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, | |||
130 | while(num_nids--) | 143 | while(num_nids--) |
131 | { | 144 | { |
132 | tmplate.nid = *nids; | 145 | tmplate.nid = *nids; |
133 | fnd = lh_retrieve(&(*table)->piles, &tmplate); | 146 | fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); |
134 | if(!fnd) | 147 | if(!fnd) |
135 | { | 148 | { |
136 | fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); | 149 | fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); |
@@ -144,7 +157,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, | |||
144 | goto end; | 157 | goto end; |
145 | } | 158 | } |
146 | fnd->funct = NULL; | 159 | fnd->funct = NULL; |
147 | lh_insert(&(*table)->piles, fnd); | 160 | (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); |
148 | } | 161 | } |
149 | /* A registration shouldn't add duplciate entries */ | 162 | /* A registration shouldn't add duplciate entries */ |
150 | (void)sk_ENGINE_delete_ptr(fnd->sk, e); | 163 | (void)sk_ENGINE_delete_ptr(fnd->sk, e); |
@@ -173,7 +186,7 @@ end: | |||
173 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | 186 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); |
174 | return ret; | 187 | return ret; |
175 | } | 188 | } |
176 | static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) | 189 | static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e) |
177 | { | 190 | { |
178 | int n; | 191 | int n; |
179 | /* Iterate the 'c->sk' stack removing any occurance of 'e' */ | 192 | /* Iterate the 'c->sk' stack removing any occurance of 'e' */ |
@@ -188,31 +201,35 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) | |||
188 | pile->funct = NULL; | 201 | pile->funct = NULL; |
189 | } | 202 | } |
190 | } | 203 | } |
191 | static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) | 204 | static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE) |
205 | |||
192 | void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) | 206 | void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) |
193 | { | 207 | { |
194 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | 208 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); |
195 | if(int_table_check(table, 0)) | 209 | if(int_table_check(table, 0)) |
196 | lh_doall_arg(&(*table)->piles, | 210 | lh_ENGINE_PILE_doall_arg(&(*table)->piles, |
197 | LHASH_DOALL_ARG_FN(int_unregister_cb), e); | 211 | LHASH_DOALL_ARG_FN(int_unregister_cb), |
212 | ENGINE, e); | ||
198 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | 213 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); |
199 | } | 214 | } |
200 | 215 | ||
201 | static void int_cleanup_cb(ENGINE_PILE *p) | 216 | static void int_cleanup_cb_doall(ENGINE_PILE *p) |
202 | { | 217 | { |
203 | sk_ENGINE_free(p->sk); | 218 | sk_ENGINE_free(p->sk); |
204 | if(p->funct) | 219 | if(p->funct) |
205 | engine_unlocked_finish(p->funct, 0); | 220 | engine_unlocked_finish(p->funct, 0); |
206 | OPENSSL_free(p); | 221 | OPENSSL_free(p); |
207 | } | 222 | } |
208 | static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) | 223 | static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE) |
224 | |||
209 | void engine_table_cleanup(ENGINE_TABLE **table) | 225 | void engine_table_cleanup(ENGINE_TABLE **table) |
210 | { | 226 | { |
211 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | 227 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); |
212 | if(*table) | 228 | if(*table) |
213 | { | 229 | { |
214 | lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); | 230 | lh_ENGINE_PILE_doall(&(*table)->piles, |
215 | lh_free(&(*table)->piles); | 231 | LHASH_DOALL_FN(int_cleanup_cb)); |
232 | lh_ENGINE_PILE_free(&(*table)->piles); | ||
216 | *table = NULL; | 233 | *table = NULL; |
217 | } | 234 | } |
218 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | 235 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); |
@@ -237,12 +254,13 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in | |||
237 | #endif | 254 | #endif |
238 | return NULL; | 255 | return NULL; |
239 | } | 256 | } |
257 | ERR_set_mark(); | ||
240 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | 258 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); |
241 | /* Check again inside the lock otherwise we could race against cleanup | 259 | /* Check again inside the lock otherwise we could race against cleanup |
242 | * operations. But don't worry about a fprintf(stderr). */ | 260 | * operations. But don't worry about a fprintf(stderr). */ |
243 | if(!int_table_check(table, 0)) goto end; | 261 | if(!int_table_check(table, 0)) goto end; |
244 | tmplate.nid = nid; | 262 | tmplate.nid = nid; |
245 | fnd = lh_retrieve(&(*table)->piles, &tmplate); | 263 | fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); |
246 | if(!fnd) goto end; | 264 | if(!fnd) goto end; |
247 | if(fnd->funct && engine_unlocked_init(fnd->funct)) | 265 | if(fnd->funct && engine_unlocked_init(fnd->funct)) |
248 | { | 266 | { |
@@ -310,6 +328,24 @@ end: | |||
310 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | 328 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); |
311 | /* Whatever happened, any failed init()s are not failures in this | 329 | /* Whatever happened, any failed init()s are not failures in this |
312 | * context, so clear our error state. */ | 330 | * context, so clear our error state. */ |
313 | ERR_clear_error(); | 331 | ERR_pop_to_mark(); |
314 | return ret; | 332 | return ret; |
315 | } | 333 | } |
334 | |||
335 | /* Table enumeration */ | ||
336 | |||
337 | static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) | ||
338 | { | ||
339 | dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); | ||
340 | } | ||
341 | static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL) | ||
342 | |||
343 | void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, | ||
344 | void *arg) | ||
345 | { | ||
346 | ENGINE_PILE_DOALL dall; | ||
347 | dall.cb = cb; | ||
348 | dall.arg = arg; | ||
349 | lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb), | ||
350 | ENGINE_PILE_DOALL, &dall); | ||
351 | } | ||