diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /openssl/crypto/engine/eng_table.c | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'openssl/crypto/engine/eng_table.c')
-rw-r--r-- | openssl/crypto/engine/eng_table.c | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/openssl/crypto/engine/eng_table.c b/openssl/crypto/engine/eng_table.c new file mode 100644 index 000000000..8879a267d --- /dev/null +++ b/openssl/crypto/engine/eng_table.c @@ -0,0 +1,315 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include <openssl/evp.h> +#include <openssl/lhash.h> +#include "eng_int.h" + +/* The type of the items in the table */ +typedef struct st_engine_pile + { + /* The 'nid' of this algorithm/mode */ + int nid; + /* ENGINEs that implement this algorithm/mode. */ + STACK_OF(ENGINE) *sk; + /* The default ENGINE to perform this algorithm/mode. */ + ENGINE *funct; + /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */ + int uptodate; + } ENGINE_PILE; + +/* The type exposed in eng_int.h */ +struct st_engine_table + { + LHASH piles; + }; /* ENGINE_TABLE */ + +/* Global flags (ENGINE_TABLE_FLAG_***). */ +static unsigned int table_flags = 0; + +/* API function manipulating 'table_flags' */ +unsigned int ENGINE_get_table_flags(void) + { + return table_flags; + } +void ENGINE_set_table_flags(unsigned int flags) + { + table_flags = flags; + } + +/* Internal functions for the "piles" hash table */ +static unsigned long engine_pile_hash(const ENGINE_PILE *c) + { + return c->nid; + } +static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) + { + return a->nid - b->nid; + } +static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) +static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) +static int int_table_check(ENGINE_TABLE **t, int create) + { + LHASH *lh; + if(*t) return 1; + if(!create) return 0; + if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), + LHASH_COMP_FN(engine_pile_cmp))) == NULL) + return 0; + *t = (ENGINE_TABLE *)lh; + return 1; + } + +/* Privately exposed (via eng_int.h) functions for adding and/or removing + * ENGINEs from the implementation table */ +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, int setdefault) + { + int ret = 0, added = 0; + ENGINE_PILE tmplate, *fnd; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(!(*table)) + added = 1; + if(!int_table_check(table, 1)) + goto end; + if(added) + /* The cleanup callback needs to be added */ + engine_cleanup_add_first(cleanup); + while(num_nids--) + { + tmplate.nid = *nids; + fnd = lh_retrieve(&(*table)->piles, &tmplate); + if(!fnd) + { + fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); + if(!fnd) goto end; + fnd->uptodate = 1; + fnd->nid = *nids; + fnd->sk = sk_ENGINE_new_null(); + if(!fnd->sk) + { + OPENSSL_free(fnd); + goto end; + } + fnd->funct = NULL; + lh_insert(&(*table)->piles, fnd); + } + /* A registration shouldn't add duplciate entries */ + (void)sk_ENGINE_delete_ptr(fnd->sk, e); + /* if 'setdefault', this ENGINE goes to the head of the list */ + if(!sk_ENGINE_push(fnd->sk, e)) + goto end; + /* "touch" this ENGINE_PILE */ + fnd->uptodate = 0; + if(setdefault) + { + if(!engine_unlocked_init(e)) + { + ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, + ENGINE_R_INIT_FAILED); + goto end; + } + if(fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = e; + fnd->uptodate = 1; + } + nids++; + } + ret = 1; +end: + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; + } +static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) + { + int n; + /* Iterate the 'c->sk' stack removing any occurance of 'e' */ + while((n = sk_ENGINE_find(pile->sk, e)) >= 0) + { + (void)sk_ENGINE_delete(pile->sk, n); + pile->uptodate = 0; + } + if(pile->funct == e) + { + engine_unlocked_finish(e, 0); + pile->funct = NULL; + } + } +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) + { + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(int_table_check(table, 0)) + lh_doall_arg(&(*table)->piles, + LHASH_DOALL_ARG_FN(int_unregister_cb), e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + } + +static void int_cleanup_cb(ENGINE_PILE *p) + { + sk_ENGINE_free(p->sk); + if(p->funct) + engine_unlocked_finish(p->funct, 0); + OPENSSL_free(p); + } +static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) +void engine_table_cleanup(ENGINE_TABLE **table) + { + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(*table) + { + lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); + lh_free(&(*table)->piles); + *table = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + } + +/* return a functional reference for a given 'nid' */ +#ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) +#else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l) +#endif + { + ENGINE *ret = NULL; + ENGINE_PILE tmplate, *fnd=NULL; + int initres, loop = 0; + + if(!(*table)) + { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " + "registered!\n", f, l, nid); +#endif + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* Check again inside the lock otherwise we could race against cleanup + * operations. But don't worry about a fprintf(stderr). */ + if(!int_table_check(table, 0)) goto end; + tmplate.nid = nid; + fnd = lh_retrieve(&(*table)->piles, &tmplate); + if(!fnd) goto end; + if(fnd->funct && engine_unlocked_init(fnd->funct)) + { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); +#endif + ret = fnd->funct; + goto end; + } + if(fnd->uptodate) + { + ret = fnd->funct; + goto end; + } +trynext: + ret = sk_ENGINE_value(fnd->sk, loop++); + if(!ret) + { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " + "registered implementations would initialise\n", + f, l, nid); +#endif + goto end; + } + /* Try to initialise the ENGINE? */ + if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) + initres = engine_unlocked_init(ret); + else + initres = 0; + if(initres) + { + /* Update 'funct' */ + if((fnd->funct != ret) && engine_unlocked_init(ret)) + { + /* If there was a previous default we release it. */ + if(fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = ret; +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " + "setting default to '%s'\n", f, l, nid, ret->id); +#endif + } +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "newly initialised '%s'\n", f, l, nid, ret->id); +#endif + goto end; + } + goto trynext; +end: + /* If it failed, it is unlikely to succeed again until some future + * registrations have taken place. In all cases, we cache. */ + if(fnd) fnd->uptodate = 1; +#ifdef ENGINE_TABLE_DEBUG + if(ret) + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "ENGINE '%s'\n", f, l, nid, ret->id); + else + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "'no matching ENGINE'\n", f, l, nid); +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* Whatever happened, any failed init()s are not failures in this + * context, so clear our error state. */ + ERR_clear_error(); + return ret; + } |