X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fameth_lib.c;h=a19e058fca693f429868bd3e5d9be5ecec133fac;hp=6f98872cf10baf235966a0c56eb8ffc2a2fdbf22;hb=3231e42d726dcb1c9fd064ea8350d4f362718443;hpb=0b33dac3100c68ab19a6be804cdeaaa87582b9a0 diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index 6f98872cf1..a19e058fca 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -1,4 +1,4 @@ -/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ /* ==================================================================== @@ -59,16 +59,20 @@ #include "cryptlib.h" #include #include -#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif #include "asn1_locl.h" extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; /* Keep this sorted in type order !! */ -const EVP_PKEY_ASN1_METHOD *standard_methods[] = +static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { #ifndef OPENSSL_NO_RSA &rsa_asn1_meths[0], @@ -85,12 +89,15 @@ const EVP_PKEY_ASN1_METHOD *standard_methods[] = &dsa_asn1_meths[4], #endif #ifndef OPENSSL_NO_EC - &eckey_asn1_meth + &eckey_asn1_meth, #endif + &hmac_asn1_meth, + &cmac_asn1_meth }; typedef int sk_cmp_fn_type(const char * const *a, const char * const *b); -static STACK *app_methods = NULL; +DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD) +static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL; @@ -107,17 +114,23 @@ void main() } #endif +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a, - const EVP_PKEY_ASN1_METHOD * const *b) + const EVP_PKEY_ASN1_METHOD * const *b) { return ((*a)->pkey_id - (*b)->pkey_id); } +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + int EVP_PKEY_asn1_get_count(void) { int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *); if (app_methods) - num += sk_num(app_methods); + num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); return num; } @@ -129,63 +142,125 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) if (idx < num) return standard_methods[idx]; idx -= num; - return (const EVP_PKEY_ASN1_METHOD *)sk_value(app_methods, idx); + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); } -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type) +static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) { - EVP_PKEY_ASN1_METHOD tmp, *t = &tmp, **ret; + EVP_PKEY_ASN1_METHOD tmp; + const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; tmp.pkey_id = type; if (app_methods) { int idx; - idx = sk_find(app_methods, (char *)&t); - if (idx > 0) - return (EVP_PKEY_ASN1_METHOD *) - sk_value(app_methods, idx); + idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); } - ret = (EVP_PKEY_ASN1_METHOD **) OBJ_bsearch((char *)&t, - (char *)standard_methods, - sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *), - sizeof(EVP_PKEY_ASN1_METHOD *), - (int (*)(const void *, const void *))ameth_cmp); + ret = OBJ_bsearch_ameth(&t, standard_methods, + sizeof(standard_methods) + /sizeof(EVP_PKEY_ASN1_METHOD *)); if (!ret || !*ret) return NULL; - if ((*ret)->pkey_flags & ASN1_PKEY_ALIAS) - return EVP_PKEY_asn1_find((*ret)->pkey_base_id); return *ret; } -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len) +/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL + * also search through engines and set *pe to a functional reference + * to the engine implementing 'type' or NULL if no engine implements + * it. + */ + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type) + { + const EVP_PKEY_ASN1_METHOD *t; + + for (;;) + { + t = pkey_asn1_find(type); + if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) + break; + type = t->pkey_base_id; + } + if (pe) + { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + /* type will contain the final unaliased type */ + e = ENGINE_get_pkey_asn1_meth_engine(type); + if (e) + { + *pe = e; + return ENGINE_get_pkey_asn1_meth(e, type); + } +#endif + *pe = NULL; + } + return t; + } + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len) { int i; const EVP_PKEY_ASN1_METHOD *ameth; + if (len == -1) + len = strlen(str); + if (pe) + { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + ameth = ENGINE_pkey_asn1_find_str(&e, str, len); + if (ameth) + { + /* Convert structural into + * functional reference + */ + if (!ENGINE_init(e)) + ameth = NULL; + ENGINE_free(e); + *pe = e; + return ameth; + } +#endif + *pe = NULL; + } for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { ameth = EVP_PKEY_asn1_get0(i); if (ameth->pkey_flags & ASN1_PKEY_ALIAS) continue; - if ((strlen(ameth->pem_str) == len) && + if (((int)strlen(ameth->pem_str) == len) && !strncasecmp(ameth->pem_str, str, len)) return ameth; } return NULL; } -int EVP_PKEY_asn1_add(const EVP_PKEY_ASN1_METHOD *ameth) +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) { if (app_methods == NULL) { - app_methods = sk_new((sk_cmp_fn_type *)ameth_cmp); + app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); if (!app_methods) return 0; } - if (!sk_push(app_methods, (char *)ameth)) + if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) return 0; - sk_sort(app_methods); + sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); return 1; } +int EVP_PKEY_asn1_add_alias(int to, int from) + { + EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); + if (!ameth) + return 0; + ameth->pkey_base_id = to; + return EVP_PKEY_asn1_add0(ameth); + } + int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, const char **pinfo, const char **ppem_str, const EVP_PKEY_ASN1_METHOD *ameth) @@ -205,7 +280,12 @@ int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, return 1; } -EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey) + { + return pkey->ameth; + } + +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, const char *info) { EVP_PKEY_ASN1_METHOD *ameth; @@ -213,9 +293,11 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, if (!ameth) return NULL; + memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD)); + ameth->pkey_id = id; ameth->pkey_base_id = id; - ameth->pkey_flags = ASN1_PKEY_DYNAMIC; + ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; if (info) { @@ -223,6 +305,8 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, if (!ameth->info) goto err; } + else + ameth->info = NULL; if (pem_str) { @@ -230,7 +314,9 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, if (!ameth->pem_str) goto err; } - + else + ameth->pem_str = NULL; + ameth->pub_decode = 0; ameth->pub_encode = 0; ameth->pub_cmp = 0; @@ -240,6 +326,12 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, ameth->priv_encode = 0; ameth->priv_print = 0; + ameth->old_priv_encode = 0; + ameth->old_priv_decode = 0; + + ameth->item_verify = 0; + ameth->item_sign = 0; + ameth->pkey_size = 0; ameth->pkey_bits = 0; @@ -262,6 +354,40 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, } +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src) + { + + dst->pub_decode = src->pub_decode; + dst->pub_encode = src->pub_encode; + dst->pub_cmp = src->pub_cmp; + dst->pub_print = src->pub_print; + + dst->priv_decode = src->priv_decode; + dst->priv_encode = src->priv_encode; + dst->priv_print = src->priv_print; + + dst->old_priv_encode = src->old_priv_encode; + dst->old_priv_decode = src->old_priv_decode; + + dst->pkey_size = src->pkey_size; + dst->pkey_bits = src->pkey_bits; + + dst->param_decode = src->param_decode; + dst->param_encode = src->param_encode; + dst->param_missing = src->param_missing; + dst->param_copy = src->param_copy; + dst->param_cmp = src->param_cmp; + dst->param_print = src->param_print; + + dst->pkey_free = src->pkey_free; + dst->pkey_ctrl = src->pkey_ctrl; + + dst->item_sign = src->item_sign; + dst->item_verify = src->item_verify; + + } + void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) { if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) @@ -327,7 +453,7 @@ void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, } void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, - void (*pkey_ctrl)(EVP_PKEY *pkey, int op, + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2)) { ameth->pkey_ctrl = pkey_ctrl;