Lookup public key ASN1 methods by string by iterating through all
authorDr. Stephen Henson <steve@openssl.org>
Wed, 21 Nov 2007 17:25:58 +0000 (17:25 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 21 Nov 2007 17:25:58 +0000 (17:25 +0000)
implementations instead of all added ENGINEs to cover case where an
ENGINE is not added.

crypto/asn1/ameth_lib.c
crypto/engine/eng_int.h
crypto/engine/eng_table.c
crypto/engine/engine.h
crypto/engine/tb_asnmth.c

index 7c385f6..cfaef87 100644 (file)
@@ -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;
index 8bee596..f7c382c 100644 (file)
@@ -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
index 0c16561..3e892c8 100644 (file)
@@ -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);
+       }
index 56aaa59..ed966a8 100644 (file)
@@ -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);
 
index b3a4fd5..0972813 100644 (file)
@@ -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;
+       }