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.
This commit is contained in:
Dr. Stephen Henson 2007-11-21 17:25:58 +00:00
parent 98057eba77
commit 2f0550c4c1
5 changed files with 90 additions and 13 deletions

View 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;

View 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

View 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);
}

View 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);

View 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;
}