X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fd2i_pr.c;h=b2791ea66e351be76d1c71abb9d403cdbf24c9de;hp=43c7a3b917dc5d5e995772c28a7b07c581ea5e14;hb=01b8b3c7d2d8f835257ac1cb2512273aa27bfba8;hpb=ec577822f95a8bca0023c5c77cef1a4916822d4a diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c index 43c7a3b917..b2791ea66e 100644 --- a/crypto/asn1/d2i_pr.c +++ b/crypto/asn1/d2i_pr.c @@ -61,9 +61,11 @@ #include #include #include -#include +#include +#include +#include "asn1_locl.h" -EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, unsigned char **pp, +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; @@ -76,34 +78,27 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, unsigned char **pp, return(NULL); } } - else ret= *a; - - ret->save_type=type; - ret->type=EVP_PKEY_type(type); - switch (ret->type) + else { -#ifndef NO_RSA - case EVP_PKEY_RSA: - if ((ret->pkey.rsa=d2i_RSAPrivateKey(NULL,pp,length)) == NULL) - { - ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); - goto err; - } - break; -#endif -#ifndef NO_DSA - case EVP_PKEY_DSA: - if ((ret->pkey.dsa=d2i_DSAPrivateKey(NULL,pp,length)) == NULL) + ret= *a; + if (ret->engine) { - ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); - goto err; + ENGINE_finish(ret->engine); + ret->engine = NULL; } - break; -#endif - default: + } + + if (!EVP_PKEY_set_type(ret, type)) + { ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; - /* break; */ + } + + if (!ret->ameth->old_priv_decode || + !ret->ameth->old_priv_decode(ret, pp, length)) + { + ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); + goto err; } if (a != NULL) (*a)=ret; return(ret); @@ -112,3 +107,29 @@ err: return(NULL); } +/* This works like d2i_PrivateKey() except it automatically works out the type */ + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length) +{ + STACK_OF(ASN1_TYPE) *inkey; + const unsigned char *p; + int keytype; + p = *pp; + /* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): + * by analyzing it we can determine the passed structure: this + * assumes the input is surrounded by an ASN1 SEQUENCE. + */ + inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE, + ASN1_TYPE_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + /* Since we only need to discern "traditional format" RSA and DSA + * keys we can just count the elements. + */ + if(sk_ASN1_TYPE_num(inkey) == 6) + keytype = EVP_PKEY_DSA; + else if (sk_ASN1_TYPE_num(inkey) == 4) + keytype = EVP_PKEY_EC; + else keytype = EVP_PKEY_RSA; + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + return d2i_PrivateKey(keytype, a, pp, length); +}