xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/x_pubkey.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/asn1/x_pubkey.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include "cryptlib.h"
610Sstevel@tonic-gate #include <openssl/asn1t.h>
620Sstevel@tonic-gate #include <openssl/x509.h>
63*2139Sjp161948 #ifndef OPENSSL_NO_RSA
64*2139Sjp161948 #include <openssl/rsa.h>
65*2139Sjp161948 #endif
66*2139Sjp161948 #ifndef OPENSSL_NO_DSA
67*2139Sjp161948 #include <openssl/dsa.h>
68*2139Sjp161948 #endif
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /* Minor tweak to operation: free up EVP_PKEY */
pubkey_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it)710Sstevel@tonic-gate static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
72*2139Sjp161948 	{
73*2139Sjp161948 	if (operation == ASN1_OP_FREE_POST)
74*2139Sjp161948 		{
750Sstevel@tonic-gate 		X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
760Sstevel@tonic-gate 		EVP_PKEY_free(pubkey->pkey);
77*2139Sjp161948 		}
780Sstevel@tonic-gate 	return 1;
79*2139Sjp161948 	}
800Sstevel@tonic-gate 
810Sstevel@tonic-gate ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
820Sstevel@tonic-gate 	ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
830Sstevel@tonic-gate 	ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
840Sstevel@tonic-gate } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
850Sstevel@tonic-gate 
860Sstevel@tonic-gate IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
870Sstevel@tonic-gate 
880Sstevel@tonic-gate int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
890Sstevel@tonic-gate 	{
90*2139Sjp161948 	X509_PUBKEY *pk=NULL;
910Sstevel@tonic-gate 	X509_ALGOR *a;
920Sstevel@tonic-gate 	ASN1_OBJECT *o;
930Sstevel@tonic-gate 	unsigned char *s,*p = NULL;
940Sstevel@tonic-gate 	int i;
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	if (x == NULL) return(0);
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
990Sstevel@tonic-gate 	a=pk->algor;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	/* set the algorithm id */
1020Sstevel@tonic-gate 	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
1030Sstevel@tonic-gate 	ASN1_OBJECT_free(a->algorithm);
1040Sstevel@tonic-gate 	a->algorithm=o;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	/* Set the parameter list */
1070Sstevel@tonic-gate 	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
1080Sstevel@tonic-gate 		{
1090Sstevel@tonic-gate 		if ((a->parameter == NULL) ||
1100Sstevel@tonic-gate 			(a->parameter->type != V_ASN1_NULL))
1110Sstevel@tonic-gate 			{
1120Sstevel@tonic-gate 			ASN1_TYPE_free(a->parameter);
113*2139Sjp161948 			if (!(a->parameter=ASN1_TYPE_new()))
114*2139Sjp161948 				{
115*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
116*2139Sjp161948 				goto err;
117*2139Sjp161948 				}
1180Sstevel@tonic-gate 			a->parameter->type=V_ASN1_NULL;
1190Sstevel@tonic-gate 			}
1200Sstevel@tonic-gate 		}
1210Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
122*2139Sjp161948 	else if (pkey->type == EVP_PKEY_DSA)
1230Sstevel@tonic-gate 		{
1240Sstevel@tonic-gate 		unsigned char *pp;
1250Sstevel@tonic-gate 		DSA *dsa;
126*2139Sjp161948 
1270Sstevel@tonic-gate 		dsa=pkey->pkey.dsa;
1280Sstevel@tonic-gate 		dsa->write_params=0;
1290Sstevel@tonic-gate 		ASN1_TYPE_free(a->parameter);
130*2139Sjp161948 		if ((i=i2d_DSAparams(dsa,NULL)) <= 0)
131*2139Sjp161948 			goto err;
132*2139Sjp161948 		if (!(p=(unsigned char *)OPENSSL_malloc(i)))
133*2139Sjp161948 			{
134*2139Sjp161948 			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
135*2139Sjp161948 			goto err;
136*2139Sjp161948 			}
1370Sstevel@tonic-gate 		pp=p;
1380Sstevel@tonic-gate 		i2d_DSAparams(dsa,&pp);
139*2139Sjp161948 		if (!(a->parameter=ASN1_TYPE_new()))
140*2139Sjp161948 			{
141*2139Sjp161948 			OPENSSL_free(p);
142*2139Sjp161948 			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
143*2139Sjp161948 			goto err;
144*2139Sjp161948 			}
1450Sstevel@tonic-gate 		a->parameter->type=V_ASN1_SEQUENCE;
146*2139Sjp161948 		if (!(a->parameter->value.sequence=ASN1_STRING_new()))
147*2139Sjp161948 			{
148*2139Sjp161948 			OPENSSL_free(p);
149*2139Sjp161948 			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
150*2139Sjp161948 			goto err;
151*2139Sjp161948 			}
152*2139Sjp161948 		if (!ASN1_STRING_set(a->parameter->value.sequence,p,i))
153*2139Sjp161948 			{
154*2139Sjp161948 			OPENSSL_free(p);
155*2139Sjp161948 			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
156*2139Sjp161948 			goto err;
157*2139Sjp161948 			}
1580Sstevel@tonic-gate 		OPENSSL_free(p);
1590Sstevel@tonic-gate 		}
1600Sstevel@tonic-gate #endif
161*2139Sjp161948 #ifndef OPENSSL_NO_EC
162*2139Sjp161948 	else if (pkey->type == EVP_PKEY_EC)
163*2139Sjp161948 		{
164*2139Sjp161948 		int nid=0;
165*2139Sjp161948 		unsigned char *pp;
166*2139Sjp161948 		EC_KEY *ec_key;
167*2139Sjp161948 		const EC_GROUP *group;
168*2139Sjp161948 
169*2139Sjp161948 		ec_key = pkey->pkey.ec;
170*2139Sjp161948 		ASN1_TYPE_free(a->parameter);
171*2139Sjp161948 
172*2139Sjp161948 		if ((a->parameter = ASN1_TYPE_new()) == NULL)
173*2139Sjp161948 			{
174*2139Sjp161948 			X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
175*2139Sjp161948 			goto err;
176*2139Sjp161948 			}
177*2139Sjp161948 
178*2139Sjp161948 		group = EC_KEY_get0_group(ec_key);
179*2139Sjp161948 		if (EC_GROUP_get_asn1_flag(group)
180*2139Sjp161948                      && (nid = EC_GROUP_get_curve_name(group)))
181*2139Sjp161948 			{
182*2139Sjp161948 			/* just set the OID */
183*2139Sjp161948 			a->parameter->type = V_ASN1_OBJECT;
184*2139Sjp161948 			a->parameter->value.object = OBJ_nid2obj(nid);
185*2139Sjp161948 			}
186*2139Sjp161948 		else /* explicit parameters */
187*2139Sjp161948 			{
188*2139Sjp161948 			if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
189*2139Sjp161948 				{
190*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
191*2139Sjp161948 				goto err;
192*2139Sjp161948 				}
193*2139Sjp161948 			if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
194*2139Sjp161948 				{
195*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
196*2139Sjp161948 				goto err;
197*2139Sjp161948 				}
198*2139Sjp161948 			pp = p;
199*2139Sjp161948 			if (!i2d_ECParameters(ec_key, &pp))
200*2139Sjp161948 				{
201*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
202*2139Sjp161948 				OPENSSL_free(p);
203*2139Sjp161948 				goto err;
204*2139Sjp161948 				}
205*2139Sjp161948 			a->parameter->type = V_ASN1_SEQUENCE;
206*2139Sjp161948 			if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
207*2139Sjp161948 				{
208*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
209*2139Sjp161948 				OPENSSL_free(p);
210*2139Sjp161948 				goto err;
211*2139Sjp161948 				}
212*2139Sjp161948 			ASN1_STRING_set(a->parameter->value.sequence, p, i);
213*2139Sjp161948 			OPENSSL_free(p);
214*2139Sjp161948 			}
215*2139Sjp161948 		}
216*2139Sjp161948 #endif
217*2139Sjp161948 	else if (1)
2180Sstevel@tonic-gate 		{
2190Sstevel@tonic-gate 		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
2200Sstevel@tonic-gate 		goto err;
2210Sstevel@tonic-gate 		}
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
2240Sstevel@tonic-gate 	if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
2250Sstevel@tonic-gate 		{
2260Sstevel@tonic-gate 		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
2270Sstevel@tonic-gate 		goto err;
2280Sstevel@tonic-gate 		}
2290Sstevel@tonic-gate 	p=s;
2300Sstevel@tonic-gate 	i2d_PublicKey(pkey,&p);
231*2139Sjp161948 	if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i))
232*2139Sjp161948 		{
233*2139Sjp161948 		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
234*2139Sjp161948 		goto err;
235*2139Sjp161948 		}
236*2139Sjp161948   	/* Set number of unused bits to zero */
2370Sstevel@tonic-gate 	pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
2380Sstevel@tonic-gate 	pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 	OPENSSL_free(s);
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate #if 0
2430Sstevel@tonic-gate 	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
2440Sstevel@tonic-gate 	pk->pkey=pkey;
2450Sstevel@tonic-gate #endif
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 	if (*x != NULL)
2480Sstevel@tonic-gate 		X509_PUBKEY_free(*x);
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 	*x=pk;
2510Sstevel@tonic-gate 
252*2139Sjp161948 	return 1;
2530Sstevel@tonic-gate err:
2540Sstevel@tonic-gate 	if (pk != NULL) X509_PUBKEY_free(pk);
255*2139Sjp161948 	return 0;
2560Sstevel@tonic-gate 	}
2570Sstevel@tonic-gate 
X509_PUBKEY_get(X509_PUBKEY * key)2580Sstevel@tonic-gate EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
2590Sstevel@tonic-gate 	{
2600Sstevel@tonic-gate 	EVP_PKEY *ret=NULL;
2610Sstevel@tonic-gate 	long j;
2620Sstevel@tonic-gate 	int type;
263*2139Sjp161948 	const unsigned char *p;
264*2139Sjp161948 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
2650Sstevel@tonic-gate 	const unsigned char *cp;
2660Sstevel@tonic-gate 	X509_ALGOR *a;
2670Sstevel@tonic-gate #endif
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	if (key == NULL) goto err;
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	if (key->pkey != NULL)
272*2139Sjp161948 		{
273*2139Sjp161948 		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
274*2139Sjp161948 		return(key->pkey);
275*2139Sjp161948 		}
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	if (key->public_key == NULL) goto err;
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	type=OBJ_obj2nid(key->algor->algorithm);
280*2139Sjp161948 	if ((ret = EVP_PKEY_new()) == NULL)
2810Sstevel@tonic-gate 		{
282*2139Sjp161948 		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
2830Sstevel@tonic-gate 		goto err;
2840Sstevel@tonic-gate 		}
285*2139Sjp161948 	ret->type = EVP_PKEY_type(type);
2860Sstevel@tonic-gate 
287*2139Sjp161948 	/* the parameters must be extracted before the public key (ECDSA!) */
288*2139Sjp161948 
289*2139Sjp161948 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
290*2139Sjp161948 	a=key->algor;
291*2139Sjp161948 #endif
292*2139Sjp161948 
293*2139Sjp161948 	if (0)
294*2139Sjp161948 		;
2950Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
296*2139Sjp161948 	else if (ret->type == EVP_PKEY_DSA)
2970Sstevel@tonic-gate 		{
2980Sstevel@tonic-gate 		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
2990Sstevel@tonic-gate 			{
300*2139Sjp161948 			if ((ret->pkey.dsa = DSA_new()) == NULL)
301*2139Sjp161948 				{
302*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
303*2139Sjp161948 				goto err;
304*2139Sjp161948 				}
3050Sstevel@tonic-gate 			ret->pkey.dsa->write_params=0;
3060Sstevel@tonic-gate 			cp=p=a->parameter->value.sequence->data;
3070Sstevel@tonic-gate 			j=a->parameter->value.sequence->length;
308*2139Sjp161948 			if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
3090Sstevel@tonic-gate 				goto err;
3100Sstevel@tonic-gate 			}
3110Sstevel@tonic-gate 		ret->save_parameters=1;
3120Sstevel@tonic-gate 		}
3130Sstevel@tonic-gate #endif
314*2139Sjp161948 #ifndef OPENSSL_NO_EC
315*2139Sjp161948 	else if (ret->type == EVP_PKEY_EC)
316*2139Sjp161948 		{
317*2139Sjp161948 		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
318*2139Sjp161948 			{
319*2139Sjp161948 			/* type == V_ASN1_SEQUENCE => we have explicit parameters
320*2139Sjp161948                          * (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
321*2139Sjp161948 			 */
322*2139Sjp161948 			if ((ret->pkey.ec= EC_KEY_new()) == NULL)
323*2139Sjp161948 				{
324*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_GET,
325*2139Sjp161948 					ERR_R_MALLOC_FAILURE);
326*2139Sjp161948 				goto err;
327*2139Sjp161948 				}
328*2139Sjp161948 			cp = p = a->parameter->value.sequence->data;
329*2139Sjp161948 			j = a->parameter->value.sequence->length;
330*2139Sjp161948 			if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j))
331*2139Sjp161948 				{
332*2139Sjp161948 				X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
333*2139Sjp161948 				goto err;
334*2139Sjp161948 				}
335*2139Sjp161948 			}
336*2139Sjp161948 		else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
337*2139Sjp161948 			{
338*2139Sjp161948 			/* type == V_ASN1_OBJECT => the parameters are given
339*2139Sjp161948 			 * by an asn1 OID
340*2139Sjp161948 			 */
341*2139Sjp161948 			EC_KEY   *ec_key;
342*2139Sjp161948 			EC_GROUP *group;
343*2139Sjp161948 
344*2139Sjp161948 			if (ret->pkey.ec == NULL)
345*2139Sjp161948 				ret->pkey.ec = EC_KEY_new();
346*2139Sjp161948 			ec_key = ret->pkey.ec;
347*2139Sjp161948 			if (ec_key == NULL)
348*2139Sjp161948 				goto err;
349*2139Sjp161948 			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
350*2139Sjp161948 			if (group == NULL)
351*2139Sjp161948 				goto err;
352*2139Sjp161948 			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
353*2139Sjp161948 			if (EC_KEY_set_group(ec_key, group) == 0)
354*2139Sjp161948 				goto err;
355*2139Sjp161948 			EC_GROUP_free(group);
356*2139Sjp161948 			}
357*2139Sjp161948 			/* the case implicitlyCA is currently not implemented */
358*2139Sjp161948 		ret->save_parameters = 1;
359*2139Sjp161948 		}
360*2139Sjp161948 #endif
361*2139Sjp161948 
362*2139Sjp161948 	p=key->public_key->data;
363*2139Sjp161948         j=key->public_key->length;
364*2139Sjp161948         if (!d2i_PublicKey(type, &ret, &p, (long)j))
365*2139Sjp161948 		{
366*2139Sjp161948 		X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
367*2139Sjp161948 		goto err;
368*2139Sjp161948 		}
369*2139Sjp161948 
370*2139Sjp161948 	key->pkey = ret;
371*2139Sjp161948 	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
3720Sstevel@tonic-gate 	return(ret);
3730Sstevel@tonic-gate err:
3740Sstevel@tonic-gate 	if (ret != NULL)
3750Sstevel@tonic-gate 		EVP_PKEY_free(ret);
3760Sstevel@tonic-gate 	return(NULL);
3770Sstevel@tonic-gate 	}
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate /* Now two pseudo ASN1 routines that take an EVP_PKEY structure
3800Sstevel@tonic-gate  * and encode or decode as X509_PUBKEY
3810Sstevel@tonic-gate  */
3820Sstevel@tonic-gate 
d2i_PUBKEY(EVP_PKEY ** a,const unsigned char ** pp,long length)383*2139Sjp161948 EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
3840Sstevel@tonic-gate 	     long length)
385*2139Sjp161948 	{
3860Sstevel@tonic-gate 	X509_PUBKEY *xpk;
3870Sstevel@tonic-gate 	EVP_PKEY *pktmp;
3880Sstevel@tonic-gate 	xpk = d2i_X509_PUBKEY(NULL, pp, length);
3890Sstevel@tonic-gate 	if(!xpk) return NULL;
3900Sstevel@tonic-gate 	pktmp = X509_PUBKEY_get(xpk);
3910Sstevel@tonic-gate 	X509_PUBKEY_free(xpk);
3920Sstevel@tonic-gate 	if(!pktmp) return NULL;
393*2139Sjp161948 	if(a)
394*2139Sjp161948 		{
3950Sstevel@tonic-gate 		EVP_PKEY_free(*a);
3960Sstevel@tonic-gate 		*a = pktmp;
397*2139Sjp161948 		}
3980Sstevel@tonic-gate 	return pktmp;
399*2139Sjp161948 	}
4000Sstevel@tonic-gate 
i2d_PUBKEY(EVP_PKEY * a,unsigned char ** pp)4010Sstevel@tonic-gate int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
402*2139Sjp161948 	{
4030Sstevel@tonic-gate 	X509_PUBKEY *xpk=NULL;
4040Sstevel@tonic-gate 	int ret;
4050Sstevel@tonic-gate 	if(!a) return 0;
4060Sstevel@tonic-gate 	if(!X509_PUBKEY_set(&xpk, a)) return 0;
4070Sstevel@tonic-gate 	ret = i2d_X509_PUBKEY(xpk, pp);
4080Sstevel@tonic-gate 	X509_PUBKEY_free(xpk);
4090Sstevel@tonic-gate 	return ret;
410*2139Sjp161948 	}
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate /* The following are equivalents but which return RSA and DSA
4130Sstevel@tonic-gate  * keys
4140Sstevel@tonic-gate  */
4150Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
d2i_RSA_PUBKEY(RSA ** a,const unsigned char ** pp,long length)416*2139Sjp161948 RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
4170Sstevel@tonic-gate 	     long length)
418*2139Sjp161948 	{
4190Sstevel@tonic-gate 	EVP_PKEY *pkey;
4200Sstevel@tonic-gate 	RSA *key;
421*2139Sjp161948 	const unsigned char *q;
4220Sstevel@tonic-gate 	q = *pp;
4230Sstevel@tonic-gate 	pkey = d2i_PUBKEY(NULL, &q, length);
424*2139Sjp161948 	if (!pkey) return NULL;
4250Sstevel@tonic-gate 	key = EVP_PKEY_get1_RSA(pkey);
4260Sstevel@tonic-gate 	EVP_PKEY_free(pkey);
427*2139Sjp161948 	if (!key) return NULL;
4280Sstevel@tonic-gate 	*pp = q;
429*2139Sjp161948 	if (a)
430*2139Sjp161948 		{
4310Sstevel@tonic-gate 		RSA_free(*a);
4320Sstevel@tonic-gate 		*a = key;
433*2139Sjp161948 		}
4340Sstevel@tonic-gate 	return key;
435*2139Sjp161948 	}
4360Sstevel@tonic-gate 
i2d_RSA_PUBKEY(RSA * a,unsigned char ** pp)4370Sstevel@tonic-gate int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
438*2139Sjp161948 	{
4390Sstevel@tonic-gate 	EVP_PKEY *pktmp;
4400Sstevel@tonic-gate 	int ret;
441*2139Sjp161948 	if (!a) return 0;
4420Sstevel@tonic-gate 	pktmp = EVP_PKEY_new();
443*2139Sjp161948 	if (!pktmp)
444*2139Sjp161948 		{
4450Sstevel@tonic-gate 		ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
4460Sstevel@tonic-gate 		return 0;
447*2139Sjp161948 		}
4480Sstevel@tonic-gate 	EVP_PKEY_set1_RSA(pktmp, a);
4490Sstevel@tonic-gate 	ret = i2d_PUBKEY(pktmp, pp);
4500Sstevel@tonic-gate 	EVP_PKEY_free(pktmp);
4510Sstevel@tonic-gate 	return ret;
452*2139Sjp161948 	}
4530Sstevel@tonic-gate #endif
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
d2i_DSA_PUBKEY(DSA ** a,const unsigned char ** pp,long length)456*2139Sjp161948 DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
4570Sstevel@tonic-gate 	     long length)
458*2139Sjp161948 	{
4590Sstevel@tonic-gate 	EVP_PKEY *pkey;
4600Sstevel@tonic-gate 	DSA *key;
461*2139Sjp161948 	const unsigned char *q;
4620Sstevel@tonic-gate 	q = *pp;
4630Sstevel@tonic-gate 	pkey = d2i_PUBKEY(NULL, &q, length);
464*2139Sjp161948 	if (!pkey) return NULL;
4650Sstevel@tonic-gate 	key = EVP_PKEY_get1_DSA(pkey);
4660Sstevel@tonic-gate 	EVP_PKEY_free(pkey);
467*2139Sjp161948 	if (!key) return NULL;
4680Sstevel@tonic-gate 	*pp = q;
469*2139Sjp161948 	if (a)
470*2139Sjp161948 		{
4710Sstevel@tonic-gate 		DSA_free(*a);
4720Sstevel@tonic-gate 		*a = key;
473*2139Sjp161948 		}
4740Sstevel@tonic-gate 	return key;
475*2139Sjp161948 	}
4760Sstevel@tonic-gate 
i2d_DSA_PUBKEY(DSA * a,unsigned char ** pp)4770Sstevel@tonic-gate int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
478*2139Sjp161948 	{
4790Sstevel@tonic-gate 	EVP_PKEY *pktmp;
4800Sstevel@tonic-gate 	int ret;
4810Sstevel@tonic-gate 	if(!a) return 0;
4820Sstevel@tonic-gate 	pktmp = EVP_PKEY_new();
483*2139Sjp161948 	if(!pktmp)
484*2139Sjp161948 		{
4850Sstevel@tonic-gate 		ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
4860Sstevel@tonic-gate 		return 0;
487*2139Sjp161948 		}
4880Sstevel@tonic-gate 	EVP_PKEY_set1_DSA(pktmp, a);
4890Sstevel@tonic-gate 	ret = i2d_PUBKEY(pktmp, pp);
4900Sstevel@tonic-gate 	EVP_PKEY_free(pktmp);
4910Sstevel@tonic-gate 	return ret;
492*2139Sjp161948 	}
4930Sstevel@tonic-gate #endif
494*2139Sjp161948 
495*2139Sjp161948 #ifndef OPENSSL_NO_EC
d2i_EC_PUBKEY(EC_KEY ** a,const unsigned char ** pp,long length)496*2139Sjp161948 EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
497*2139Sjp161948 	{
498*2139Sjp161948 	EVP_PKEY *pkey;
499*2139Sjp161948 	EC_KEY *key;
500*2139Sjp161948 	const unsigned char *q;
501*2139Sjp161948 	q = *pp;
502*2139Sjp161948 	pkey = d2i_PUBKEY(NULL, &q, length);
503*2139Sjp161948 	if (!pkey) return(NULL);
504*2139Sjp161948 	key = EVP_PKEY_get1_EC_KEY(pkey);
505*2139Sjp161948 	EVP_PKEY_free(pkey);
506*2139Sjp161948 	if (!key)  return(NULL);
507*2139Sjp161948 	*pp = q;
508*2139Sjp161948 	if (a)
509*2139Sjp161948 		{
510*2139Sjp161948 		EC_KEY_free(*a);
511*2139Sjp161948 		*a = key;
512*2139Sjp161948 		}
513*2139Sjp161948 	return(key);
514*2139Sjp161948 	}
515*2139Sjp161948 
i2d_EC_PUBKEY(EC_KEY * a,unsigned char ** pp)516*2139Sjp161948 int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
517*2139Sjp161948 	{
518*2139Sjp161948 	EVP_PKEY *pktmp;
519*2139Sjp161948 	int ret;
520*2139Sjp161948 	if (!a)	return(0);
521*2139Sjp161948 	if ((pktmp = EVP_PKEY_new()) == NULL)
522*2139Sjp161948 		{
523*2139Sjp161948 		ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
524*2139Sjp161948 		return(0);
525*2139Sjp161948 		}
526*2139Sjp161948 	EVP_PKEY_set1_EC_KEY(pktmp, a);
527*2139Sjp161948 	ret = i2d_PUBKEY(pktmp, pp);
528*2139Sjp161948 	EVP_PKEY_free(pktmp);
529*2139Sjp161948 	return(ret);
530*2139Sjp161948 	}
531*2139Sjp161948 #endif
532