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