eng_table.c revision 656d9c7f52f88b3a3daccafa7655dec086c4756e
181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* ==================================================================== 281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * Redistribution and use in source and binary forms, with or without 581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * modification, are permitted provided that the following conditions 681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * are met: 781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 1. Redistributions of source code must retain the above copyright 981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * notice, this list of conditions and the following disclaimer. 1081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 1181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 2. Redistributions in binary form must reproduce the above copyright 1281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * notice, this list of conditions and the following disclaimer in 1381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * the documentation and/or other materials provided with the 1481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * distribution. 1581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 1681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 3. All advertising materials mentioning features or use of this 1781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * software must display the following acknowledgment: 1881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * "This product includes software developed by the OpenSSL Project 1981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 21371eb9756c32109ea572b91216b19bb623f6d3fdAlex Ray * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * endorse or promote products derived from this software without 23153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten * prior written permission. For written permission, please contact 2481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * licensing@OpenSSL.org. 2581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 2681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 5. Products derived from this software may not be called "OpenSSL" 2781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * nor may "OpenSSL" appear in their names without prior written 281ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten * permission of the OpenSSL Project. 29cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * 3081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 6. Redistributions of any form whatsoever must retain the following 31371eb9756c32109ea572b91216b19bb623f6d3fdAlex Ray * acknowledgment: 3281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * "This product includes software developed by the OpenSSL Project 3381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 3581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 3681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * OF THE POSSIBILITY OF SUCH DAMAGE. 4781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * ==================================================================== 4881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 4981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * This product includes cryptographic software written by Eric Young 5081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * (eay@cryptsoft.com). This product includes software written by Tim 5181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * Hudson (tjh@cryptsoft.com). 5281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * 5381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent */ 5481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "cryptlib.h" 5681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <openssl/evp.h> 5781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <openssl/lhash.h> 586dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#include "eng_int.h" 5981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* The type of the items in the table */ 6181784c37c61b09289654b979567a42bf73cd2b12Eric Laurenttypedef struct st_engine_pile 6281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 6381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* The 'nid' of this algorithm/mode */ 6481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int nid; 6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* ENGINEs that implement this algorithm/mode. */ 6681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent STACK_OF(ENGINE) *sk; 6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* The default ENGINE to perform this algorithm/mode. */ 6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ENGINE *funct; 6981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */ 7081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int uptodate; 7181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } ENGINE_PILE; 7281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* The type exposed in eng_int.h */ 7481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstruct st_engine_table 7581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 7681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent LHASH piles; 7781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent }; /* ENGINE_TABLE */ 7881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* Global flags (ENGINE_TABLE_FLAG_***). */ 8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic unsigned int table_flags = 0; 8181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* API function manipulating 'table_flags' */ 8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentunsigned int ENGINE_get_table_flags(void) 8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return table_flags; 8681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 8749d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kastenvoid ENGINE_set_table_flags(unsigned int flags) 8849d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten { 8981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent table_flags = flags; 9081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 9181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 9281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* Internal functions for the "piles" hash table */ 9381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic unsigned long engine_pile_hash(const ENGINE_PILE *c) 9481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 9581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return c->nid; 9681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 9781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) 9881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 9981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return a->nid - b->nid; 10081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 10181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) 10281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) 10381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic int int_table_check(ENGINE_TABLE **t, int create) 10481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 10581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent LHASH *lh; 1061035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if(*t) return 1; 1071035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if(!create) return 0; 10881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), 10981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent LHASH_COMP_FN(engine_pile_cmp))) == NULL) 11081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 0; 11181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *t = (ENGINE_TABLE *)lh; 11281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 1; 11381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 11409a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung 11509a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung/* Privately exposed (via eng_int.h) functions for adding and/or removing 11609a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung * ENGINEs from the implementation table */ 11709a5007b17acb49d25cfa386a2e2534d942e8854Andy Hungint engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, 11881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ENGINE *e, const int *nids, int num_nids, int setdefault) 119972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent { 120972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent int ret = 0, added = 0; 121972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent ENGINE_PILE tmplate, *fnd; 12281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 12381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!(*table)) 12481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent added = 1; 12581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!int_table_check(table, 1)) 12681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto end; 12781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(added) 12881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* The cleanup callback needs to be added */ 12981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent engine_cleanup_add_first(cleanup); 13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while(num_nids--) 13181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 13281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tmplate.nid = *nids; 13381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fnd = lh_retrieve(&(*table)->piles, &tmplate); 13481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!fnd) 13581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 13681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); 13781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!fnd) goto end; 13881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fnd->uptodate = 1; 1396dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten fnd->nid = *nids; 1406dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten fnd->sk = sk_ENGINE_new_null(); 1416dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if(!fnd->sk) 1426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten { 1436dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten OPENSSL_free(fnd); 1446dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten goto end; 1456dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 14681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fnd->funct = NULL; 14781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lh_insert(&(*table)->piles, fnd); 14881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten /* A registration shouldn't add duplciate entries */ 15081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (void)sk_ENGINE_delete_ptr(fnd->sk, e); 15181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* if 'setdefault', this ENGINE goes to the head of the list */ 15281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!sk_ENGINE_push(fnd->sk, e)) 153b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten goto end; 154b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten /* "touch" this ENGINE_PILE */ 155b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten fnd->uptodate = 0; 156b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten if(setdefault) 15781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 1580349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if(!engine_unlocked_init(e)) 1590349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten { 160b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, 16181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ENGINE_R_INIT_FAILED); 1620349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten goto end; 1630349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 1640349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if(fnd->funct) 1650349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten engine_unlocked_finish(fnd->funct, 0); 1660349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten fnd->funct = e; 1670349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten fnd->uptodate = 1; 1680349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 169b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten nids++; 170b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten } 171b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten ret = 1; 172b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kastenend: 1739f81de3452dfb2385bd57dc05456a045174a1ab1Glenn Kasten CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 174b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten return ret; 17581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 17681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) 1770349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten { 1780349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten int n; 1790349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten /* Iterate the 'c->sk' stack removing any occurance of 'e' */ 1800349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten while((n = sk_ENGINE_find(pile->sk, e)) >= 0) 1810349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten { 1820349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten (void)sk_ENGINE_delete(pile->sk, n); 1830349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten pile->uptodate = 0; 1840349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 1850349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if(pile->funct == e) 1860349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten { 1870349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten engine_unlocked_finish(e, 0); 1880349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten pile->funct = NULL; 1890349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 1900349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 1910349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) 1920349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenvoid engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) 19381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 19481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 19581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(int_table_check(table, 0)) 19681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lh_doall_arg(&(*table)->piles, 19781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent LHASH_DOALL_ARG_FN(int_unregister_cb), e); 19881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 19981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 20081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 20181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic void int_cleanup_cb(ENGINE_PILE *p) 20281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 20381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sk_ENGINE_free(p->sk); 20481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(p->funct) 20581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent engine_unlocked_finish(p->funct, 0); 20681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent OPENSSL_free(p); 20781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 20881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) 20981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid engine_table_cleanup(ENGINE_TABLE **table) 21081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 21181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 21281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(*table) 21381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 21481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); 21581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lh_free(&(*table)->piles); 21681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *table = NULL; 21781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 21881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 21981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 22081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 22181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* return a functional reference for a given 'nid' */ 22281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifndef ENGINE_TABLE_DEBUG 22381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentENGINE *engine_table_select(ENGINE_TABLE **table, int nid) 22481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else 22581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l) 22681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 22781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 22881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ENGINE *ret = NULL; 22981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ENGINE_PILE tmplate, *fnd=NULL; 23081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int initres, loop = 0; 23181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 23281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!(*table)) 23381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 2340f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten#ifdef ENGINE_TABLE_DEBUG 2350f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " 2360f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten "registered!\n", f, l, nid); 2370f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten#endif 2380f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten return NULL; 23981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 24081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 24181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* Check again inside the lock otherwise we could race against cleanup 24281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * operations. But don't worry about a fprintf(stderr). */ 24381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!int_table_check(table, 0)) goto end; 24481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tmplate.nid = nid; 24581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fnd = lh_retrieve(&(*table)->piles, &tmplate); 24681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!fnd) goto end; 24781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(fnd->funct && engine_unlocked_init(fnd->funct)) 24881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 24981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ENGINE_TABLE_DEBUG 25081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " 25181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); 25281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 25381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ret = fnd->funct; 25481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto end; 25581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 25681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(fnd->uptodate) 25781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 25881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ret = fnd->funct; 25981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto end; 26081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 26181784c37c61b09289654b979567a42bf73cd2b12Eric Laurenttrynext: 26281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ret = sk_ENGINE_value(fnd->sk, loop++); 26381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(!ret) 26481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 26581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ENGINE_TABLE_DEBUG 26681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " 26781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "registered implementations would initialise\n", 26881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent f, l, nid); 26981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 27081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto end; 27181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 27281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* Try to initialise the ENGINE? */ 27381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) 27481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent initres = engine_unlocked_init(ret); 27581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent else 27681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent initres = 0; 27781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(initres) 27881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 27981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* Update 'funct' */ 28081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if((fnd->funct != ret) && engine_unlocked_init(ret)) 28181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 28281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* If there was a previous default we release it. */ 28381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(fnd->funct) 28481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent engine_unlocked_finish(fnd->funct, 0); 28581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fnd->funct = ret; 28681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ENGINE_TABLE_DEBUG 28781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " 28881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "setting default to '%s'\n", f, l, nid, ret->id); 28981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 29081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 29181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ENGINE_TABLE_DEBUG 29281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " 29381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "newly initialised '%s'\n", f, l, nid, ret->id); 29481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 29581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto end; 29681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 29781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto trynext; 29881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentend: 29981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* If it failed, it is unlikely to succeed again until some future 30081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * registrations have taken place. In all cases, we cache. */ 30181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(fnd) fnd->uptodate = 1; 30281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ENGINE_TABLE_DEBUG 30381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if(ret) 30481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " 30581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "ENGINE '%s'\n", f, l, nid, ret->id); 30681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent else 30781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " 30881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "'no matching ENGINE'\n", f, l, nid); 30981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 31081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 31181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /* Whatever happened, any failed init()s are not failures in this 31281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * context, so clear our error state. */ 31381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ERR_clear_error(); 31481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return ret; 31581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 31681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent