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