summaryrefslogtreecommitdiff
path: root/src/lib/libssl/src/crypto/engine/eng_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/src/crypto/engine/eng_table.c')
-rw-r--r--src/lib/libssl/src/crypto/engine/eng_table.c94
1 files changed, 24 insertions, 70 deletions
diff --git a/src/lib/libssl/src/crypto/engine/eng_table.c b/src/lib/libssl/src/crypto/engine/eng_table.c
index c69a84a8bf..8879a267d1 100644
--- a/src/lib/libssl/src/crypto/engine/eng_table.c
+++ b/src/lib/libssl/src/crypto/engine/eng_table.c
@@ -52,49 +52,31 @@
52 * 52 *
53 */ 53 */
54 54
55#include "cryptlib.h"
55#include <openssl/evp.h> 56#include <openssl/evp.h>
56#include <openssl/engine.h> 57#include <openssl/lhash.h>
57#include "eng_int.h" 58#include "eng_int.h"
58 59
59/* This is the type of item in the 'implementation' table. Each 'nid' hashes to
60 * a (potentially NULL) ENGINE_PILE structure which contains a stack of ENGINE*
61 * pointers. These pointers aren't references, because they're inserted and
62 * removed during ENGINE creation and ENGINE destruction. They point to ENGINEs
63 * that *exist* (ie. have a structural reference count greater than zero) rather
64 * than ENGINEs that are *functional*. Each pointer in those stacks are to
65 * ENGINEs that implements the algorithm corresponding to each 'nid'. */
66
67/* The type of the items in the table */ 60/* The type of the items in the table */
68typedef struct st_engine_pile 61typedef struct st_engine_pile
69 { 62 {
70 /* The 'nid' of the algorithm/mode this ENGINE_PILE structure represents 63 /* The 'nid' of this algorithm/mode */
71 * */
72 int nid; 64 int nid;
73 /* A stack of ENGINE pointers for ENGINEs that support this 65 /* ENGINEs that implement this algorithm/mode. */
74 * algorithm/mode. In the event that 'funct' is NULL, the first entry in
75 * this stack that initialises will be set as 'funct' and assumed as the
76 * default for operations of this type. */
77 STACK_OF(ENGINE) *sk; 66 STACK_OF(ENGINE) *sk;
78 /* The default ENGINE to perform this algorithm/mode. */ 67 /* The default ENGINE to perform this algorithm/mode. */
79 ENGINE *funct; 68 ENGINE *funct;
80 /* This value optimises engine_table_select(). If it is called it sets 69 /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
81 * this value to 1. Any changes to this ENGINE_PILE resets it to zero.
82 * As such, no ENGINE_init() thrashing is done unless ENGINEs
83 * continually register (and/or unregister). */
84 int uptodate; 70 int uptodate;
85 } ENGINE_PILE; 71 } ENGINE_PILE;
86 72
87/* The type of the hash table of ENGINE_PILE structures such that each are 73/* The type exposed in eng_int.h */
88 * unique and keyed by the 'nid' value. */
89struct st_engine_table 74struct st_engine_table
90 { 75 {
91 LHASH piles; 76 LHASH piles;
92 }; /* ENGINE_TABLE */ 77 }; /* ENGINE_TABLE */
93 78
94/* This value stores global options controlling behaviour of (mostly) the 79/* Global flags (ENGINE_TABLE_FLAG_***). */
95 * engine_table_select() function. It's a bitmask of flag values of the form
96 * ENGINE_TABLE_FLAG_*** (as defined in engine.h) and is controlled by the
97 * ENGINE_[get|set]_table_flags() function. */
98static unsigned int table_flags = 0; 80static unsigned int table_flags = 0;
99 81
100/* API function manipulating 'table_flags' */ 82/* API function manipulating 'table_flags' */
@@ -121,10 +103,8 @@ static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *)
121static int int_table_check(ENGINE_TABLE **t, int create) 103static int int_table_check(ENGINE_TABLE **t, int create)
122 { 104 {
123 LHASH *lh; 105 LHASH *lh;
124 if(*t) 106 if(*t) return 1;
125 return 1; 107 if(!create) return 0;
126 if(!create)
127 return 0;
128 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), 108 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
129 LHASH_COMP_FN(engine_pile_cmp))) == NULL) 109 LHASH_COMP_FN(engine_pile_cmp))) == NULL)
130 return 0; 110 return 0;
@@ -154,8 +134,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
154 if(!fnd) 134 if(!fnd)
155 { 135 {
156 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); 136 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
157 if(!fnd) 137 if(!fnd) goto end;
158 goto end;
159 fnd->uptodate = 1; 138 fnd->uptodate = 1;
160 fnd->nid = *nids; 139 fnd->nid = *nids;
161 fnd->sk = sk_ENGINE_new_null(); 140 fnd->sk = sk_ENGINE_new_null();
@@ -164,11 +143,11 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
164 OPENSSL_free(fnd); 143 OPENSSL_free(fnd);
165 goto end; 144 goto end;
166 } 145 }
167 fnd->funct= NULL; 146 fnd->funct = NULL;
168 lh_insert(&(*table)->piles, fnd); 147 lh_insert(&(*table)->piles, fnd);
169 } 148 }
170 /* A registration shouldn't add duplciate entries */ 149 /* A registration shouldn't add duplciate entries */
171 sk_ENGINE_delete_ptr(fnd->sk, e); 150 (void)sk_ENGINE_delete_ptr(fnd->sk, e);
172 /* if 'setdefault', this ENGINE goes to the head of the list */ 151 /* if 'setdefault', this ENGINE goes to the head of the list */
173 if(!sk_ENGINE_push(fnd->sk, e)) 152 if(!sk_ENGINE_push(fnd->sk, e))
174 goto end; 153 goto end;
@@ -185,6 +164,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
185 if(fnd->funct) 164 if(fnd->funct)
186 engine_unlocked_finish(fnd->funct, 0); 165 engine_unlocked_finish(fnd->funct, 0);
187 fnd->funct = e; 166 fnd->funct = e;
167 fnd->uptodate = 1;
188 } 168 }
189 nids++; 169 nids++;
190 } 170 }
@@ -199,8 +179,7 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
199 /* Iterate the 'c->sk' stack removing any occurance of 'e' */ 179 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
200 while((n = sk_ENGINE_find(pile->sk, e)) >= 0) 180 while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
201 { 181 {
202 sk_ENGINE_delete(pile->sk, n); 182 (void)sk_ENGINE_delete(pile->sk, n);
203 /* "touch" this ENGINE_CIPHER */
204 pile->uptodate = 0; 183 pile->uptodate = 0;
205 } 184 }
206 if(pile->funct == e) 185 if(pile->funct == e)
@@ -239,9 +218,7 @@ void engine_table_cleanup(ENGINE_TABLE **table)
239 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 218 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
240 } 219 }
241 220
242/* Exposed API function to get a functional reference from the implementation 221/* return a functional reference for a given 'nid' */
243 * table (ie. try to get a functional reference from the tabled structural
244 * references) for a given cipher 'nid' */
245#ifndef ENGINE_TABLE_DEBUG 222#ifndef ENGINE_TABLE_DEBUG
246ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) 223ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
247#else 224#else
@@ -252,25 +229,21 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
252 ENGINE_PILE tmplate, *fnd=NULL; 229 ENGINE_PILE tmplate, *fnd=NULL;
253 int initres, loop = 0; 230 int initres, loop = 0;
254 231
255 /* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no
256 * ENGINEs have registered any implementations! */
257 if(!(*table)) 232 if(!(*table))
258 { 233 {
259#ifdef ENGINE_TABLE_DEBUG 234#ifdef ENGINE_TABLE_DEBUG
260 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " 235 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
261 "registered for anything!\n", f, l, nid); 236 "registered!\n", f, l, nid);
262#endif 237#endif
263 return NULL; 238 return NULL;
264 } 239 }
265 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 240 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
266 /* Check again inside the lock otherwise we could race against cleanup 241 /* Check again inside the lock otherwise we could race against cleanup
267 * operations. But don't worry about a fprintf(stderr). */ 242 * operations. But don't worry about a fprintf(stderr). */
268 if(!int_table_check(table, 0)) 243 if(!int_table_check(table, 0)) goto end;
269 goto end;
270 tmplate.nid = nid; 244 tmplate.nid = nid;
271 fnd = lh_retrieve(&(*table)->piles, &tmplate); 245 fnd = lh_retrieve(&(*table)->piles, &tmplate);
272 if(!fnd) 246 if(!fnd) goto end;
273 goto end;
274 if(fnd->funct && engine_unlocked_init(fnd->funct)) 247 if(fnd->funct && engine_unlocked_init(fnd->funct))
275 { 248 {
276#ifdef ENGINE_TABLE_DEBUG 249#ifdef ENGINE_TABLE_DEBUG
@@ -296,34 +269,19 @@ trynext:
296#endif 269#endif
297 goto end; 270 goto end;
298 } 271 }
299#if 0 272 /* Try to initialise the ENGINE? */
300 /* Don't need to get a reference if we hold the lock. If the locking has
301 * to change in future, that would be different ... */
302 ret->struct_ref++; engine_ref_debug(ret, 0, 1)
303#endif
304 /* Try and initialise the ENGINE if it's already functional *or* if the
305 * ENGINE_TABLE_FLAG_NOINIT flag is not set. */
306 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) 273 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
307 initres = engine_unlocked_init(ret); 274 initres = engine_unlocked_init(ret);
308 else 275 else
309 initres = 0; 276 initres = 0;
310#if 0
311 /* Release the structural reference */
312 ret->struct_ref--; engine_ref_debug(ret, 0, -1);
313#endif
314 if(initres) 277 if(initres)
315 { 278 {
316 /* If we didn't have a default (functional reference) for this 279 /* Update 'funct' */
317 * 'nid' (or we had one but for whatever reason we're now
318 * initialising a different one), use this opportunity to set
319 * 'funct'. */
320 if((fnd->funct != ret) && engine_unlocked_init(ret)) 280 if((fnd->funct != ret) && engine_unlocked_init(ret))
321 { 281 {
322 /* If there was a previous default we release it. */ 282 /* If there was a previous default we release it. */
323 if(fnd->funct) 283 if(fnd->funct)
324 engine_unlocked_finish(fnd->funct, 0); 284 engine_unlocked_finish(fnd->funct, 0);
325 /* We got an extra functional reference for the
326 * per-'nid' default */
327 fnd->funct = ret; 285 fnd->funct = ret;
328#ifdef ENGINE_TABLE_DEBUG 286#ifdef ENGINE_TABLE_DEBUG
329 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " 287 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
@@ -338,13 +296,9 @@ trynext:
338 } 296 }
339 goto trynext; 297 goto trynext;
340end: 298end:
341 /* Whatever happened - we should "untouch" our uptodate file seeing as 299 /* If it failed, it is unlikely to succeed again until some future
342 * we have tried our best to find a functional reference for 'nid'. If 300 * registrations have taken place. In all cases, we cache. */
343 * it failed, it is unlikely to succeed again until some future 301 if(fnd) fnd->uptodate = 1;
344 * registrations (or unregistrations) have taken place that affect that
345 * 'nid'. */
346 if(fnd)
347 fnd->uptodate = 1;
348#ifdef ENGINE_TABLE_DEBUG 302#ifdef ENGINE_TABLE_DEBUG
349 if(ret) 303 if(ret)
350 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " 304 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "