diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2007-11-21 17:25:58 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2007-11-21 17:25:58 +0000 |
commit | 2f0550c4c1b622540091368eabada3f5e4549976 (patch) | |
tree | 3891fa284942ec541c74c4be8117fb5455d9171e /crypto/engine | |
parent | 98057eba7794790f6de51da83f3c9ed8faf3279b (diff) |
Lookup public key ASN1 methods by string by iterating through all
implementations instead of all added ENGINEs to cover case where an
ENGINE is not added.
Diffstat (limited to 'crypto/engine')
-rw-r--r-- | crypto/engine/eng_int.h | 2 | ||||
-rw-r--r-- | crypto/engine/eng_table.c | 26 | ||||
-rw-r--r-- | crypto/engine/engine.h | 2 | ||||
-rw-r--r-- | crypto/engine/tb_asnmth.c | 50 |
4 files changed, 80 insertions, 0 deletions
diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h index 8bee5962c5..f7c382c37e 100644 --- a/crypto/engine/eng_int.h +++ b/crypto/engine/eng_int.h @@ -127,6 +127,8 @@ ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l); #define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) #endif +typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg); +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg); /* Internal versions of API functions that have control over locking. These are * used between C files when functionality needs to be shared but the caller may diff --git a/crypto/engine/eng_table.c b/crypto/engine/eng_table.c index 0c1656168d..3e892c8a62 100644 --- a/crypto/engine/eng_table.c +++ b/crypto/engine/eng_table.c @@ -76,6 +76,14 @@ struct st_engine_table LHASH piles; }; /* ENGINE_TABLE */ + +typedef struct st_engine_pile_doall + { + engine_table_doall_cb *cb; + void *arg; + } ENGINE_PILE_DOALL; + + /* Global flags (ENGINE_TABLE_FLAG_***). */ static unsigned int table_flags = 0; @@ -313,3 +321,21 @@ end: ERR_clear_error(); return ret; } + +/* Table enumeration */ + +static void int_doall_cb(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) + { + dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); + } + +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_doall_cb,ENGINE_PILE *,ENGINE_PILE_DOALL *) +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, + void *arg) + { + ENGINE_PILE_DOALL dall; + dall.cb = cb; + dall.arg = arg; + lh_doall_arg(&table->piles, + LHASH_DOALL_ARG_FN(int_doall_cb), &dall); + } diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index 56aaa594ed..ed966a82c5 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -520,6 +520,8 @@ const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, const char *str, int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, int len); const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); int ENGINE_get_flags(const ENGINE *e); diff --git a/crypto/engine/tb_asnmth.c b/crypto/engine/tb_asnmth.c index b3a4fd533c..0972813a02 100644 --- a/crypto/engine/tb_asnmth.c +++ b/crypto/engine/tb_asnmth.c @@ -193,3 +193,53 @@ const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, } return NULL; } + +typedef struct + { + ENGINE *e; + const EVP_PKEY_ASN1_METHOD *ameth; + const char *str; + int len; + } ENGINE_FIND_STR; + +static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) + { + ENGINE_FIND_STR *lk = arg; + int i; + if (lk->ameth) + return; + for (i = 0; i < sk_ENGINE_num(sk); i++) + { + ENGINE *e = sk_ENGINE_value(sk, i); + EVP_PKEY_ASN1_METHOD *ameth; + e->pkey_asn1_meths(e, &ameth, NULL, nid); + if (((int)strlen(ameth->pem_str) == lk->len) && + !strncasecmp(ameth->pem_str, lk->str, lk->len)) + { + lk->e = e; + lk->ameth = ameth; + return; + } + } + } + +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, int len) + { + ENGINE_FIND_STR fstr; + fstr.e = NULL; + fstr.ameth = NULL; + fstr.str = str; + fstr.len = len; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); + /* If found obtain a structural reference to engine */ + if (fstr.e) + { + fstr.e->struct_ref++; + engine_ref_debug(fstr.e, 0, 1) + } + *pe = fstr.e; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return fstr.ameth; + } |