xref: /onnv-gate/usr/src/common/openssl/crypto/evp/evp_pkey.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* evp_pkey.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate  * project 1999.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate /* ====================================================================
6*2139Sjp161948  * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate  * are met:
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
180Sstevel@tonic-gate  *    distribution.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate  *    software must display the following acknowledgment:
220Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate  *    endorse or promote products derived from this software without
270Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
280Sstevel@tonic-gate  *    licensing@OpenSSL.org.
290Sstevel@tonic-gate  *
300Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate  *    permission of the OpenSSL Project.
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate  *    acknowledgment:
360Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate  * ====================================================================
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
550Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <stdlib.h>
610Sstevel@tonic-gate #include "cryptlib.h"
620Sstevel@tonic-gate #include <openssl/x509.h>
630Sstevel@tonic-gate #include <openssl/rand.h>
64*2139Sjp161948 #ifndef OPENSSL_NO_RSA
65*2139Sjp161948 #include <openssl/rsa.h>
66*2139Sjp161948 #endif
67*2139Sjp161948 #ifndef OPENSSL_NO_DSA
68*2139Sjp161948 #include <openssl/dsa.h>
69*2139Sjp161948 #endif
70*2139Sjp161948 #include <openssl/bn.h>
710Sstevel@tonic-gate 
720Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
730Sstevel@tonic-gate static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
740Sstevel@tonic-gate #endif
75*2139Sjp161948 #ifndef OPENSSL_NO_EC
76*2139Sjp161948 static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
77*2139Sjp161948 #endif
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /* Extract a private key from a PKCS8 structure */
800Sstevel@tonic-gate 
EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO * p8)81*2139Sjp161948 EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	EVP_PKEY *pkey = NULL;
840Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
850Sstevel@tonic-gate 	RSA *rsa = NULL;
860Sstevel@tonic-gate #endif
870Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
880Sstevel@tonic-gate 	DSA *dsa = NULL;
89*2139Sjp161948 	ASN1_TYPE *t1, *t2;
900Sstevel@tonic-gate 	ASN1_INTEGER *privkey;
910Sstevel@tonic-gate 	STACK_OF(ASN1_TYPE) *ndsa = NULL;
92*2139Sjp161948 #endif
93*2139Sjp161948 #ifndef OPENSSL_NO_EC
94*2139Sjp161948 	EC_KEY *eckey = NULL;
95*2139Sjp161948 	const unsigned char *p_tmp;
96*2139Sjp161948 #endif
97*2139Sjp161948 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
98*2139Sjp161948 	ASN1_TYPE    *param = NULL;
990Sstevel@tonic-gate 	BN_CTX *ctx = NULL;
1000Sstevel@tonic-gate 	int plen;
1010Sstevel@tonic-gate #endif
1020Sstevel@tonic-gate 	X509_ALGOR *a;
103*2139Sjp161948 	const unsigned char *p;
1040Sstevel@tonic-gate 	const unsigned char *cp;
1050Sstevel@tonic-gate 	int pkeylen;
106*2139Sjp161948 	int  nid;
1070Sstevel@tonic-gate 	char obj_tmp[80];
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	if(p8->pkey->type == V_ASN1_OCTET_STRING) {
1100Sstevel@tonic-gate 		p8->broken = PKCS8_OK;
1110Sstevel@tonic-gate 		p = p8->pkey->value.octet_string->data;
1120Sstevel@tonic-gate 		pkeylen = p8->pkey->value.octet_string->length;
1130Sstevel@tonic-gate 	} else {
1140Sstevel@tonic-gate 		p8->broken = PKCS8_NO_OCTET;
1150Sstevel@tonic-gate 		p = p8->pkey->value.sequence->data;
1160Sstevel@tonic-gate 		pkeylen = p8->pkey->value.sequence->length;
1170Sstevel@tonic-gate 	}
1180Sstevel@tonic-gate 	if (!(pkey = EVP_PKEY_new())) {
1190Sstevel@tonic-gate 		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
1200Sstevel@tonic-gate 		return NULL;
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate 	a = p8->pkeyalg;
123*2139Sjp161948 	nid = OBJ_obj2nid(a->algorithm);
124*2139Sjp161948 	switch(nid)
1250Sstevel@tonic-gate 	{
1260Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1270Sstevel@tonic-gate 		case NID_rsaEncryption:
1280Sstevel@tonic-gate 		cp = p;
1290Sstevel@tonic-gate 		if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
1300Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1310Sstevel@tonic-gate 			return NULL;
1320Sstevel@tonic-gate 		}
1330Sstevel@tonic-gate 		EVP_PKEY_assign_RSA (pkey, rsa);
1340Sstevel@tonic-gate 		break;
1350Sstevel@tonic-gate #endif
1360Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
1370Sstevel@tonic-gate 		case NID_dsa:
1380Sstevel@tonic-gate 		/* PKCS#8 DSA is weird: you just get a private key integer
1390Sstevel@tonic-gate 	         * and parameters in the AlgorithmIdentifier the pubkey must
1400Sstevel@tonic-gate 		 * be recalculated.
1410Sstevel@tonic-gate 		 */
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 		/* Check for broken DSA PKCS#8, UGH! */
1440Sstevel@tonic-gate 		if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
1450Sstevel@tonic-gate 		    if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
1460Sstevel@tonic-gate 							  d2i_ASN1_TYPE,
1470Sstevel@tonic-gate 							  ASN1_TYPE_free))) {
1480Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1490Sstevel@tonic-gate 			goto dsaerr;
1500Sstevel@tonic-gate 		    }
1510Sstevel@tonic-gate 		    if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
1520Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1530Sstevel@tonic-gate 			goto dsaerr;
1540Sstevel@tonic-gate 		    }
1550Sstevel@tonic-gate 		    /* Handle Two broken types:
1560Sstevel@tonic-gate 		     * SEQUENCE {parameters, priv_key}
1570Sstevel@tonic-gate 		     * SEQUENCE {pub_key, priv_key}
1580Sstevel@tonic-gate 		     */
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 		    t1 = sk_ASN1_TYPE_value(ndsa, 0);
1610Sstevel@tonic-gate 		    t2 = sk_ASN1_TYPE_value(ndsa, 1);
1620Sstevel@tonic-gate 		    if(t1->type == V_ASN1_SEQUENCE) {
1630Sstevel@tonic-gate 			p8->broken = PKCS8_EMBEDDED_PARAM;
1640Sstevel@tonic-gate 			param = t1;
1650Sstevel@tonic-gate 		    } else if(a->parameter->type == V_ASN1_SEQUENCE) {
1660Sstevel@tonic-gate 			p8->broken = PKCS8_NS_DB;
1670Sstevel@tonic-gate 			param = a->parameter;
1680Sstevel@tonic-gate 		    } else {
1690Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1700Sstevel@tonic-gate 			goto dsaerr;
1710Sstevel@tonic-gate 		    }
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 		    if(t2->type != V_ASN1_INTEGER) {
1740Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1750Sstevel@tonic-gate 			goto dsaerr;
1760Sstevel@tonic-gate 		    }
1770Sstevel@tonic-gate 		    privkey = t2->value.integer;
1780Sstevel@tonic-gate 		} else {
1790Sstevel@tonic-gate 			if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
1800Sstevel@tonic-gate 				EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1810Sstevel@tonic-gate 				goto dsaerr;
1820Sstevel@tonic-gate 			}
1830Sstevel@tonic-gate 			param = p8->pkeyalg->parameter;
1840Sstevel@tonic-gate 		}
1850Sstevel@tonic-gate 		if (!param || (param->type != V_ASN1_SEQUENCE)) {
1860Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1870Sstevel@tonic-gate 			goto dsaerr;
1880Sstevel@tonic-gate 		}
1890Sstevel@tonic-gate 		cp = p = param->value.sequence->data;
1900Sstevel@tonic-gate 		plen = param->value.sequence->length;
1910Sstevel@tonic-gate 		if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
1920Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
1930Sstevel@tonic-gate 			goto dsaerr;
1940Sstevel@tonic-gate 		}
1950Sstevel@tonic-gate 		/* We have parameters now set private key */
1960Sstevel@tonic-gate 		if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
1970Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
1980Sstevel@tonic-gate 			goto dsaerr;
1990Sstevel@tonic-gate 		}
2000Sstevel@tonic-gate 		/* Calculate public key (ouch!) */
2010Sstevel@tonic-gate 		if (!(dsa->pub_key = BN_new())) {
2020Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
2030Sstevel@tonic-gate 			goto dsaerr;
2040Sstevel@tonic-gate 		}
2050Sstevel@tonic-gate 		if (!(ctx = BN_CTX_new())) {
2060Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
2070Sstevel@tonic-gate 			goto dsaerr;
2080Sstevel@tonic-gate 		}
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 		if (!BN_mod_exp(dsa->pub_key, dsa->g,
2110Sstevel@tonic-gate 						 dsa->priv_key, dsa->p, ctx)) {
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
2140Sstevel@tonic-gate 			goto dsaerr;
2150Sstevel@tonic-gate 		}
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 		EVP_PKEY_assign_DSA(pkey, dsa);
2180Sstevel@tonic-gate 		BN_CTX_free (ctx);
2190Sstevel@tonic-gate 		if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
2200Sstevel@tonic-gate 		else ASN1_INTEGER_free(privkey);
2210Sstevel@tonic-gate 		break;
2220Sstevel@tonic-gate 		dsaerr:
2230Sstevel@tonic-gate 		BN_CTX_free (ctx);
2240Sstevel@tonic-gate 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
2250Sstevel@tonic-gate 		DSA_free(dsa);
2260Sstevel@tonic-gate 		EVP_PKEY_free(pkey);
2270Sstevel@tonic-gate 		return NULL;
2280Sstevel@tonic-gate 		break;
2290Sstevel@tonic-gate #endif
230*2139Sjp161948 #ifndef OPENSSL_NO_EC
231*2139Sjp161948 		case NID_X9_62_id_ecPublicKey:
232*2139Sjp161948 		p_tmp = p;
233*2139Sjp161948 		/* extract the ec parameters */
234*2139Sjp161948 		param = p8->pkeyalg->parameter;
235*2139Sjp161948 
236*2139Sjp161948 		if (!param || ((param->type != V_ASN1_SEQUENCE) &&
237*2139Sjp161948 		    (param->type != V_ASN1_OBJECT)))
238*2139Sjp161948 		{
239*2139Sjp161948 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
240*2139Sjp161948 			goto ecerr;
241*2139Sjp161948 		}
242*2139Sjp161948 
243*2139Sjp161948 		if (param->type == V_ASN1_SEQUENCE)
244*2139Sjp161948 		{
245*2139Sjp161948 			cp = p = param->value.sequence->data;
246*2139Sjp161948 			plen = param->value.sequence->length;
247*2139Sjp161948 
248*2139Sjp161948 			if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
249*2139Sjp161948 			{
250*2139Sjp161948 				EVPerr(EVP_F_EVP_PKCS82PKEY,
251*2139Sjp161948 					EVP_R_DECODE_ERROR);
252*2139Sjp161948 				goto ecerr;
253*2139Sjp161948 			}
254*2139Sjp161948 		}
255*2139Sjp161948 		else
256*2139Sjp161948 		{
257*2139Sjp161948 			EC_GROUP *group;
258*2139Sjp161948 			cp = p = param->value.object->data;
259*2139Sjp161948 			plen = param->value.object->length;
260*2139Sjp161948 
261*2139Sjp161948 			/* type == V_ASN1_OBJECT => the parameters are given
262*2139Sjp161948 			 * by an asn1 OID
263*2139Sjp161948 			 */
264*2139Sjp161948 			if ((eckey = EC_KEY_new()) == NULL)
265*2139Sjp161948 			{
266*2139Sjp161948 				EVPerr(EVP_F_EVP_PKCS82PKEY,
267*2139Sjp161948 					ERR_R_MALLOC_FAILURE);
268*2139Sjp161948 				goto ecerr;
269*2139Sjp161948 			}
270*2139Sjp161948 			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
271*2139Sjp161948 			if (group == NULL)
272*2139Sjp161948 				goto ecerr;
273*2139Sjp161948 			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
274*2139Sjp161948 			if (EC_KEY_set_group(eckey, group) == 0)
275*2139Sjp161948 				goto ecerr;
276*2139Sjp161948 			EC_GROUP_free(group);
277*2139Sjp161948 		}
278*2139Sjp161948 
279*2139Sjp161948 		/* We have parameters now set private key */
280*2139Sjp161948 		if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
281*2139Sjp161948 		{
282*2139Sjp161948 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
283*2139Sjp161948 			goto ecerr;
284*2139Sjp161948 		}
285*2139Sjp161948 
286*2139Sjp161948 		/* calculate public key (if necessary) */
287*2139Sjp161948 		if (EC_KEY_get0_public_key(eckey) == NULL)
288*2139Sjp161948 		{
289*2139Sjp161948 			const BIGNUM *priv_key;
290*2139Sjp161948 			const EC_GROUP *group;
291*2139Sjp161948 			EC_POINT *pub_key;
292*2139Sjp161948 			/* the public key was not included in the SEC1 private
293*2139Sjp161948 			 * key => calculate the public key */
294*2139Sjp161948 			group   = EC_KEY_get0_group(eckey);
295*2139Sjp161948 			pub_key = EC_POINT_new(group);
296*2139Sjp161948 			if (pub_key == NULL)
297*2139Sjp161948 			{
298*2139Sjp161948 				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
299*2139Sjp161948 				goto ecerr;
300*2139Sjp161948 			}
301*2139Sjp161948 			if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
302*2139Sjp161948 			{
303*2139Sjp161948 				EC_POINT_free(pub_key);
304*2139Sjp161948 				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
305*2139Sjp161948 				goto ecerr;
306*2139Sjp161948 			}
307*2139Sjp161948 			priv_key = EC_KEY_get0_private_key(eckey);
308*2139Sjp161948 			if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
309*2139Sjp161948 			{
310*2139Sjp161948 				EC_POINT_free(pub_key);
311*2139Sjp161948 				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
312*2139Sjp161948 				goto ecerr;
313*2139Sjp161948 			}
314*2139Sjp161948 			if (EC_KEY_set_public_key(eckey, pub_key) == 0)
315*2139Sjp161948 			{
316*2139Sjp161948 				EC_POINT_free(pub_key);
317*2139Sjp161948 				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
318*2139Sjp161948 				goto ecerr;
319*2139Sjp161948 			}
320*2139Sjp161948 			EC_POINT_free(pub_key);
321*2139Sjp161948 		}
322*2139Sjp161948 
323*2139Sjp161948 		EVP_PKEY_assign_EC_KEY(pkey, eckey);
324*2139Sjp161948 		if (ctx)
325*2139Sjp161948 			BN_CTX_free(ctx);
326*2139Sjp161948 		break;
327*2139Sjp161948 ecerr:
328*2139Sjp161948 		if (ctx)
329*2139Sjp161948 			BN_CTX_free(ctx);
330*2139Sjp161948 		if (eckey)
331*2139Sjp161948 			EC_KEY_free(eckey);
332*2139Sjp161948 		if (pkey)
333*2139Sjp161948 			EVP_PKEY_free(pkey);
334*2139Sjp161948 		return NULL;
335*2139Sjp161948 #endif
3360Sstevel@tonic-gate 		default:
3370Sstevel@tonic-gate 		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
3380Sstevel@tonic-gate 		if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
3390Sstevel@tonic-gate 		else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
3400Sstevel@tonic-gate 		ERR_add_error_data(2, "TYPE=", obj_tmp);
3410Sstevel@tonic-gate 		EVP_PKEY_free (pkey);
3420Sstevel@tonic-gate 		return NULL;
3430Sstevel@tonic-gate 	}
3440Sstevel@tonic-gate 	return pkey;
3450Sstevel@tonic-gate }
3460Sstevel@tonic-gate 
EVP_PKEY2PKCS8(EVP_PKEY * pkey)3470Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate 	return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate /* Turn a private key into a PKCS8 structure */
3530Sstevel@tonic-gate 
EVP_PKEY2PKCS8_broken(EVP_PKEY * pkey,int broken)3540Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
3550Sstevel@tonic-gate {
3560Sstevel@tonic-gate 	PKCS8_PRIV_KEY_INFO *p8;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
359*2139Sjp161948 		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
3600Sstevel@tonic-gate 		return NULL;
3610Sstevel@tonic-gate 	}
3620Sstevel@tonic-gate 	p8->broken = broken;
363*2139Sjp161948 	if (!ASN1_INTEGER_set(p8->version, 0)) {
364*2139Sjp161948 		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
365*2139Sjp161948 		PKCS8_PRIV_KEY_INFO_free (p8);
366*2139Sjp161948 		return NULL;
367*2139Sjp161948 	}
3680Sstevel@tonic-gate 	if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
369*2139Sjp161948 		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
3700Sstevel@tonic-gate 		PKCS8_PRIV_KEY_INFO_free (p8);
3710Sstevel@tonic-gate 		return NULL;
3720Sstevel@tonic-gate 	}
3730Sstevel@tonic-gate 	p8->pkey->type = V_ASN1_OCTET_STRING;
3740Sstevel@tonic-gate 	switch (EVP_PKEY_type(pkey->type)) {
3750Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
3760Sstevel@tonic-gate 		case EVP_PKEY_RSA:
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 		if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 		p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
3810Sstevel@tonic-gate 		p8->pkeyalg->parameter->type = V_ASN1_NULL;
382*2139Sjp161948 		if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey,
3830Sstevel@tonic-gate 					 &p8->pkey->value.octet_string)) {
384*2139Sjp161948 			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
3850Sstevel@tonic-gate 			PKCS8_PRIV_KEY_INFO_free (p8);
3860Sstevel@tonic-gate 			return NULL;
3870Sstevel@tonic-gate 		}
3880Sstevel@tonic-gate 		break;
3890Sstevel@tonic-gate #endif
3900Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
3910Sstevel@tonic-gate 		case EVP_PKEY_DSA:
3920Sstevel@tonic-gate 		if(!dsa_pkey2pkcs8(p8, pkey)) {
3930Sstevel@tonic-gate 			PKCS8_PRIV_KEY_INFO_free (p8);
3940Sstevel@tonic-gate 			return NULL;
3950Sstevel@tonic-gate 		}
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 		break;
3980Sstevel@tonic-gate #endif
399*2139Sjp161948 #ifndef OPENSSL_NO_EC
400*2139Sjp161948 		case EVP_PKEY_EC:
401*2139Sjp161948 		if (!eckey_pkey2pkcs8(p8, pkey))
402*2139Sjp161948 		{
403*2139Sjp161948 			PKCS8_PRIV_KEY_INFO_free(p8);
404*2139Sjp161948 			return(NULL);
405*2139Sjp161948 		}
406*2139Sjp161948 		break;
407*2139Sjp161948 #endif
4080Sstevel@tonic-gate 		default:
409*2139Sjp161948 		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
4100Sstevel@tonic-gate 		PKCS8_PRIV_KEY_INFO_free (p8);
4110Sstevel@tonic-gate 		return NULL;
4120Sstevel@tonic-gate 	}
4130Sstevel@tonic-gate 	RAND_add(p8->pkey->value.octet_string->data,
414*2139Sjp161948 		 p8->pkey->value.octet_string->length, 0.0);
4150Sstevel@tonic-gate 	return p8;
4160Sstevel@tonic-gate }
4170Sstevel@tonic-gate 
PKCS8_set_broken(PKCS8_PRIV_KEY_INFO * p8,int broken)4180Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
4190Sstevel@tonic-gate {
4200Sstevel@tonic-gate 	switch (broken) {
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 		case PKCS8_OK:
4230Sstevel@tonic-gate 		p8->broken = PKCS8_OK;
4240Sstevel@tonic-gate 		return p8;
4250Sstevel@tonic-gate 		break;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 		case PKCS8_NO_OCTET:
4280Sstevel@tonic-gate 		p8->broken = PKCS8_NO_OCTET;
4290Sstevel@tonic-gate 		p8->pkey->type = V_ASN1_SEQUENCE;
4300Sstevel@tonic-gate 		return p8;
4310Sstevel@tonic-gate 		break;
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 		default:
434*2139Sjp161948 		EVPerr(EVP_F_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
4350Sstevel@tonic-gate 		return NULL;
4360Sstevel@tonic-gate 	}
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO * p8,EVP_PKEY * pkey)4400Sstevel@tonic-gate static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
4410Sstevel@tonic-gate {
442*2139Sjp161948 	ASN1_STRING *params = NULL;
443*2139Sjp161948 	ASN1_INTEGER *prkey = NULL;
444*2139Sjp161948 	ASN1_TYPE *ttmp = NULL;
445*2139Sjp161948 	STACK_OF(ASN1_TYPE) *ndsa = NULL;
446*2139Sjp161948 	unsigned char *p = NULL, *q;
4470Sstevel@tonic-gate 	int len;
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
4500Sstevel@tonic-gate 	len = i2d_DSAparams (pkey->pkey.dsa, NULL);
4510Sstevel@tonic-gate 	if (!(p = OPENSSL_malloc(len))) {
452*2139Sjp161948 		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
453*2139Sjp161948 		goto err;
4540Sstevel@tonic-gate 	}
4550Sstevel@tonic-gate 	q = p;
4560Sstevel@tonic-gate 	i2d_DSAparams (pkey->pkey.dsa, &q);
457*2139Sjp161948 	if (!(params = ASN1_STRING_new())) {
458*2139Sjp161948 		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
459*2139Sjp161948 		goto err;
460*2139Sjp161948 	}
461*2139Sjp161948 	if (!ASN1_STRING_set(params, p, len)) {
462*2139Sjp161948 		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
463*2139Sjp161948 		goto err;
464*2139Sjp161948 	}
4650Sstevel@tonic-gate 	OPENSSL_free(p);
466*2139Sjp161948 	p = NULL;
4670Sstevel@tonic-gate 	/* Get private key into integer */
4680Sstevel@tonic-gate 	if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
469*2139Sjp161948 		EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
470*2139Sjp161948 		goto err;
4710Sstevel@tonic-gate 	}
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate 	switch(p8->broken) {
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate 		case PKCS8_OK:
4760Sstevel@tonic-gate 		case PKCS8_NO_OCTET:
4770Sstevel@tonic-gate 
478*2139Sjp161948 		if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
4790Sstevel@tonic-gate 					 &p8->pkey->value.octet_string)) {
480*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
481*2139Sjp161948 			goto err;
4820Sstevel@tonic-gate 		}
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate 		M_ASN1_INTEGER_free (prkey);
485*2139Sjp161948 		prkey = NULL;
4860Sstevel@tonic-gate 		p8->pkeyalg->parameter->value.sequence = params;
487*2139Sjp161948 		params = NULL;
4880Sstevel@tonic-gate 		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 		break;
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 		case PKCS8_NS_DB:
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 		p8->pkeyalg->parameter->value.sequence = params;
495*2139Sjp161948 		params = NULL;
4960Sstevel@tonic-gate 		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
497*2139Sjp161948 		if (!(ndsa = sk_ASN1_TYPE_new_null())) {
498*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
499*2139Sjp161948 			goto err;
500*2139Sjp161948 		}
501*2139Sjp161948 		if (!(ttmp = ASN1_TYPE_new())) {
502*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
503*2139Sjp161948 			goto err;
504*2139Sjp161948 		}
505*2139Sjp161948 		if (!(ttmp->value.integer =
506*2139Sjp161948 			BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
507*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
508*2139Sjp161948 			goto err;
5090Sstevel@tonic-gate 		}
5100Sstevel@tonic-gate 		ttmp->type = V_ASN1_INTEGER;
511*2139Sjp161948 		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
512*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
513*2139Sjp161948 			goto err;
514*2139Sjp161948 		}
5150Sstevel@tonic-gate 
516*2139Sjp161948 		if (!(ttmp = ASN1_TYPE_new())) {
517*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
518*2139Sjp161948 			goto err;
519*2139Sjp161948 		}
5200Sstevel@tonic-gate 		ttmp->value.integer = prkey;
521*2139Sjp161948 		prkey = NULL;
5220Sstevel@tonic-gate 		ttmp->type = V_ASN1_INTEGER;
523*2139Sjp161948 		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
524*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
525*2139Sjp161948 			goto err;
526*2139Sjp161948 		}
527*2139Sjp161948 		ttmp = NULL;
5280Sstevel@tonic-gate 
529*2139Sjp161948 		if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
530*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
531*2139Sjp161948 			goto err;
532*2139Sjp161948 		}
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
5350Sstevel@tonic-gate 					 &p8->pkey->value.octet_string->data,
5360Sstevel@tonic-gate 					 &p8->pkey->value.octet_string->length)) {
5370Sstevel@tonic-gate 
538*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
539*2139Sjp161948 			goto err;
5400Sstevel@tonic-gate 		}
5410Sstevel@tonic-gate 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
5420Sstevel@tonic-gate 		break;
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate 		case PKCS8_EMBEDDED_PARAM:
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate 		p8->pkeyalg->parameter->type = V_ASN1_NULL;
547*2139Sjp161948 		if (!(ndsa = sk_ASN1_TYPE_new_null())) {
548*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
549*2139Sjp161948 			goto err;
550*2139Sjp161948 		}
551*2139Sjp161948 		if (!(ttmp = ASN1_TYPE_new())) {
552*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
553*2139Sjp161948 			goto err;
554*2139Sjp161948 		}
5550Sstevel@tonic-gate 		ttmp->value.sequence = params;
556*2139Sjp161948 		params = NULL;
5570Sstevel@tonic-gate 		ttmp->type = V_ASN1_SEQUENCE;
558*2139Sjp161948 		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
559*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
560*2139Sjp161948 			goto err;
561*2139Sjp161948 		}
5620Sstevel@tonic-gate 
563*2139Sjp161948 		if (!(ttmp = ASN1_TYPE_new())) {
564*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
565*2139Sjp161948 			goto err;
566*2139Sjp161948 		}
5670Sstevel@tonic-gate 		ttmp->value.integer = prkey;
568*2139Sjp161948 		prkey = NULL;
5690Sstevel@tonic-gate 		ttmp->type = V_ASN1_INTEGER;
570*2139Sjp161948 		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
571*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
572*2139Sjp161948 			goto err;
573*2139Sjp161948 		}
574*2139Sjp161948 		ttmp = NULL;
5750Sstevel@tonic-gate 
576*2139Sjp161948 		if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
577*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
578*2139Sjp161948 			goto err;
579*2139Sjp161948 		}
5800Sstevel@tonic-gate 
5810Sstevel@tonic-gate 		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
5820Sstevel@tonic-gate 					 &p8->pkey->value.octet_string->data,
5830Sstevel@tonic-gate 					 &p8->pkey->value.octet_string->length)) {
5840Sstevel@tonic-gate 
585*2139Sjp161948 			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
586*2139Sjp161948 			goto err;
5870Sstevel@tonic-gate 		}
5880Sstevel@tonic-gate 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
5890Sstevel@tonic-gate 		break;
5900Sstevel@tonic-gate 	}
5910Sstevel@tonic-gate 	return 1;
592*2139Sjp161948 err:
593*2139Sjp161948 	if (p != NULL) OPENSSL_free(p);
594*2139Sjp161948 	if (params != NULL) ASN1_STRING_free(params);
595*2139Sjp161948 	if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
596*2139Sjp161948 	if (ttmp != NULL) ASN1_TYPE_free(ttmp);
597*2139Sjp161948 	if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
598*2139Sjp161948 	return 0;
5990Sstevel@tonic-gate }
6000Sstevel@tonic-gate #endif
601*2139Sjp161948 
602*2139Sjp161948 #ifndef OPENSSL_NO_EC
eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO * p8,EVP_PKEY * pkey)603*2139Sjp161948 static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
604*2139Sjp161948 {
605*2139Sjp161948 	EC_KEY		*ec_key;
606*2139Sjp161948 	const EC_GROUP  *group;
607*2139Sjp161948 	unsigned char	*p, *pp;
608*2139Sjp161948 	int 		nid, i, ret = 0;
609*2139Sjp161948 	unsigned int    tmp_flags, old_flags;
610*2139Sjp161948 
611*2139Sjp161948 	ec_key = pkey->pkey.ec;
612*2139Sjp161948 	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
613*2139Sjp161948 	{
614*2139Sjp161948 		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
615*2139Sjp161948 		return 0;
616*2139Sjp161948 	}
617*2139Sjp161948 
618*2139Sjp161948 	/* set the ec parameters OID */
619*2139Sjp161948 	if (p8->pkeyalg->algorithm)
620*2139Sjp161948 		ASN1_OBJECT_free(p8->pkeyalg->algorithm);
621*2139Sjp161948 
622*2139Sjp161948 	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
623*2139Sjp161948 
624*2139Sjp161948 	/* set the ec parameters */
625*2139Sjp161948 
626*2139Sjp161948 	if (p8->pkeyalg->parameter)
627*2139Sjp161948 	{
628*2139Sjp161948 		ASN1_TYPE_free(p8->pkeyalg->parameter);
629*2139Sjp161948 		p8->pkeyalg->parameter = NULL;
630*2139Sjp161948 	}
631*2139Sjp161948 
632*2139Sjp161948 	if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
633*2139Sjp161948 	{
634*2139Sjp161948 		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
635*2139Sjp161948 		return 0;
636*2139Sjp161948 	}
637*2139Sjp161948 
638*2139Sjp161948 	if (EC_GROUP_get_asn1_flag(group)
639*2139Sjp161948                      && (nid = EC_GROUP_get_curve_name(group)))
640*2139Sjp161948 	{
641*2139Sjp161948 		/* we have a 'named curve' => just set the OID */
642*2139Sjp161948 		p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
643*2139Sjp161948 		p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
644*2139Sjp161948 	}
645*2139Sjp161948 	else	/* explicit parameters */
646*2139Sjp161948 	{
647*2139Sjp161948 		if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
648*2139Sjp161948 		{
649*2139Sjp161948 			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
650*2139Sjp161948 			return 0;
651*2139Sjp161948 		}
652*2139Sjp161948 		if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
653*2139Sjp161948 		{
654*2139Sjp161948 			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
655*2139Sjp161948 			return 0;
656*2139Sjp161948 		}
657*2139Sjp161948 		pp = p;
658*2139Sjp161948 		if (!i2d_ECParameters(ec_key, &pp))
659*2139Sjp161948 		{
660*2139Sjp161948 			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
661*2139Sjp161948 			OPENSSL_free(p);
662*2139Sjp161948 			return 0;
663*2139Sjp161948 		}
664*2139Sjp161948 		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
665*2139Sjp161948 		if ((p8->pkeyalg->parameter->value.sequence
666*2139Sjp161948 			= ASN1_STRING_new()) == NULL)
667*2139Sjp161948 		{
668*2139Sjp161948 			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
669*2139Sjp161948 			OPENSSL_free(p);
670*2139Sjp161948 			return 0;
671*2139Sjp161948 		}
672*2139Sjp161948 		ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
673*2139Sjp161948 		OPENSSL_free(p);
674*2139Sjp161948 	}
675*2139Sjp161948 
676*2139Sjp161948 	/* set the private key */
677*2139Sjp161948 
678*2139Sjp161948 	/* do not include the parameters in the SEC1 private key
679*2139Sjp161948 	 * see PKCS#11 12.11 */
680*2139Sjp161948 	old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
681*2139Sjp161948 	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
682*2139Sjp161948 	EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
683*2139Sjp161948 	i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
684*2139Sjp161948 	if (!i)
685*2139Sjp161948 	{
686*2139Sjp161948 		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
687*2139Sjp161948 		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
688*2139Sjp161948 		return 0;
689*2139Sjp161948 	}
690*2139Sjp161948 	p = (unsigned char *) OPENSSL_malloc(i);
691*2139Sjp161948 	if (!p)
692*2139Sjp161948 	{
693*2139Sjp161948 		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
694*2139Sjp161948 		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
695*2139Sjp161948 		return 0;
696*2139Sjp161948 	}
697*2139Sjp161948 	pp = p;
698*2139Sjp161948 	if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
699*2139Sjp161948 	{
700*2139Sjp161948 		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
701*2139Sjp161948 		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
702*2139Sjp161948 		OPENSSL_free(p);
703*2139Sjp161948 		return 0;
704*2139Sjp161948 	}
705*2139Sjp161948 	/* restore old encoding flags */
706*2139Sjp161948 	EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
707*2139Sjp161948 
708*2139Sjp161948 	switch(p8->broken) {
709*2139Sjp161948 
710*2139Sjp161948 		case PKCS8_OK:
711*2139Sjp161948 		p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
712*2139Sjp161948 		if (!p8->pkey->value.octet_string ||
713*2139Sjp161948 		    !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
714*2139Sjp161948 		    (const void *)p, i))
715*2139Sjp161948 
716*2139Sjp161948 		{
717*2139Sjp161948 			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
718*2139Sjp161948 		}
719*2139Sjp161948 		else
720*2139Sjp161948 			ret = 1;
721*2139Sjp161948 		break;
722*2139Sjp161948 		case PKCS8_NO_OCTET:		/* RSA specific */
723*2139Sjp161948 		case PKCS8_NS_DB:		/* DSA specific */
724*2139Sjp161948 		case PKCS8_EMBEDDED_PARAM:	/* DSA specific */
725*2139Sjp161948 		default:
726*2139Sjp161948 			EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
727*2139Sjp161948 	}
728*2139Sjp161948 	OPENSSL_cleanse(p, (size_t)i);
729*2139Sjp161948 	OPENSSL_free(p);
730*2139Sjp161948 	return ret;
731*2139Sjp161948 }
732*2139Sjp161948 #endif
733*2139Sjp161948 
734*2139Sjp161948 /* EVP_PKEY attribute functions */
735*2139Sjp161948 
EVP_PKEY_get_attr_count(const EVP_PKEY * key)736*2139Sjp161948 int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
737*2139Sjp161948 {
738*2139Sjp161948 	return X509at_get_attr_count(key->attributes);
739*2139Sjp161948 }
740*2139Sjp161948 
EVP_PKEY_get_attr_by_NID(const EVP_PKEY * key,int nid,int lastpos)741*2139Sjp161948 int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
742*2139Sjp161948 			  int lastpos)
743*2139Sjp161948 {
744*2139Sjp161948 	return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
745*2139Sjp161948 }
746*2139Sjp161948 
EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY * key,ASN1_OBJECT * obj,int lastpos)747*2139Sjp161948 int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
748*2139Sjp161948 			  int lastpos)
749*2139Sjp161948 {
750*2139Sjp161948 	return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
751*2139Sjp161948 }
752*2139Sjp161948 
EVP_PKEY_get_attr(const EVP_PKEY * key,int loc)753*2139Sjp161948 X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
754*2139Sjp161948 {
755*2139Sjp161948 	return X509at_get_attr(key->attributes, loc);
756*2139Sjp161948 }
757*2139Sjp161948 
EVP_PKEY_delete_attr(EVP_PKEY * key,int loc)758*2139Sjp161948 X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
759*2139Sjp161948 {
760*2139Sjp161948 	return X509at_delete_attr(key->attributes, loc);
761*2139Sjp161948 }
762*2139Sjp161948 
EVP_PKEY_add1_attr(EVP_PKEY * key,X509_ATTRIBUTE * attr)763*2139Sjp161948 int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
764*2139Sjp161948 {
765*2139Sjp161948 	if(X509at_add1_attr(&key->attributes, attr)) return 1;
766*2139Sjp161948 	return 0;
767*2139Sjp161948 }
768*2139Sjp161948 
EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY * key,const ASN1_OBJECT * obj,int type,const unsigned char * bytes,int len)769*2139Sjp161948 int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
770*2139Sjp161948 			const ASN1_OBJECT *obj, int type,
771*2139Sjp161948 			const unsigned char *bytes, int len)
772*2139Sjp161948 {
773*2139Sjp161948 	if(X509at_add1_attr_by_OBJ(&key->attributes, obj,
774*2139Sjp161948 				type, bytes, len)) return 1;
775*2139Sjp161948 	return 0;
776*2139Sjp161948 }
777*2139Sjp161948 
EVP_PKEY_add1_attr_by_NID(EVP_PKEY * key,int nid,int type,const unsigned char * bytes,int len)778*2139Sjp161948 int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
779*2139Sjp161948 			int nid, int type,
780*2139Sjp161948 			const unsigned char *bytes, int len)
781*2139Sjp161948 {
782*2139Sjp161948 	if(X509at_add1_attr_by_NID(&key->attributes, nid,
783*2139Sjp161948 				type, bytes, len)) return 1;
784*2139Sjp161948 	return 0;
785*2139Sjp161948 }
786*2139Sjp161948 
EVP_PKEY_add1_attr_by_txt(EVP_PKEY * key,const char * attrname,int type,const unsigned char * bytes,int len)787*2139Sjp161948 int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
788*2139Sjp161948 			const char *attrname, int type,
789*2139Sjp161948 			const unsigned char *bytes, int len)
790*2139Sjp161948 {
791*2139Sjp161948 	if(X509at_add1_attr_by_txt(&key->attributes, attrname,
792*2139Sjp161948 				type, bytes, len)) return 1;
793*2139Sjp161948 	return 0;
794*2139Sjp161948 }
795