diff options
| author | djm <> | 2008-09-06 12:17:54 +0000 |
|---|---|---|
| committer | djm <> | 2008-09-06 12:17:54 +0000 |
| commit | 6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda (patch) | |
| tree | 7ccc28afe1789ea3dbedf72365f955d5b8e105b5 /src/lib/libcrypto/engine/eng_table.c | |
| parent | 89181603212b41e95cde36b1be5a146ce8fb2935 (diff) | |
| download | openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.gz openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.bz2 openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.zip | |
resolve conflicts
Diffstat (limited to 'src/lib/libcrypto/engine/eng_table.c')
| -rw-r--r-- | src/lib/libcrypto/engine/eng_table.c | 94 |
1 files changed, 24 insertions, 70 deletions
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c index c69a84a8bf..8879a267d1 100644 --- a/src/lib/libcrypto/engine/eng_table.c +++ b/src/lib/libcrypto/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 */ |
| 68 | typedef struct st_engine_pile | 61 | typedef 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. */ | ||
| 89 | struct st_engine_table | 74 | struct 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. */ | ||
| 98 | static unsigned int table_flags = 0; | 80 | static 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 *) | |||
| 121 | static int int_table_check(ENGINE_TABLE **t, int create) | 103 | static 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 |
| 246 | ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) | 223 | ENGINE *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; |
| 340 | end: | 298 | end: |
| 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 " |
