os/ossrv/ssl/libcrypto/src/crypto/asn1/x_pubkey.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* crypto/asn1/x_pubkey.c */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
sl@0
    59
#include <stdio.h>
sl@0
    60
#include "cryptlib.h"
sl@0
    61
#include <openssl/asn1t.h>
sl@0
    62
#include <openssl/x509.h>
sl@0
    63
#ifndef OPENSSL_NO_RSA
sl@0
    64
#include <openssl/rsa.h>
sl@0
    65
#endif
sl@0
    66
#ifndef OPENSSL_NO_DSA
sl@0
    67
#include <openssl/dsa.h>
sl@0
    68
#endif
sl@0
    69
sl@0
    70
/* Minor tweak to operation: free up EVP_PKEY */
sl@0
    71
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
sl@0
    72
	{
sl@0
    73
	if (operation == ASN1_OP_FREE_POST)
sl@0
    74
		{
sl@0
    75
		X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
sl@0
    76
		EVP_PKEY_free(pubkey->pkey);
sl@0
    77
		}
sl@0
    78
	return 1;
sl@0
    79
	}
sl@0
    80
sl@0
    81
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
sl@0
    82
	ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
sl@0
    83
	ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
sl@0
    84
} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
sl@0
    85
sl@0
    86
IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
sl@0
    87
sl@0
    88
EXPORT_C int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
sl@0
    89
	{
sl@0
    90
	X509_PUBKEY *pk=NULL;
sl@0
    91
	X509_ALGOR *a;
sl@0
    92
	ASN1_OBJECT *o;
sl@0
    93
	unsigned char *s,*p = NULL;
sl@0
    94
	int i;
sl@0
    95
sl@0
    96
	if (x == NULL) return(0);
sl@0
    97
sl@0
    98
	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
sl@0
    99
	a=pk->algor;
sl@0
   100
sl@0
   101
	/* set the algorithm id */
sl@0
   102
	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
sl@0
   103
	ASN1_OBJECT_free(a->algorithm);
sl@0
   104
	a->algorithm=o;
sl@0
   105
sl@0
   106
	/* Set the parameter list */
sl@0
   107
	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
sl@0
   108
		{
sl@0
   109
		if ((a->parameter == NULL) ||
sl@0
   110
			(a->parameter->type != V_ASN1_NULL))
sl@0
   111
			{
sl@0
   112
			ASN1_TYPE_free(a->parameter);
sl@0
   113
			if (!(a->parameter=ASN1_TYPE_new()))
sl@0
   114
				{
sl@0
   115
				X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   116
				goto err;
sl@0
   117
				}
sl@0
   118
			a->parameter->type=V_ASN1_NULL;
sl@0
   119
			}
sl@0
   120
		}
sl@0
   121
#ifndef OPENSSL_NO_DSA
sl@0
   122
	else if (pkey->type == EVP_PKEY_DSA)
sl@0
   123
		{
sl@0
   124
		unsigned char *pp;
sl@0
   125
		DSA *dsa;
sl@0
   126
		
sl@0
   127
		dsa=pkey->pkey.dsa;
sl@0
   128
		dsa->write_params=0;
sl@0
   129
		ASN1_TYPE_free(a->parameter);
sl@0
   130
		if ((i=i2d_DSAparams(dsa,NULL)) <= 0)
sl@0
   131
			goto err;
sl@0
   132
		if (!(p=(unsigned char *)OPENSSL_malloc(i)))
sl@0
   133
			{
sl@0
   134
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   135
			goto err;
sl@0
   136
			}
sl@0
   137
		pp=p;
sl@0
   138
		i2d_DSAparams(dsa,&pp);
sl@0
   139
		if (!(a->parameter=ASN1_TYPE_new()))
sl@0
   140
			{
sl@0
   141
			OPENSSL_free(p);
sl@0
   142
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   143
			goto err;
sl@0
   144
			}
sl@0
   145
		a->parameter->type=V_ASN1_SEQUENCE;
sl@0
   146
		if (!(a->parameter->value.sequence=ASN1_STRING_new()))
sl@0
   147
			{
sl@0
   148
			OPENSSL_free(p);
sl@0
   149
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   150
			goto err;
sl@0
   151
			}
sl@0
   152
		if (!ASN1_STRING_set(a->parameter->value.sequence,p,i))
sl@0
   153
			{
sl@0
   154
			OPENSSL_free(p);
sl@0
   155
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   156
			goto err;
sl@0
   157
			}
sl@0
   158
		OPENSSL_free(p);
sl@0
   159
		}
sl@0
   160
#endif
sl@0
   161
#ifndef OPENSSL_NO_EC
sl@0
   162
	else if (pkey->type == EVP_PKEY_EC)
sl@0
   163
		{
sl@0
   164
		int nid=0;
sl@0
   165
		unsigned char *pp;
sl@0
   166
		EC_KEY *ec_key;
sl@0
   167
		const EC_GROUP *group;
sl@0
   168
		
sl@0
   169
		ec_key = pkey->pkey.ec;
sl@0
   170
		ASN1_TYPE_free(a->parameter);
sl@0
   171
sl@0
   172
		if ((a->parameter = ASN1_TYPE_new()) == NULL)
sl@0
   173
			{
sl@0
   174
			X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
sl@0
   175
			goto err;
sl@0
   176
			}
sl@0
   177
sl@0
   178
		group = EC_KEY_get0_group(ec_key);
sl@0
   179
		if (EC_GROUP_get_asn1_flag(group)
sl@0
   180
                     && (nid = EC_GROUP_get_curve_name(group)))
sl@0
   181
			{
sl@0
   182
			/* just set the OID */
sl@0
   183
			a->parameter->type = V_ASN1_OBJECT;
sl@0
   184
			a->parameter->value.object = OBJ_nid2obj(nid);
sl@0
   185
			}
sl@0
   186
		else /* explicit parameters */
sl@0
   187
			{
sl@0
   188
			if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
sl@0
   189
				{
sl@0
   190
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
sl@0
   191
				goto err;
sl@0
   192
				}
sl@0
   193
			if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
sl@0
   194
				{
sl@0
   195
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
sl@0
   196
				goto err;
sl@0
   197
				}	
sl@0
   198
			pp = p;
sl@0
   199
			if (!i2d_ECParameters(ec_key, &pp))
sl@0
   200
				{
sl@0
   201
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
sl@0
   202
				OPENSSL_free(p);
sl@0
   203
				goto err;
sl@0
   204
				}
sl@0
   205
			a->parameter->type = V_ASN1_SEQUENCE;
sl@0
   206
			if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
sl@0
   207
				{
sl@0
   208
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
sl@0
   209
				OPENSSL_free(p);
sl@0
   210
				goto err;
sl@0
   211
				}
sl@0
   212
			ASN1_STRING_set(a->parameter->value.sequence, p, i);
sl@0
   213
			OPENSSL_free(p);
sl@0
   214
			}
sl@0
   215
		}
sl@0
   216
#endif
sl@0
   217
	else if (1)
sl@0
   218
		{
sl@0
   219
		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
sl@0
   220
		goto err;
sl@0
   221
		}
sl@0
   222
sl@0
   223
	if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
sl@0
   224
	if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
sl@0
   225
		{
sl@0
   226
		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   227
		goto err;
sl@0
   228
		}
sl@0
   229
	p=s;
sl@0
   230
	i2d_PublicKey(pkey,&p);
sl@0
   231
	if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i))
sl@0
   232
		{
sl@0
   233
		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
sl@0
   234
		goto err;
sl@0
   235
		}
sl@0
   236
  	/* Set number of unused bits to zero */
sl@0
   237
	pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
sl@0
   238
	pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
sl@0
   239
sl@0
   240
	OPENSSL_free(s);
sl@0
   241
sl@0
   242
#if 0
sl@0
   243
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
sl@0
   244
	pk->pkey=pkey;
sl@0
   245
#endif
sl@0
   246
sl@0
   247
	if (*x != NULL)
sl@0
   248
		X509_PUBKEY_free(*x);
sl@0
   249
sl@0
   250
	*x=pk;
sl@0
   251
sl@0
   252
	return 1;
sl@0
   253
err:
sl@0
   254
	if (pk != NULL) X509_PUBKEY_free(pk);
sl@0
   255
	return 0;
sl@0
   256
	}
sl@0
   257
sl@0
   258
EXPORT_C EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
sl@0
   259
	{
sl@0
   260
	EVP_PKEY *ret=NULL;
sl@0
   261
	long j;
sl@0
   262
	int type;
sl@0
   263
	const unsigned char *p;
sl@0
   264
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
sl@0
   265
	const unsigned char *cp;
sl@0
   266
	X509_ALGOR *a;
sl@0
   267
#endif
sl@0
   268
sl@0
   269
	if (key == NULL) goto err;
sl@0
   270
sl@0
   271
	if (key->pkey != NULL)
sl@0
   272
		{
sl@0
   273
		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
sl@0
   274
		return(key->pkey);
sl@0
   275
		}
sl@0
   276
sl@0
   277
	if (key->public_key == NULL) goto err;
sl@0
   278
sl@0
   279
	type=OBJ_obj2nid(key->algor->algorithm);
sl@0
   280
	if ((ret = EVP_PKEY_new()) == NULL)
sl@0
   281
		{
sl@0
   282
		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
sl@0
   283
		goto err;
sl@0
   284
		}
sl@0
   285
	ret->type = EVP_PKEY_type(type);
sl@0
   286
sl@0
   287
	/* the parameters must be extracted before the public key (ECDSA!) */
sl@0
   288
	
sl@0
   289
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
sl@0
   290
	a=key->algor;
sl@0
   291
#endif
sl@0
   292
sl@0
   293
	if (0)
sl@0
   294
		;
sl@0
   295
#ifndef OPENSSL_NO_DSA
sl@0
   296
	else if (ret->type == EVP_PKEY_DSA)
sl@0
   297
		{
sl@0
   298
		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
sl@0
   299
			{
sl@0
   300
			if ((ret->pkey.dsa = DSA_new()) == NULL)
sl@0
   301
				{
sl@0
   302
				X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
sl@0
   303
				goto err;
sl@0
   304
				}
sl@0
   305
			ret->pkey.dsa->write_params=0;
sl@0
   306
			cp=p=a->parameter->value.sequence->data;
sl@0
   307
			j=a->parameter->value.sequence->length;
sl@0
   308
			if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
sl@0
   309
				goto err;
sl@0
   310
			}
sl@0
   311
		ret->save_parameters=1;
sl@0
   312
		}
sl@0
   313
#endif
sl@0
   314
#ifndef OPENSSL_NO_EC
sl@0
   315
	else if (ret->type == EVP_PKEY_EC)
sl@0
   316
		{
sl@0
   317
		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
sl@0
   318
			{
sl@0
   319
			/* type == V_ASN1_SEQUENCE => we have explicit parameters
sl@0
   320
                         * (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
sl@0
   321
			 */
sl@0
   322
			if ((ret->pkey.ec= EC_KEY_new()) == NULL)
sl@0
   323
				{
sl@0
   324
				X509err(X509_F_X509_PUBKEY_GET, 
sl@0
   325
					ERR_R_MALLOC_FAILURE);
sl@0
   326
				goto err;
sl@0
   327
				}
sl@0
   328
			cp = p = a->parameter->value.sequence->data;
sl@0
   329
			j = a->parameter->value.sequence->length;
sl@0
   330
			if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j))
sl@0
   331
				{
sl@0
   332
				X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
sl@0
   333
				goto err;
sl@0
   334
				}
sl@0
   335
			}
sl@0
   336
		else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
sl@0
   337
			{
sl@0
   338
			/* type == V_ASN1_OBJECT => the parameters are given
sl@0
   339
			 * by an asn1 OID
sl@0
   340
			 */
sl@0
   341
			EC_KEY   *ec_key;
sl@0
   342
			EC_GROUP *group;
sl@0
   343
sl@0
   344
			if (ret->pkey.ec == NULL)
sl@0
   345
				ret->pkey.ec = EC_KEY_new();
sl@0
   346
			ec_key = ret->pkey.ec;
sl@0
   347
			if (ec_key == NULL)
sl@0
   348
				goto err;
sl@0
   349
			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
sl@0
   350
			if (group == NULL)
sl@0
   351
				goto err;
sl@0
   352
			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
sl@0
   353
			if (EC_KEY_set_group(ec_key, group) == 0)
sl@0
   354
				goto err;
sl@0
   355
			EC_GROUP_free(group);
sl@0
   356
			}
sl@0
   357
			/* the case implicitlyCA is currently not implemented */
sl@0
   358
		ret->save_parameters = 1;
sl@0
   359
		}
sl@0
   360
#endif
sl@0
   361
sl@0
   362
	p=key->public_key->data;
sl@0
   363
        j=key->public_key->length;
sl@0
   364
        if (!d2i_PublicKey(type, &ret, &p, (long)j))
sl@0
   365
		{
sl@0
   366
		X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
sl@0
   367
		goto err;
sl@0
   368
		}
sl@0
   369
sl@0
   370
	key->pkey = ret;
sl@0
   371
	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
sl@0
   372
	return(ret);
sl@0
   373
err:
sl@0
   374
	if (ret != NULL)
sl@0
   375
		EVP_PKEY_free(ret);
sl@0
   376
	return(NULL);
sl@0
   377
	}
sl@0
   378
sl@0
   379
/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
sl@0
   380
 * and encode or decode as X509_PUBKEY
sl@0
   381
 */
sl@0
   382
sl@0
   383
EXPORT_C EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
sl@0
   384
	     long length)
sl@0
   385
	{
sl@0
   386
	X509_PUBKEY *xpk;
sl@0
   387
	EVP_PKEY *pktmp;
sl@0
   388
	xpk = d2i_X509_PUBKEY(NULL, pp, length);
sl@0
   389
	if(!xpk) return NULL;
sl@0
   390
	pktmp = X509_PUBKEY_get(xpk);
sl@0
   391
	X509_PUBKEY_free(xpk);
sl@0
   392
	if(!pktmp) return NULL;
sl@0
   393
	if(a)
sl@0
   394
		{
sl@0
   395
		EVP_PKEY_free(*a);
sl@0
   396
		*a = pktmp;
sl@0
   397
		}
sl@0
   398
	return pktmp;
sl@0
   399
	}
sl@0
   400
sl@0
   401
EXPORT_C int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
sl@0
   402
	{
sl@0
   403
	X509_PUBKEY *xpk=NULL;
sl@0
   404
	int ret;
sl@0
   405
	if(!a) return 0;
sl@0
   406
	if(!X509_PUBKEY_set(&xpk, a)) return 0;
sl@0
   407
	ret = i2d_X509_PUBKEY(xpk, pp);
sl@0
   408
	X509_PUBKEY_free(xpk);
sl@0
   409
	return ret;
sl@0
   410
	}
sl@0
   411
sl@0
   412
/* The following are equivalents but which return RSA and DSA
sl@0
   413
 * keys
sl@0
   414
 */
sl@0
   415
#ifndef OPENSSL_NO_RSA
sl@0
   416
EXPORT_C RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
sl@0
   417
	     long length)
sl@0
   418
	{
sl@0
   419
	EVP_PKEY *pkey;
sl@0
   420
	RSA *key;
sl@0
   421
	const unsigned char *q;
sl@0
   422
	q = *pp;
sl@0
   423
	pkey = d2i_PUBKEY(NULL, &q, length);
sl@0
   424
	if (!pkey) return NULL;
sl@0
   425
	key = EVP_PKEY_get1_RSA(pkey);
sl@0
   426
	EVP_PKEY_free(pkey);
sl@0
   427
	if (!key) return NULL;
sl@0
   428
	*pp = q;
sl@0
   429
	if (a)
sl@0
   430
		{
sl@0
   431
		RSA_free(*a);
sl@0
   432
		*a = key;
sl@0
   433
		}
sl@0
   434
	return key;
sl@0
   435
	}
sl@0
   436
sl@0
   437
EXPORT_C int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
sl@0
   438
	{
sl@0
   439
	EVP_PKEY *pktmp;
sl@0
   440
	int ret;
sl@0
   441
	if (!a) return 0;
sl@0
   442
	pktmp = EVP_PKEY_new();
sl@0
   443
	if (!pktmp)
sl@0
   444
		{
sl@0
   445
		ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
sl@0
   446
		return 0;
sl@0
   447
		}
sl@0
   448
	EVP_PKEY_set1_RSA(pktmp, a);
sl@0
   449
	ret = i2d_PUBKEY(pktmp, pp);
sl@0
   450
	EVP_PKEY_free(pktmp);
sl@0
   451
	return ret;
sl@0
   452
	}
sl@0
   453
#endif
sl@0
   454
sl@0
   455
#ifndef OPENSSL_NO_DSA
sl@0
   456
EXPORT_C DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
sl@0
   457
	     long length)
sl@0
   458
	{
sl@0
   459
	EVP_PKEY *pkey;
sl@0
   460
	DSA *key;
sl@0
   461
	const unsigned char *q;
sl@0
   462
	q = *pp;
sl@0
   463
	pkey = d2i_PUBKEY(NULL, &q, length);
sl@0
   464
	if (!pkey) return NULL;
sl@0
   465
	key = EVP_PKEY_get1_DSA(pkey);
sl@0
   466
	EVP_PKEY_free(pkey);
sl@0
   467
	if (!key) return NULL;
sl@0
   468
	*pp = q;
sl@0
   469
	if (a)
sl@0
   470
		{
sl@0
   471
		DSA_free(*a);
sl@0
   472
		*a = key;
sl@0
   473
		}
sl@0
   474
	return key;
sl@0
   475
	}
sl@0
   476
sl@0
   477
EXPORT_C int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
sl@0
   478
	{
sl@0
   479
	EVP_PKEY *pktmp;
sl@0
   480
	int ret;
sl@0
   481
	if(!a) return 0;
sl@0
   482
	pktmp = EVP_PKEY_new();
sl@0
   483
	if(!pktmp)
sl@0
   484
		{
sl@0
   485
		ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
sl@0
   486
		return 0;
sl@0
   487
		}
sl@0
   488
	EVP_PKEY_set1_DSA(pktmp, a);
sl@0
   489
	ret = i2d_PUBKEY(pktmp, pp);
sl@0
   490
	EVP_PKEY_free(pktmp);
sl@0
   491
	return ret;
sl@0
   492
	}
sl@0
   493
#endif
sl@0
   494
sl@0
   495
#ifndef OPENSSL_NO_EC
sl@0
   496
EXPORT_C EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
sl@0
   497
	{
sl@0
   498
	EVP_PKEY *pkey;
sl@0
   499
	EC_KEY *key;
sl@0
   500
	const unsigned char *q;
sl@0
   501
	q = *pp;
sl@0
   502
	pkey = d2i_PUBKEY(NULL, &q, length);
sl@0
   503
	if (!pkey) return(NULL);
sl@0
   504
	key = EVP_PKEY_get1_EC_KEY(pkey);
sl@0
   505
	EVP_PKEY_free(pkey);
sl@0
   506
	if (!key)  return(NULL);
sl@0
   507
	*pp = q;
sl@0
   508
	if (a)
sl@0
   509
		{
sl@0
   510
		EC_KEY_free(*a);
sl@0
   511
		*a = key;
sl@0
   512
		}
sl@0
   513
	return(key);
sl@0
   514
	}
sl@0
   515
sl@0
   516
EXPORT_C int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
sl@0
   517
	{
sl@0
   518
	EVP_PKEY *pktmp;
sl@0
   519
	int ret;
sl@0
   520
	if (!a)	return(0);
sl@0
   521
	if ((pktmp = EVP_PKEY_new()) == NULL)
sl@0
   522
		{
sl@0
   523
		ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
sl@0
   524
		return(0);
sl@0
   525
		}
sl@0
   526
	EVP_PKEY_set1_EC_KEY(pktmp, a);
sl@0
   527
	ret = i2d_PUBKEY(pktmp, pp);
sl@0
   528
	EVP_PKEY_free(pktmp);
sl@0
   529
	return(ret);
sl@0
   530
	}
sl@0
   531
#endif