aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2007-11-21 17:25:58 +0000
committerDr. Stephen Henson <steve@openssl.org>2007-11-21 17:25:58 +0000
commit2f0550c4c1b622540091368eabada3f5e4549976 (patch)
tree3891fa284942ec541c74c4be8117fb5455d9171e
parent98057eba7794790f6de51da83f3c9ed8faf3279b (diff)
downloadopenssl-2f0550c4c1b622540091368eabada3f5e4549976.tar.gz
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.
-rw-r--r--crypto/asn1/ameth_lib.c23
-rw-r--r--crypto/engine/eng_int.h2
-rw-r--r--crypto/engine/eng_table.c26
-rw-r--r--crypto/engine/engine.h2
-rw-r--r--crypto/engine/tb_asnmth.c50
5 files changed, 90 insertions, 13 deletions
diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
index 7c385f6dd3..cfaef87555 100644
--- a/crypto/asn1/ameth_lib.c
+++ b/crypto/asn1/ameth_lib.c
@@ -203,20 +203,17 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
{
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
- for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+ ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+ if (ameth)
{
- ameth = ENGINE_get_pkey_asn1_meth_str(e, str, len);
- if (ameth)
- {
- /* Convert structural into
- * functional reference
- */
- if (!ENGINE_init(e))
- ameth = NULL;
- ENGINE_free(e);
- *pe = e;
- return ameth;
- }
+ /* Convert structural into
+ * functional reference
+ */
+ if (!ENGINE_init(e))
+ ameth = NULL;
+ ENGINE_free(e);
+ *pe = e;
+ return ameth;
}
#endif
*pe = NULL;
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;
+ }