| Index: openssl/crypto/asn1/d2i_pr.c
|
| ===================================================================
|
| --- openssl/crypto/asn1/d2i_pr.c (revision 105093)
|
| +++ openssl/crypto/asn1/d2i_pr.c (working copy)
|
| @@ -61,16 +61,12 @@
|
| #include <openssl/bn.h>
|
| #include <openssl/evp.h>
|
| #include <openssl/objects.h>
|
| +#ifndef OPENSSL_NO_ENGINE
|
| +#include <openssl/engine.h>
|
| +#endif
|
| +#include <openssl/x509.h>
|
| #include <openssl/asn1.h>
|
| -#ifndef OPENSSL_NO_RSA
|
| -#include <openssl/rsa.h>
|
| -#endif
|
| -#ifndef OPENSSL_NO_DSA
|
| -#include <openssl/dsa.h>
|
| -#endif
|
| -#ifndef OPENSSL_NO_EC
|
| -#include <openssl/ec.h>
|
| -#endif
|
| +#include "asn1_locl.h"
|
|
|
| EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
|
| long length)
|
| @@ -85,47 +81,43 @@
|
| return(NULL);
|
| }
|
| }
|
| - else ret= *a;
|
| -
|
| - ret->save_type=type;
|
| - ret->type=EVP_PKEY_type(type);
|
| - switch (ret->type)
|
| + else
|
| {
|
| -#ifndef OPENSSL_NO_RSA
|
| - case EVP_PKEY_RSA:
|
| - if ((ret->pkey.rsa=d2i_RSAPrivateKey(NULL,
|
| - (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
|
| + ret= *a;
|
| +#ifndef OPENSSL_NO_ENGINE
|
| + if (ret->engine)
|
| {
|
| - ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
|
| - goto err;
|
| + ENGINE_finish(ret->engine);
|
| + ret->engine = NULL;
|
| }
|
| - break;
|
| #endif
|
| -#ifndef OPENSSL_NO_DSA
|
| - case EVP_PKEY_DSA:
|
| - if ((ret->pkey.dsa=d2i_DSAPrivateKey(NULL,
|
| - (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
|
| + }
|
| +
|
| + if (!EVP_PKEY_set_type(ret, type))
|
| + {
|
| + ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
| + goto err;
|
| + }
|
| +
|
| + if (!ret->ameth->old_priv_decode ||
|
| + !ret->ameth->old_priv_decode(ret, pp, length))
|
| + {
|
| + if (ret->ameth->priv_decode)
|
| {
|
| + PKCS8_PRIV_KEY_INFO *p8=NULL;
|
| + p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
|
| + if (!p8) goto err;
|
| + EVP_PKEY_free(ret);
|
| + ret = EVP_PKCS82PKEY(p8);
|
| + PKCS8_PRIV_KEY_INFO_free(p8);
|
| +
|
| + }
|
| + else
|
| + {
|
| ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
|
| goto err;
|
| }
|
| - break;
|
| -#endif
|
| -#ifndef OPENSSL_NO_EC
|
| - case EVP_PKEY_EC:
|
| - if ((ret->pkey.ec = d2i_ECPrivateKey(NULL,
|
| - (const unsigned char **)pp, length)) == NULL)
|
| - {
|
| - ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
|
| - goto err;
|
| - }
|
| - break;
|
| -#endif
|
| - default:
|
| - ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
| - goto err;
|
| - /* break; */
|
| - }
|
| + }
|
| if (a != NULL) (*a)=ret;
|
| return(ret);
|
| err:
|
| @@ -146,8 +138,7 @@
|
| * 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);
|
| + inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
|
| /* Since we only need to discern "traditional format" RSA and DSA
|
| * keys we can just count the elements.
|
| */
|
| @@ -155,6 +146,24 @@
|
| keytype = EVP_PKEY_DSA;
|
| else if (sk_ASN1_TYPE_num(inkey) == 4)
|
| keytype = EVP_PKEY_EC;
|
| + else if (sk_ASN1_TYPE_num(inkey) == 3)
|
| + { /* This seems to be PKCS8, not traditional format */
|
| + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
|
| + EVP_PKEY *ret;
|
| +
|
| + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
|
| + if (!p8)
|
| + {
|
| + ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
| + return NULL;
|
| + }
|
| + ret = EVP_PKCS82PKEY(p8);
|
| + PKCS8_PRIV_KEY_INFO_free(p8);
|
| + if (a) {
|
| + *a = ret;
|
| + }
|
| + return ret;
|
| + }
|
| else keytype = EVP_PKEY_RSA;
|
| sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
|
| return d2i_PrivateKey(keytype, a, pp, length);
|
|
|