ec_asn1.c revision 267258
1/* crypto/ec/ec_asn1.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 *    software must display the following acknowledgment:
22 *    "This product includes software developed by the OpenSSL Project
23 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 *    endorse or promote products derived from this software without
27 *    prior written permission. For written permission, please contact
28 *    licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 *    nor may "OpenSSL" appear in their names without prior written
32 *    permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 *    acknowledgment:
36 *    "This product includes software developed by the OpenSSL Project
37 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com).  This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <string.h>
60#include "ec_lcl.h"
61#include <openssl/err.h>
62#include <openssl/asn1t.h>
63#include <openssl/objects.h>
64
65
66int EC_GROUP_get_basis_type(const EC_GROUP *group)
67	{
68	int i=0;
69
70	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
71		NID_X9_62_characteristic_two_field)
72		/* everything else is currently not supported */
73		return 0;
74
75	while (group->poly[i] != 0)
76		i++;
77
78	if (i == 4)
79		return NID_X9_62_ppBasis;
80	else if (i == 2)
81		return NID_X9_62_tpBasis;
82	else
83		/* everything else is currently not supported */
84		return 0;
85	}
86#ifndef OPENSSL_NO_EC2M
87int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
88	{
89	if (group == NULL)
90		return 0;
91
92	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
93	    NID_X9_62_characteristic_two_field
94	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
95		{
96		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
97		return 0;
98		}
99
100	if (k)
101		*k = group->poly[1];
102
103	return 1;
104	}
105int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
106	unsigned int *k2, unsigned int *k3)
107	{
108	if (group == NULL)
109		return 0;
110
111	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
112	    NID_X9_62_characteristic_two_field
113	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
114		{
115		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
116		return 0;
117		}
118
119	if (k1)
120		*k1 = group->poly[3];
121	if (k2)
122		*k2 = group->poly[2];
123	if (k3)
124		*k3 = group->poly[1];
125
126	return 1;
127	}
128#endif
129
130
131/* some structures needed for the asn1 encoding */
132typedef struct x9_62_pentanomial_st {
133	long k1;
134	long k2;
135	long k3;
136	} X9_62_PENTANOMIAL;
137
138typedef struct x9_62_characteristic_two_st {
139	long m;
140	ASN1_OBJECT  *type;
141	union	{
142		char *ptr;
143		/* NID_X9_62_onBasis */
144		ASN1_NULL    *onBasis;
145		/* NID_X9_62_tpBasis */
146		ASN1_INTEGER *tpBasis;
147		/* NID_X9_62_ppBasis */
148		X9_62_PENTANOMIAL *ppBasis;
149		/* anything else */
150		ASN1_TYPE *other;
151		} p;
152	} X9_62_CHARACTERISTIC_TWO;
153
154typedef struct x9_62_fieldid_st {
155        ASN1_OBJECT *fieldType;
156	union	{
157		char *ptr;
158		/* NID_X9_62_prime_field */
159		ASN1_INTEGER *prime;
160		/* NID_X9_62_characteristic_two_field */
161		X9_62_CHARACTERISTIC_TWO *char_two;
162		/* anything else */
163		ASN1_TYPE *other;
164		} p;
165	} X9_62_FIELDID;
166
167typedef struct x9_62_curve_st {
168        ASN1_OCTET_STRING *a;
169        ASN1_OCTET_STRING *b;
170        ASN1_BIT_STRING   *seed;
171        } X9_62_CURVE;
172
173typedef struct ec_parameters_st {
174        long              version;
175        X9_62_FIELDID     *fieldID;
176        X9_62_CURVE       *curve;
177        ASN1_OCTET_STRING *base;
178        ASN1_INTEGER      *order;
179        ASN1_INTEGER      *cofactor;
180        } ECPARAMETERS;
181
182struct ecpk_parameters_st {
183	int	type;
184	union {
185		ASN1_OBJECT  *named_curve;
186		ECPARAMETERS *parameters;
187		ASN1_NULL    *implicitlyCA;
188	} value;
189	}/* ECPKPARAMETERS */;
190
191/* SEC1 ECPrivateKey */
192typedef struct ec_privatekey_st {
193	long              version;
194	ASN1_OCTET_STRING *privateKey;
195        ECPKPARAMETERS    *parameters;
196	ASN1_BIT_STRING   *publicKey;
197	} EC_PRIVATEKEY;
198
199/* the OpenSSL ASN.1 definitions */
200ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
201	ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
202	ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
203	ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
204} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
205
206DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
207IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
208
209ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
210
211ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
212	ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
213	ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
214	ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
215} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
216
217ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
218	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
219	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
220	ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
221} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
222
223DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
224IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
225
226ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
227
228ASN1_ADB(X9_62_FIELDID) = {
229	ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
230	ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
231} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
232
233ASN1_SEQUENCE(X9_62_FIELDID) = {
234	ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
235	ASN1_ADB_OBJECT(X9_62_FIELDID)
236} ASN1_SEQUENCE_END(X9_62_FIELDID)
237
238ASN1_SEQUENCE(X9_62_CURVE) = {
239	ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
240	ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
241	ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
242} ASN1_SEQUENCE_END(X9_62_CURVE)
243
244ASN1_SEQUENCE(ECPARAMETERS) = {
245	ASN1_SIMPLE(ECPARAMETERS, version, LONG),
246	ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
247	ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
248	ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
249	ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
250	ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
251} ASN1_SEQUENCE_END(ECPARAMETERS)
252
253DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
254IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
255
256ASN1_CHOICE(ECPKPARAMETERS) = {
257	ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
258	ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
259	ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
260} ASN1_CHOICE_END(ECPKPARAMETERS)
261
262DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
263DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
264IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
265
266ASN1_SEQUENCE(EC_PRIVATEKEY) = {
267	ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
268	ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
269	ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
270	ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
271} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
272
273DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
274DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
275IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
276
277/* some declarations of internal function */
278
279/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
280static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
281/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
282static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
283/* ec_asn1_parameters2group() creates a EC_GROUP object from a
284 * ECPARAMETERS object */
285static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
286/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
287 * EC_GROUP object */
288static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
289/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
290 * ECPKPARAMETERS object */
291static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
292/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
293 * EC_GROUP object */
294static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
295	ECPKPARAMETERS *);
296
297
298/* the function definitions */
299
300static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
301	{
302	int			ok=0, nid;
303	BIGNUM			*tmp = NULL;
304
305	if (group == NULL || field == NULL)
306		return 0;
307
308	/* clear the old values (if necessary) */
309	if (field->fieldType != NULL)
310		ASN1_OBJECT_free(field->fieldType);
311	if (field->p.other != NULL)
312		ASN1_TYPE_free(field->p.other);
313
314	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
315	/* set OID for the field */
316	if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
317		{
318		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
319		goto err;
320		}
321
322	if (nid == NID_X9_62_prime_field)
323		{
324		if ((tmp = BN_new()) == NULL)
325			{
326			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
327			goto err;
328			}
329		/* the parameters are specified by the prime number p */
330		if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
331			{
332			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
333			goto err;
334			}
335		/* set the prime number */
336		field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
337		if (field->p.prime == NULL)
338			{
339			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
340			goto err;
341			}
342		}
343	else	/* nid == NID_X9_62_characteristic_two_field */
344#ifdef OPENSSL_NO_EC2M
345		{
346		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
347		goto err;
348		}
349#else
350		{
351		int		field_type;
352		X9_62_CHARACTERISTIC_TWO *char_two;
353
354		field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
355		char_two = field->p.char_two;
356
357		if (char_two == NULL)
358			{
359			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
360			goto err;
361			}
362
363		char_two->m = (long)EC_GROUP_get_degree(group);
364
365		field_type = EC_GROUP_get_basis_type(group);
366
367		if (field_type == 0)
368			{
369			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
370			goto err;
371			}
372		/* set base type OID */
373		if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
374			{
375			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
376			goto err;
377			}
378
379		if (field_type == NID_X9_62_tpBasis)
380			{
381			unsigned int k;
382
383			if (!EC_GROUP_get_trinomial_basis(group, &k))
384				goto err;
385
386			char_two->p.tpBasis = ASN1_INTEGER_new();
387			if (!char_two->p.tpBasis)
388				{
389				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
390				goto err;
391				}
392			if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
393				{
394				ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
395					ERR_R_ASN1_LIB);
396				goto err;
397				}
398			}
399		else if (field_type == NID_X9_62_ppBasis)
400			{
401			unsigned int k1, k2, k3;
402
403			if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
404				goto err;
405
406			char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
407			if (!char_two->p.ppBasis)
408				{
409				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
410				goto err;
411				}
412
413			/* set k? values */
414			char_two->p.ppBasis->k1 = (long)k1;
415			char_two->p.ppBasis->k2 = (long)k2;
416			char_two->p.ppBasis->k3 = (long)k3;
417			}
418		else /* field_type == NID_X9_62_onBasis */
419			{
420			/* for ONB the parameters are (asn1) NULL */
421			char_two->p.onBasis = ASN1_NULL_new();
422			if (!char_two->p.onBasis)
423				{
424				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
425				goto err;
426				}
427			}
428		}
429#endif
430
431	ok = 1;
432
433err :	if (tmp)
434		BN_free(tmp);
435	return(ok);
436}
437
438static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
439	{
440	int           ok=0, nid;
441	BIGNUM        *tmp_1=NULL, *tmp_2=NULL;
442	unsigned char *buffer_1=NULL, *buffer_2=NULL,
443	              *a_buf=NULL, *b_buf=NULL;
444	size_t        len_1, len_2;
445	unsigned char char_zero = 0;
446
447	if (!group || !curve || !curve->a || !curve->b)
448		return 0;
449
450	if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
451		{
452		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
453		goto err;
454		}
455
456	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
457
458	/* get a and b */
459	if (nid == NID_X9_62_prime_field)
460		{
461		if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
462			{
463			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
464			goto err;
465			}
466		}
467#ifndef OPENSSL_NO_EC2M
468	else	/* nid == NID_X9_62_characteristic_two_field */
469		{
470		if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
471			{
472			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
473			goto err;
474			}
475		}
476#endif
477	len_1 = (size_t)BN_num_bytes(tmp_1);
478	len_2 = (size_t)BN_num_bytes(tmp_2);
479
480	if (len_1 == 0)
481		{
482		/* len_1 == 0 => a == 0 */
483		a_buf = &char_zero;
484		len_1 = 1;
485		}
486	else
487		{
488		if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
489			{
490			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
491			      ERR_R_MALLOC_FAILURE);
492			goto err;
493			}
494		if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
495			{
496			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
497			goto err;
498			}
499		a_buf = buffer_1;
500		}
501
502	if (len_2 == 0)
503		{
504		/* len_2 == 0 => b == 0 */
505		b_buf = &char_zero;
506		len_2 = 1;
507		}
508	else
509		{
510		if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
511			{
512			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
513			      ERR_R_MALLOC_FAILURE);
514			goto err;
515			}
516		if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
517			{
518			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
519			goto err;
520			}
521		b_buf = buffer_2;
522		}
523
524	/* set a and b */
525	if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
526	    !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
527		{
528		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
529		goto err;
530		}
531
532	/* set the seed (optional) */
533	if (group->seed)
534		{
535		if (!curve->seed)
536			if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
537				{
538				ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
539				goto err;
540				}
541		curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
542		curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
543		if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
544		                         (int)group->seed_len))
545			{
546			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
547			goto err;
548			}
549		}
550	else
551		{
552		if (curve->seed)
553			{
554			ASN1_BIT_STRING_free(curve->seed);
555			curve->seed = NULL;
556			}
557		}
558
559	ok = 1;
560
561err:	if (buffer_1)
562		OPENSSL_free(buffer_1);
563	if (buffer_2)
564		OPENSSL_free(buffer_2);
565	if (tmp_1)
566		BN_free(tmp_1);
567	if (tmp_2)
568		BN_free(tmp_2);
569	return(ok);
570	}
571
572static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
573                                              ECPARAMETERS *param)
574	{
575	int	ok=0;
576	size_t  len=0;
577	ECPARAMETERS   *ret=NULL;
578	BIGNUM	       *tmp=NULL;
579	unsigned char  *buffer=NULL;
580	const EC_POINT *point=NULL;
581	point_conversion_form_t form;
582
583	if ((tmp = BN_new()) == NULL)
584		{
585		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
586		goto err;
587		}
588
589	if (param == NULL)
590	{
591		if ((ret = ECPARAMETERS_new()) == NULL)
592			{
593			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
594			      ERR_R_MALLOC_FAILURE);
595			goto err;
596			}
597	}
598	else
599		ret = param;
600
601	/* set the version (always one) */
602	ret->version = (long)0x1;
603
604	/* set the fieldID */
605	if (!ec_asn1_group2fieldid(group, ret->fieldID))
606		{
607		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
608		goto err;
609		}
610
611	/* set the curve */
612	if (!ec_asn1_group2curve(group, ret->curve))
613		{
614		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
615		goto err;
616		}
617
618	/* set the base point */
619	if ((point = EC_GROUP_get0_generator(group)) == NULL)
620		{
621		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
622		goto err;
623		}
624
625	form = EC_GROUP_get_point_conversion_form(group);
626
627	len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
628	if (len == 0)
629		{
630		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
631		goto err;
632		}
633	if ((buffer = OPENSSL_malloc(len)) == NULL)
634		{
635		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
636		goto err;
637		}
638	if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
639		{
640		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
641		goto err;
642		}
643	if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
644		{
645		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
646		goto err;
647		}
648	if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
649		{
650		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
651		goto err;
652		}
653
654	/* set the order */
655	if (!EC_GROUP_get_order(group, tmp, NULL))
656		{
657		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
658		goto err;
659		}
660	ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
661	if (ret->order == NULL)
662		{
663		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
664		goto err;
665		}
666
667	/* set the cofactor (optional) */
668	if (EC_GROUP_get_cofactor(group, tmp, NULL))
669		{
670		ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
671		if (ret->cofactor == NULL)
672			{
673			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
674			goto err;
675			}
676		}
677
678	ok = 1;
679
680err :	if(!ok)
681		{
682		if (ret && !param)
683			ECPARAMETERS_free(ret);
684		ret = NULL;
685		}
686	if (tmp)
687		BN_free(tmp);
688	if (buffer)
689		OPENSSL_free(buffer);
690	return(ret);
691	}
692
693ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
694                                           ECPKPARAMETERS *params)
695	{
696	int            ok = 1, tmp;
697	ECPKPARAMETERS *ret = params;
698
699	if (ret == NULL)
700		{
701		if ((ret = ECPKPARAMETERS_new()) == NULL)
702			{
703			ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
704			      ERR_R_MALLOC_FAILURE);
705			return NULL;
706			}
707		}
708	else
709		{
710		if (ret->type == 0 && ret->value.named_curve)
711			ASN1_OBJECT_free(ret->value.named_curve);
712		else if (ret->type == 1 && ret->value.parameters)
713			ECPARAMETERS_free(ret->value.parameters);
714		}
715
716	if (EC_GROUP_get_asn1_flag(group))
717		{
718		/* use the asn1 OID to describe the
719		 * the elliptic curve parameters
720		 */
721		tmp = EC_GROUP_get_curve_name(group);
722		if (tmp)
723			{
724			ret->type = 0;
725			if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
726				ok = 0;
727			}
728		else
729			/* we don't kmow the nid => ERROR */
730			ok = 0;
731		}
732	else
733		{
734		/* use the ECPARAMETERS structure */
735		ret->type = 1;
736		if ((ret->value.parameters = ec_asn1_group2parameters(
737		     group, NULL)) == NULL)
738			ok = 0;
739		}
740
741	if (!ok)
742		{
743		ECPKPARAMETERS_free(ret);
744		return NULL;
745		}
746	return ret;
747	}
748
749static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
750	{
751	int			ok = 0, tmp;
752	EC_GROUP		*ret = NULL;
753	BIGNUM			*p = NULL, *a = NULL, *b = NULL;
754	EC_POINT		*point=NULL;
755	long    		field_bits;
756
757	if (!params->fieldID || !params->fieldID->fieldType ||
758	    !params->fieldID->p.ptr)
759		{
760		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
761		goto err;
762		}
763
764	/* now extract the curve parameters a and b */
765	if (!params->curve || !params->curve->a ||
766	    !params->curve->a->data || !params->curve->b ||
767	    !params->curve->b->data)
768		{
769		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
770		goto err;
771		}
772	a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
773	if (a == NULL)
774		{
775		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
776		goto err;
777		}
778	b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
779	if (b == NULL)
780		{
781		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
782		goto err;
783		}
784
785	/* get the field parameters */
786	tmp = OBJ_obj2nid(params->fieldID->fieldType);
787	if (tmp == NID_X9_62_characteristic_two_field)
788#ifdef OPENSSL_NO_EC2M
789		{
790		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
791		goto err;
792		}
793#else
794		{
795		X9_62_CHARACTERISTIC_TWO *char_two;
796
797		char_two = params->fieldID->p.char_two;
798
799		field_bits = char_two->m;
800		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
801			{
802			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
803			goto err;
804			}
805
806		if ((p = BN_new()) == NULL)
807			{
808			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
809			goto err;
810			}
811
812		/* get the base type */
813		tmp = OBJ_obj2nid(char_two->type);
814
815		if (tmp ==  NID_X9_62_tpBasis)
816			{
817			long tmp_long;
818
819			if (!char_two->p.tpBasis)
820				{
821				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
822				goto err;
823				}
824
825			tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
826
827			if (!(char_two->m > tmp_long && tmp_long > 0))
828				{
829				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
830				goto err;
831				}
832
833			/* create the polynomial */
834			if (!BN_set_bit(p, (int)char_two->m))
835				goto err;
836			if (!BN_set_bit(p, (int)tmp_long))
837				goto err;
838			if (!BN_set_bit(p, 0))
839				goto err;
840			}
841		else if (tmp == NID_X9_62_ppBasis)
842			{
843			X9_62_PENTANOMIAL *penta;
844
845			penta = char_two->p.ppBasis;
846			if (!penta)
847				{
848				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
849				goto err;
850				}
851
852			if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
853				{
854				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
855				goto err;
856				}
857
858			/* create the polynomial */
859			if (!BN_set_bit(p, (int)char_two->m)) goto err;
860			if (!BN_set_bit(p, (int)penta->k1)) goto err;
861			if (!BN_set_bit(p, (int)penta->k2)) goto err;
862			if (!BN_set_bit(p, (int)penta->k3)) goto err;
863			if (!BN_set_bit(p, 0)) goto err;
864			}
865		else if (tmp == NID_X9_62_onBasis)
866			{
867			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
868			goto err;
869			}
870		else /* error */
871			{
872			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
873			goto err;
874			}
875
876		/* create the EC_GROUP structure */
877		ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
878		}
879#endif
880	else if (tmp == NID_X9_62_prime_field)
881		{
882		/* we have a curve over a prime field */
883		/* extract the prime number */
884		if (!params->fieldID->p.prime)
885			{
886			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
887			goto err;
888			}
889		p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
890		if (p == NULL)
891			{
892			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
893			goto err;
894			}
895
896		if (BN_is_negative(p) || BN_is_zero(p))
897			{
898			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
899			goto err;
900			}
901
902		field_bits = BN_num_bits(p);
903		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
904			{
905			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
906			goto err;
907			}
908
909		/* create the EC_GROUP structure */
910		ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
911		}
912	else
913		{
914		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
915		goto err;
916		}
917
918	if (ret == NULL)
919		{
920		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
921		goto err;
922		}
923
924	/* extract seed (optional) */
925	if (params->curve->seed != NULL)
926		{
927		if (ret->seed != NULL)
928			OPENSSL_free(ret->seed);
929		if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
930			{
931			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
932			      ERR_R_MALLOC_FAILURE);
933			goto err;
934			}
935		memcpy(ret->seed, params->curve->seed->data,
936		       params->curve->seed->length);
937		ret->seed_len = params->curve->seed->length;
938		}
939
940	if (!params->order || !params->base || !params->base->data)
941		{
942		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
943		goto err;
944		}
945
946	if ((point = EC_POINT_new(ret)) == NULL) goto err;
947
948	/* set the point conversion form */
949	EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
950				(params->base->data[0] & ~0x01));
951
952	/* extract the ec point */
953	if (!EC_POINT_oct2point(ret, point, params->base->data,
954		                params->base->length, NULL))
955		{
956		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
957		goto err;
958		}
959
960	/* extract the order */
961	if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
962		{
963		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
964		goto err;
965		}
966	if (BN_is_negative(a) || BN_is_zero(a))
967		{
968		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
969		goto err;
970		}
971	if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
972		{
973		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
974		goto err;
975		}
976
977	/* extract the cofactor (optional) */
978	if (params->cofactor == NULL)
979		{
980		if (b)
981			{
982			BN_free(b);
983			b = NULL;
984			}
985		}
986	else
987		if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
988			{
989			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
990			goto err;
991			}
992	/* set the generator, order and cofactor (if present) */
993	if (!EC_GROUP_set_generator(ret, point, a, b))
994		{
995		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
996		goto err;
997		}
998
999	ok = 1;
1000
1001err:	if (!ok)
1002		{
1003		if (ret)
1004			EC_GROUP_clear_free(ret);
1005		ret = NULL;
1006		}
1007
1008	if (p)
1009		BN_free(p);
1010	if (a)
1011		BN_free(a);
1012	if (b)
1013		BN_free(b);
1014	if (point)
1015		EC_POINT_free(point);
1016	return(ret);
1017}
1018
1019EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1020	{
1021	EC_GROUP *ret=NULL;
1022	int      tmp=0;
1023
1024	if (params == NULL)
1025		{
1026		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1027		      EC_R_MISSING_PARAMETERS);
1028		return NULL;
1029		}
1030
1031	if (params->type == 0)
1032		{ /* the curve is given by an OID */
1033		tmp = OBJ_obj2nid(params->value.named_curve);
1034		if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
1035			{
1036			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1037			      EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1038			return NULL;
1039			}
1040		EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1041		}
1042	else if (params->type == 1)
1043		{ /* the parameters are given by a ECPARAMETERS
1044		   * structure */
1045		ret = ec_asn1_parameters2group(params->value.parameters);
1046		if (!ret)
1047			{
1048			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1049			return NULL;
1050			}
1051		EC_GROUP_set_asn1_flag(ret, 0x0);
1052		}
1053	else if (params->type == 2)
1054		{ /* implicitlyCA */
1055		return NULL;
1056		}
1057	else
1058		{
1059		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1060		return NULL;
1061		}
1062
1063	return ret;
1064	}
1065
1066/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1067
1068EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1069	{
1070	EC_GROUP	*group  = NULL;
1071	ECPKPARAMETERS	*params = NULL;
1072
1073	if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1074		{
1075		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1076		ECPKPARAMETERS_free(params);
1077		return NULL;
1078		}
1079
1080	if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1081		{
1082		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1083		ECPKPARAMETERS_free(params);
1084		return NULL;
1085		}
1086
1087
1088	if (a && *a)
1089		EC_GROUP_clear_free(*a);
1090	if (a)
1091		*a = group;
1092
1093	ECPKPARAMETERS_free(params);
1094	return(group);
1095	}
1096
1097int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1098	{
1099	int		ret=0;
1100	ECPKPARAMETERS	*tmp = ec_asn1_group2pkparameters(a, NULL);
1101	if (tmp == NULL)
1102		{
1103		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1104		return 0;
1105		}
1106	if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1107		{
1108		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1109		ECPKPARAMETERS_free(tmp);
1110		return 0;
1111		}
1112	ECPKPARAMETERS_free(tmp);
1113	return(ret);
1114	}
1115
1116/* some EC_KEY functions */
1117
1118EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1119	{
1120	int             ok=0;
1121	EC_KEY          *ret=NULL;
1122	EC_PRIVATEKEY   *priv_key=NULL;
1123
1124	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1125		{
1126		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1127		return NULL;
1128		}
1129
1130	if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1131		{
1132		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1133		EC_PRIVATEKEY_free(priv_key);
1134		return NULL;
1135		}
1136
1137	if (a == NULL || *a == NULL)
1138		{
1139		if ((ret = EC_KEY_new()) == NULL)
1140			{
1141			ECerr(EC_F_D2I_ECPRIVATEKEY,
1142                                 ERR_R_MALLOC_FAILURE);
1143			goto err;
1144			}
1145		if (a)
1146			*a = ret;
1147		}
1148	else
1149		ret = *a;
1150
1151	if (priv_key->parameters)
1152		{
1153		if (ret->group)
1154			EC_GROUP_clear_free(ret->group);
1155		ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1156		}
1157
1158	if (ret->group == NULL)
1159		{
1160		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1161		goto err;
1162		}
1163
1164	ret->version = priv_key->version;
1165
1166	if (priv_key->privateKey)
1167		{
1168		ret->priv_key = BN_bin2bn(
1169			M_ASN1_STRING_data(priv_key->privateKey),
1170			M_ASN1_STRING_length(priv_key->privateKey),
1171			ret->priv_key);
1172		if (ret->priv_key == NULL)
1173			{
1174			ECerr(EC_F_D2I_ECPRIVATEKEY,
1175                              ERR_R_BN_LIB);
1176			goto err;
1177			}
1178		}
1179	else
1180		{
1181		ECerr(EC_F_D2I_ECPRIVATEKEY,
1182                      EC_R_MISSING_PRIVATE_KEY);
1183		goto err;
1184		}
1185
1186	if (priv_key->publicKey)
1187		{
1188		const unsigned char *pub_oct;
1189		size_t pub_oct_len;
1190
1191		if (ret->pub_key)
1192			EC_POINT_clear_free(ret->pub_key);
1193		ret->pub_key = EC_POINT_new(ret->group);
1194		if (ret->pub_key == NULL)
1195			{
1196			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1197			goto err;
1198			}
1199		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
1200		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1201		/* save the point conversion form */
1202		ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
1203		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1204			pub_oct, pub_oct_len, NULL))
1205			{
1206			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1207			goto err;
1208			}
1209		}
1210
1211	ok = 1;
1212err:
1213	if (!ok)
1214		{
1215		if (ret)
1216			EC_KEY_free(ret);
1217		ret = NULL;
1218		}
1219
1220	if (priv_key)
1221		EC_PRIVATEKEY_free(priv_key);
1222
1223	return(ret);
1224	}
1225
1226int	i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1227	{
1228	int             ret=0, ok=0;
1229	unsigned char   *buffer=NULL;
1230	size_t          buf_len=0, tmp_len;
1231	EC_PRIVATEKEY   *priv_key=NULL;
1232
1233	if (a == NULL || a->group == NULL || a->priv_key == NULL)
1234		{
1235		ECerr(EC_F_I2D_ECPRIVATEKEY,
1236                      ERR_R_PASSED_NULL_PARAMETER);
1237		goto err;
1238		}
1239
1240	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1241		{
1242		ECerr(EC_F_I2D_ECPRIVATEKEY,
1243                      ERR_R_MALLOC_FAILURE);
1244		goto err;
1245		}
1246
1247	priv_key->version = a->version;
1248
1249	buf_len = (size_t)BN_num_bytes(a->priv_key);
1250	buffer = OPENSSL_malloc(buf_len);
1251	if (buffer == NULL)
1252		{
1253		ECerr(EC_F_I2D_ECPRIVATEKEY,
1254                      ERR_R_MALLOC_FAILURE);
1255		goto err;
1256		}
1257
1258	if (!BN_bn2bin(a->priv_key, buffer))
1259		{
1260		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1261		goto err;
1262		}
1263
1264	if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1265		{
1266		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1267		goto err;
1268		}
1269
1270	if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1271		{
1272		if ((priv_key->parameters = ec_asn1_group2pkparameters(
1273			a->group, priv_key->parameters)) == NULL)
1274			{
1275			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1276			goto err;
1277			}
1278		}
1279
1280	if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1281		{
1282		priv_key->publicKey = M_ASN1_BIT_STRING_new();
1283		if (priv_key->publicKey == NULL)
1284			{
1285			ECerr(EC_F_I2D_ECPRIVATEKEY,
1286				ERR_R_MALLOC_FAILURE);
1287			goto err;
1288			}
1289
1290		tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1291				a->conv_form, NULL, 0, NULL);
1292
1293		if (tmp_len > buf_len)
1294			{
1295			unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1296			if (!tmp_buffer)
1297				{
1298				ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1299				goto err;
1300				}
1301			buffer = tmp_buffer;
1302			buf_len = tmp_len;
1303			}
1304
1305		if (!EC_POINT_point2oct(a->group, a->pub_key,
1306			a->conv_form, buffer, buf_len, NULL))
1307			{
1308			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1309			goto err;
1310			}
1311
1312		priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
1313		priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1314		if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer,
1315				buf_len))
1316			{
1317			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1318			goto err;
1319			}
1320		}
1321
1322	if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1323		{
1324		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1325		goto err;
1326		}
1327	ok=1;
1328err:
1329	if (buffer)
1330		OPENSSL_free(buffer);
1331	if (priv_key)
1332		EC_PRIVATEKEY_free(priv_key);
1333	return(ok?ret:0);
1334	}
1335
1336int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1337	{
1338	if (a == NULL)
1339		{
1340		ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1341		return 0;
1342		}
1343	return i2d_ECPKParameters(a->group, out);
1344	}
1345
1346EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1347	{
1348	EC_KEY   *ret;
1349
1350	if (in == NULL || *in == NULL)
1351		{
1352		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1353		return NULL;
1354		}
1355
1356	if (a == NULL || *a == NULL)
1357		{
1358		if ((ret = EC_KEY_new()) == NULL)
1359			{
1360			ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1361			return NULL;
1362			}
1363		if (a)
1364			*a = ret;
1365		}
1366	else
1367		ret = *a;
1368
1369	if (!d2i_ECPKParameters(&ret->group, in, len))
1370		{
1371		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1372		return NULL;
1373		}
1374
1375	return ret;
1376	}
1377
1378EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1379	{
1380	EC_KEY *ret=NULL;
1381
1382	if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1383		{
1384		/* sorry, but a EC_GROUP-structur is necessary
1385                 * to set the public key */
1386		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1387		return 0;
1388		}
1389	ret = *a;
1390	if (ret->pub_key == NULL &&
1391		(ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1392		{
1393		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1394		return 0;
1395		}
1396	if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1397		{
1398		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1399		return 0;
1400		}
1401	/* save the point conversion form */
1402	ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1403	*in += len;
1404	return ret;
1405	}
1406
1407int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1408	{
1409        size_t buf_len=0;
1410	int new_buffer = 0;
1411
1412        if (a == NULL)
1413		{
1414		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1415		return 0;
1416		}
1417
1418        buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1419                              a->conv_form, NULL, 0, NULL);
1420
1421	if (out == NULL || buf_len == 0)
1422	/* out == NULL => just return the length of the octet string */
1423		return buf_len;
1424
1425	if (*out == NULL)
1426		{
1427		if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1428			{
1429			ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1430			return 0;
1431			}
1432		new_buffer = 1;
1433		}
1434        if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1435				*out, buf_len, NULL))
1436		{
1437		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1438		if (new_buffer)
1439			{
1440			OPENSSL_free(*out);
1441			*out = NULL;
1442			}
1443		return 0;
1444		}
1445	if (!new_buffer)
1446		*out += buf_len;
1447	return buf_len;
1448	}
1449