Fix some of the command line password stuff. New function that can automatically determine the type of a DER encoded "traditional" format private key and change some of the d2i functions to use it instead of requiring the application to work out the key type.
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index a24775d..c9500a6 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h
@@ -890,8 +890,6 @@ #define ASN1_F_D2I_POLICYINFO 269 #define ASN1_F_D2I_POLICYQUALINFO 270 #define ASN1_F_D2I_PRIVATEKEY 155 -#define ASN1_F_D2I_PRIVATEKEY_BIO 293 -#define ASN1_F_D2I_PRIVATEKEY_FP 294 #define ASN1_F_D2I_PUBLICKEY 156 #define ASN1_F_D2I_RSAPRIVATEKEY 157 #define ASN1_F_D2I_RSAPUBLICKEY 158
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index 62aa5f4..e7ac614 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c
@@ -163,8 +163,6 @@ {ERR_PACK(0,ASN1_F_D2I_POLICYINFO,0), "d2i_POLICYINFO"}, {ERR_PACK(0,ASN1_F_D2I_POLICYQUALINFO,0), "d2i_POLICYQUALINFO"}, {ERR_PACK(0,ASN1_F_D2I_PRIVATEKEY,0), "d2i_PrivateKey"}, -{ERR_PACK(0,ASN1_F_D2I_PRIVATEKEY_BIO,0), "d2i_PrivateKey_bio"}, -{ERR_PACK(0,ASN1_F_D2I_PRIVATEKEY_FP,0), "d2i_PrivateKey_fp"}, {ERR_PACK(0,ASN1_F_D2I_PUBLICKEY,0), "d2i_PublicKey"}, {ERR_PACK(0,ASN1_F_D2I_RSAPRIVATEKEY,0), "d2i_RSAPrivateKey"}, {ERR_PACK(0,ASN1_F_D2I_RSAPUBLICKEY,0), "d2i_RSAPublicKey"},
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c index f3d1aa6..7ae8781 100644 --- a/crypto/asn1/d2i_pr.c +++ b/crypto/asn1/d2i_pr.c
@@ -112,3 +112,26 @@ return(NULL); } +/* This works like d2i_PrivateKey() except it automatically works out the type */ + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp, + long length) +{ + STACK_OF(ASN1_TYPE) *inkey; + unsigned char *p; + int keytype; + p = *pp; + /* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): + * by analysing 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 keytype = EVP_PKEY_RSA; + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + return d2i_PrivateKey(keytype, a, pp, length); +}
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 2191aee..a4ed6c7 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h
@@ -632,6 +632,8 @@ EVP_PKEY * d2i_PrivateKey(int type,EVP_PKEY **a, unsigned char **pp, long length); +EVP_PKEY * d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp, + long length); int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); int EVP_PKEY_copy_parameters(EVP_PKEY *to,EVP_PKEY *from);
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index a11f9bc..2e6d207 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h
@@ -656,7 +656,7 @@ int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, int type, EVP_PKEY **a); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); #endif #ifdef HEADER_BIO_H @@ -687,7 +687,7 @@ int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, int type, EVP_PKEY **a); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); #endif X509 *X509_dup(X509 *x509);
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index e1d70df..d2bf3c8 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c
@@ -486,17 +486,10 @@ return(ASN1_i2d_fp(i2d_PrivateKey,fp,(unsigned char *)pkey)); } -EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, int type, EVP_PKEY **a) +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) { - BIO *bp; - EVP_PKEY *ret; - if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - ASN1err(ASN1_F_D2I_PRIVATEKEY_FP,ERR_R_MALLOC_FAILURE); - return NULL; - } - ret = d2i_PrivateKey_bio(bp, type, a); - BIO_free(bp); - return ret; + return((EVP_PKEY *)ASN1_d2i_fp((char *(*)())EVP_PKEY_new, + (char *(*)())d2i_AutoPrivateKey, (fp),(unsigned char **)(a))); } #endif @@ -531,50 +524,8 @@ return(ASN1_i2d_bio(i2d_PrivateKey,bp,(unsigned char *)pkey)); } -EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, int type, EVP_PKEY **a) +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) { - EVP_PKEY *ret; - - if ((a == NULL) || (*a == NULL)) - { - if ((ret=EVP_PKEY_new()) == NULL) - { - ASN1err(ASN1_F_D2I_PRIVATEKEY_BIO,ERR_R_EVP_LIB); - return(NULL); - } - } - else ret= *a; - - ret->save_type=type; - ret->type=EVP_PKEY_type(type); - switch (ret->type) - { -#ifndef NO_RSA - case EVP_PKEY_RSA: - if ((ret->pkey.rsa=d2i_RSAPrivateKey_bio(bp,NULL)) == NULL) - { - ASN1err(ASN1_F_D2I_PRIVATEKEY_BIO,ERR_R_ASN1_LIB); - goto err; - } - break; -#endif -#ifndef NO_DSA - case EVP_PKEY_DSA: - if ((ret->pkey.dsa=d2i_DSAPrivateKey_bio(bp, NULL)) == NULL) - { - ASN1err(ASN1_F_D2I_PRIVATEKEY_BIO,ERR_R_ASN1_LIB); - goto err; - } - break; -#endif - default: - ASN1err(ASN1_F_D2I_PRIVATEKEY_BIO,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); - goto err; - /* break; */ - } - if (a != NULL) (*a)=ret; - return(ret); -err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret); - return(NULL); + return((EVP_PKEY *)ASN1_d2i_bio((char *(*)())EVP_PKEY_new, + (char *(*)())d2i_AutoPrivateKey, (bp),(unsigned char **)(a))); }