Pedantic polish to rc4-ia64.pl.
[openssl.git] / crypto / evp / evp_pkey.c
index e81b810deac53cfac66ffe617e169c343167dc74..0147f3e02a683979b43f10aaf60fbaefc06a59b8 100644 (file)
 #include "cryptlib.h"
 #include <openssl/x509.h>
 #include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
+#endif
 #include <openssl/bn.h>
 
 #ifndef OPENSSL_NO_DSA
@@ -74,7 +78,7 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
 
 /* Extract a private key from a PKCS8 structure */
 
-EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
 {
        EVP_PKEY *pkey = NULL;
 #ifndef OPENSSL_NO_RSA
@@ -250,6 +254,7 @@ EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
                }
                else
                {
+                       EC_GROUP *group;
                        cp = p = param->value.object->data;
                        plen = param->value.object->length;
 
@@ -262,11 +267,13 @@ EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
                                        ERR_R_MALLOC_FAILURE);
                                goto ecerr;
                        }
-                       if ((eckey->group = EC_GROUP_new_by_nid(
-                             OBJ_obj2nid(a->parameter->value.object))) == NULL)
+                       group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
+                       if (group == NULL)
+                               goto ecerr;
+                       EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+                       if (EC_KEY_set_group(eckey, group) == 0)
                                goto ecerr;
-                       EC_GROUP_set_asn1_flag(eckey->group, 
-                                               OPENSSL_EC_NAMED_CURVE);
+                       EC_GROUP_free(group);
                }
 
                /* We have parameters now set private key */
@@ -277,28 +284,40 @@ EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
                }
 
                /* calculate public key (if necessary) */
-               if (!eckey->pub_key)
+               if (EC_KEY_get0_public_key(eckey) == NULL)
                {
+                       const BIGNUM *priv_key;
+                       const EC_GROUP *group;
+                       EC_POINT *pub_key;
                        /* the public key was not included in the SEC1 private
                         * key => calculate the public key */
-                       eckey->pub_key = EC_POINT_new(eckey->group);
-                       if (!eckey->pub_key)
+                       group   = EC_KEY_get0_group(eckey);
+                       pub_key = EC_POINT_new(group);
+                       if (pub_key == NULL)
+                       {
+                               EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
+                               goto ecerr;
+                       }
+                       if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
                        {
+                               EC_POINT_free(pub_key);
                                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
                                goto ecerr;
                        }
-                       if (!EC_POINT_copy(eckey->pub_key, 
-                               EC_GROUP_get0_generator(eckey->group)))
+                       priv_key = EC_KEY_get0_private_key(eckey);
+                       if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
                        {
+                               EC_POINT_free(pub_key);
                                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
                                goto ecerr;
                        }
-                       if (!EC_POINT_mul(eckey->group, eckey->pub_key, 
-                               eckey->priv_key, NULL, NULL, ctx))
+                       if (EC_KEY_set_public_key(eckey, pub_key) == 0)
                        {
+                               EC_POINT_free(pub_key);
                                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
                                goto ecerr;
                        }
+                       EC_POINT_free(pub_key);
                }
 
                EVP_PKEY_assign_EC_KEY(pkey, eckey);
@@ -337,13 +356,17 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
        PKCS8_PRIV_KEY_INFO *p8;
 
        if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {        
-               EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+               EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
                return NULL;
        }
        p8->broken = broken;
-       ASN1_INTEGER_set (p8->version, 0);
+       if (!ASN1_INTEGER_set(p8->version, 0)) {
+               EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
+               PKCS8_PRIV_KEY_INFO_free (p8);
+               return NULL;
+       }
        if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
-               EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+               EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
                PKCS8_PRIV_KEY_INFO_free (p8);
                return NULL;
        }
@@ -356,9 +379,9 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
 
                p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
                p8->pkeyalg->parameter->type = V_ASN1_NULL;
-               if (!ASN1_pack_string ((char *)pkey, i2d_PrivateKey,
+               if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey,
                                         &p8->pkey->value.octet_string)) {
-                       EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
                        PKCS8_PRIV_KEY_INFO_free (p8);
                        return NULL;
                }
@@ -383,7 +406,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
                break;
 #endif
                default:
-               EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+               EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
                PKCS8_PRIV_KEY_INFO_free (p8);
                return NULL;
        }
@@ -408,39 +431,43 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
                break;
 
                default:
-               EVPerr(EVP_F_EVP_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
+               EVPerr(EVP_F_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
                return NULL;
-               break;
-               
        }
 }
 
 #ifndef OPENSSL_NO_DSA
 static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
 {
-       ASN1_STRING *params;
-       ASN1_INTEGER *prkey;
-       ASN1_TYPE *ttmp;
-       STACK_OF(ASN1_TYPE) *ndsa;
-       unsigned char *p, *q;
+       ASN1_STRING *params = NULL;
+       ASN1_INTEGER *prkey = NULL;
+       ASN1_TYPE *ttmp = NULL;
+       STACK_OF(ASN1_TYPE) *ndsa = NULL;
+       unsigned char *p = NULL, *q;
        int len;
 
        p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
        len = i2d_DSAparams (pkey->pkey.dsa, NULL);
        if (!(p = OPENSSL_malloc(len))) {
-               EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-               PKCS8_PRIV_KEY_INFO_free (p8);
-               return 0;
+               EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+               goto err;
        }
        q = p;
        i2d_DSAparams (pkey->pkey.dsa, &q);
-       params = ASN1_STRING_new();
-       ASN1_STRING_set(params, p, len);
+       if (!(params = ASN1_STRING_new())) {
+               EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+               goto err;
+       }
+       if (!ASN1_STRING_set(params, p, len)) {
+               EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+               goto err;
+       }
        OPENSSL_free(p);
+       p = NULL;
        /* Get private key into integer */
        if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
-               EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
-               return 0;
+               EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
+               goto err;
        }
 
        switch(p8->broken) {
@@ -448,15 +475,16 @@ static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
                case PKCS8_OK:
                case PKCS8_NO_OCTET:
 
-               if (!ASN1_pack_string((char *)prkey, i2d_ASN1_INTEGER,
+               if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
                                         &p8->pkey->value.octet_string)) {
-                       EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-                       M_ASN1_INTEGER_free (prkey);
-                       return 0;
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
                }
 
                M_ASN1_INTEGER_free (prkey);
+               prkey = NULL;
                p8->pkeyalg->parameter->value.sequence = params;
+               params = NULL;
                p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
 
                break;
@@ -464,32 +492,51 @@ static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
                case PKCS8_NS_DB:
 
                p8->pkeyalg->parameter->value.sequence = params;
+               params = NULL;
                p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
-               ndsa = sk_ASN1_TYPE_new_null();
-               ttmp = ASN1_TYPE_new();
-               if (!(ttmp->value.integer = BN_to_ASN1_INTEGER (pkey->pkey.dsa->pub_key, NULL))) {
-                       EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
-                       PKCS8_PRIV_KEY_INFO_free(p8);
-                       return 0;
+               if (!(ndsa = sk_ASN1_TYPE_new_null())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
+               if (!(ttmp = ASN1_TYPE_new())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
+               if (!(ttmp->value.integer =
+                       BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
+                       goto err;
                }
                ttmp->type = V_ASN1_INTEGER;
-               sk_ASN1_TYPE_push(ndsa, ttmp);
+               if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
 
-               ttmp = ASN1_TYPE_new();
+               if (!(ttmp = ASN1_TYPE_new())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
                ttmp->value.integer = prkey;
+               prkey = NULL;
                ttmp->type = V_ASN1_INTEGER;
-               sk_ASN1_TYPE_push(ndsa, ttmp);
+               if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
+               ttmp = NULL;
 
-               p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
+               if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
 
                if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
                                         &p8->pkey->value.octet_string->data,
                                         &p8->pkey->value.octet_string->length)) {
 
-                       EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-                       sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-                       M_ASN1_INTEGER_free(prkey);
-                       return 0;
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
                }
                sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
                break;
@@ -497,49 +544,76 @@ static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
                case PKCS8_EMBEDDED_PARAM:
 
                p8->pkeyalg->parameter->type = V_ASN1_NULL;
-               ndsa = sk_ASN1_TYPE_new_null();
-               ttmp = ASN1_TYPE_new();
+               if (!(ndsa = sk_ASN1_TYPE_new_null())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
+               if (!(ttmp = ASN1_TYPE_new())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
                ttmp->value.sequence = params;
+               params = NULL;
                ttmp->type = V_ASN1_SEQUENCE;
-               sk_ASN1_TYPE_push(ndsa, ttmp);
+               if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
 
-               ttmp = ASN1_TYPE_new();
+               if (!(ttmp = ASN1_TYPE_new())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
                ttmp->value.integer = prkey;
+               prkey = NULL;
                ttmp->type = V_ASN1_INTEGER;
-               sk_ASN1_TYPE_push(ndsa, ttmp);
+               if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
+               ttmp = NULL;
 
-               p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
+               if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
+               }
 
                if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
                                         &p8->pkey->value.octet_string->data,
                                         &p8->pkey->value.octet_string->length)) {
 
-                       EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-                       sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-                       M_ASN1_INTEGER_free (prkey);
-                       return 0;
+                       EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
+                       goto err;
                }
                sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
                break;
        }
        return 1;
+err:
+       if (p != NULL) OPENSSL_free(p);
+       if (params != NULL) ASN1_STRING_free(params);
+       if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
+       if (ttmp != NULL) ASN1_TYPE_free(ttmp);
+       if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+       return 0;
 }
 #endif
 
 #ifndef OPENSSL_NO_EC
 static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
 {
-       EC_KEY          *eckey;
+       EC_KEY          *ec_key;
+       const EC_GROUP  *group;
        unsigned char   *p, *pp;
        int             nid, i, ret = 0;
-       unsigned int    tmp_flags;
+       unsigned int    tmp_flags, old_flags;
 
-       if (pkey->pkey.eckey == NULL || pkey->pkey.eckey->group == NULL)
+       ec_key = pkey->pkey.ec;
+       if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
        {
-               EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
+               EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
                return 0;
        }
-       eckey = pkey->pkey.eckey;
 
        /* set the ec parameters OID */
        if (p8->pkeyalg->algorithm)
@@ -557,12 +631,12 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
 
        if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
        {
-               EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+               EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
                return 0;
        }
        
-       if (EC_GROUP_get_asn1_flag(eckey->group)
-                     && (nid = EC_GROUP_get_nid(eckey->group)))
+       if (EC_GROUP_get_asn1_flag(group)
+                     && (nid = EC_GROUP_get_curve_name(group)))
        {
                /* we have a 'named curve' => just set the OID */
                p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
@@ -570,20 +644,20 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
        }
        else    /* explicit parameters */
        {
-               if ((i = i2d_ECParameters(eckey, NULL)) == 0)
+               if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
                {
-                       EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_EC_LIB);
+                       EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
                        return 0;
                }
                if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
                {
-                       EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+                       EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
                        return 0;
                }       
                pp = p;
-               if (!i2d_ECParameters(eckey, &pp))
+               if (!i2d_ECParameters(ec_key, &pp))
                {
-                       EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_EC_LIB);
+                       EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
                        OPENSSL_free(p);
                        return 0;
                }
@@ -591,7 +665,7 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
                if ((p8->pkeyalg->parameter->value.sequence 
                        = ASN1_STRING_new()) == NULL)
                {
-                       EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
+                       EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
                        OPENSSL_free(p);
                        return 0;
                }
@@ -603,32 +677,33 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
 
        /* do not include the parameters in the SEC1 private key
         * see PKCS#11 12.11 */
-       tmp_flags  = pkey->pkey.eckey->enc_flag;
-       pkey->pkey.eckey->enc_flag |= EC_PKEY_NO_PARAMETERS;
-       i = i2d_ECPrivateKey(pkey->pkey.eckey, NULL);
+       old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
+       tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
+       EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
+       i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
        if (!i)
        {
-               pkey->pkey.eckey->enc_flag = tmp_flags;
-               EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_EC_LIB);
+               EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
+               EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
                return 0;
        }
        p = (unsigned char *) OPENSSL_malloc(i);
        if (!p)
        {
-               pkey->pkey.eckey->enc_flag = tmp_flags;
-               EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+               EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
+               EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
                return 0;
        }
        pp = p;
-       if (!i2d_ECPrivateKey(pkey->pkey.eckey, &pp))
+       if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
        {
-               pkey->pkey.eckey->enc_flag = tmp_flags;
-               EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_EC_LIB);
+               EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
+               EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
                OPENSSL_free(p);
                return 0;
        }
        /* restore old encoding flags */
-       pkey->pkey.eckey->enc_flag = tmp_flags;
+       EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
 
        switch(p8->broken) {
 
@@ -639,7 +714,7 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
                    (const void *)p, i))
 
                {
-                       EVPerr(EVP_F_EC_KEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+                       EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
                }
                else
                        ret = 1;
@@ -648,10 +723,72 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
                case PKCS8_NS_DB:               /* DSA specific */
                case PKCS8_EMBEDDED_PARAM:      /* DSA specific */
                default:
-                       EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
+                       EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
        }
        OPENSSL_cleanse(p, (size_t)i);
        OPENSSL_free(p);
        return ret;
 }
 #endif
+
+/* EVP_PKEY attribute functions */
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
+{
+       return X509at_get_attr_count(key->attributes);
+}
+
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
+                         int lastpos)
+{
+       return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+}
+
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+                         int lastpos)
+{
+       return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
+{
+       return X509at_get_attr(key->attributes, loc);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
+{
+       return X509at_delete_attr(key->attributes, loc);
+}
+
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
+{
+       if(X509at_add1_attr(&key->attributes, attr)) return 1;
+       return 0;
+}
+
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+                       const ASN1_OBJECT *obj, int type,
+                       const unsigned char *bytes, int len)
+{
+       if(X509at_add1_attr_by_OBJ(&key->attributes, obj,
+                               type, bytes, len)) return 1;
+       return 0;
+}
+
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+                       int nid, int type,
+                       const unsigned char *bytes, int len)
+{
+       if(X509at_add1_attr_by_NID(&key->attributes, nid,
+                               type, bytes, len)) return 1;
+       return 0;
+}
+
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+                       const char *attrname, int type,
+                       const unsigned char *bytes, int len)
+{
+       if(X509at_add1_attr_by_txt(&key->attributes, attrname,
+                               type, bytes, len)) return 1;
+       return 0;
+}