diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2007-11-20 13:37:51 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2007-11-20 13:37:51 +0000 |
commit | 94e6ae7a697486716313062c5c6700c9e0d6423a (patch) | |
tree | a7ca14b0f0e82a367934f452d4de8201b1b5a9b1 /crypto/asn1/d2i_pr.c | |
parent | f670738987247d43cad624bf432c6b615a950572 (diff) |
Submitted by: "Victor B. Wagner" <vitus@cryptocom.ru>
Make {d2i,i2d}_PrivateKey() fall back to PKCS#8 format if no legacy format
supported. Add support in d2i_AutoPrivateKey().
Diffstat (limited to 'crypto/asn1/d2i_pr.c')
-rw-r--r-- | crypto/asn1/d2i_pr.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c index e90cfa9db8..2828944777 100644 --- a/crypto/asn1/d2i_pr.c +++ b/crypto/asn1/d2i_pr.c @@ -64,6 +64,7 @@ #ifndef OPENSSL_NO_ENGINE #include <openssl/engine.h> #endif +#include <openssl/x509.h> #include <openssl/asn1.h> #include "asn1_locl.h" @@ -101,9 +102,22 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, 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 (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; + } + } if (a != NULL) (*a)=ret; return(ret); err: @@ -132,6 +146,24 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, 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); |