X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fasn1%2Fameth_lib.c;h=d155791324007296de75bcc9220fa2d9ff5ebde0;hb=6cb9fca70d5878fde11b5f16fee259c49f936d1c;hp=8c33ca562587d691245a0270f0a868ffa0352355;hpb=492a9e241550b537ef3db1719e18e9b795b6d24c;p=oweals%2Fopenssl.git diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index 8c33ca5625..d155791324 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -59,13 +59,16 @@ #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; /* Keep this sorted in type order !! */ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = @@ -85,12 +88,14 @@ static 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 }; 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; @@ -117,7 +122,7 @@ 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,20 +134,19 @@ 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; tmp.pkey_id = type; if (app_methods) { int idx; - idx = sk_find(app_methods, (char *)&tmp); + idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); if (idx >= 0) - return (EVP_PKEY_ASN1_METHOD *) - sk_value(app_methods, idx); + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); } ret = (EVP_PKEY_ASN1_METHOD **) OBJ_bsearch((char *)&t, (char *)standard_methods, @@ -151,17 +155,69 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type) (int (*)(const void *, const void *))ameth_cmp); 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; + ENGINE *e; + + 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 + /* 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); @@ -178,24 +234,23 @@ 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, NULL, NULL); + ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); if (!ameth) return 0; ameth->pkey_base_id = to; - ameth->pkey_flags |= ASN1_PKEY_ALIAS; return EVP_PKEY_asn1_add0(ameth); } @@ -218,7 +273,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; @@ -228,7 +288,7 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, ameth->pkey_id = id; ameth->pkey_base_id = id; - ameth->pkey_flags = ASN1_PKEY_DYNAMIC; + ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; if (info) { @@ -243,7 +303,7 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, if (!ameth->pem_str) goto err; } - + ameth->pub_decode = 0; ameth->pub_encode = 0; ameth->pub_cmp = 0; @@ -253,6 +313,9 @@ 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->pkey_size = 0; ameth->pkey_bits = 0; @@ -275,6 +338,37 @@ 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; + + } + void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) { if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))