Change array representation of binary polynomials to make GF2m part of
[openssl.git] / crypto / ec / ec_asn1.c
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                 }
841         else if (tmp == NID_X9_62_prime_field)
842                 {
843                 /* we have a curve over a prime field */
844                 /* extract the prime number */
845                 if (!params->fieldID->p.prime)
846                         {
847                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
848                         goto err;
849                         }
850                 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
851                 if (p == NULL)
852                         {
853                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
854                         goto err;
855                         }
856                 /* create the EC_GROUP structure */
857                 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
858                 }
859         else
860                 {
861                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
862                 goto err;
863                 }
864
865         if (ret == NULL)
866                 {
867                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
868                 goto err;
869                 }
870
871         /* extract seed (optional) */
872         if (params->curve->seed != NULL)
873                 {
874                 if (ret->seed != NULL)
875                         OPENSSL_free(ret->seed);
876                 if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
877                         {
878                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
879                               ERR_R_MALLOC_FAILURE);
880                         goto err;
881                         }
882                 memcpy(ret->seed, params->curve->seed->data, 
883                        params->curve->seed->length);
884                 ret->seed_len = params->curve->seed->length;
885                 }
886
887         if (!params->order || !params->base || !params->base->data)
888                 {
889                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
890                 goto err;
891                 }
892
893         if ((point = EC_POINT_new(ret)) == NULL) goto err;
894
895         /* set the point conversion form */
896         EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
897                                 (params->base->data[0] & ~0x01));
898
899         /* extract the ec point */
900         if (!EC_POINT_oct2point(ret, point, params->base->data, 
901                                 params->base->length, NULL))
902                 {
903                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
904                 goto err;
905                 }
906
907         /* extract the order */
908         if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
909                 {
910                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
911                 goto err;
912                 }
913         
914         /* extract the cofactor (optional) */
915         if (params->cofactor == NULL)
916                 {
917                 if (b)
918                         {
919                         BN_free(b);
920                         b = NULL;
921                         }
922                 }
923         else
924                 if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
925                         {
926                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
927                         goto err;
928                         }
929         /* set the generator, order and cofactor (if present) */
930         if (!EC_GROUP_set_generator(ret, point, a, b))
931                 {
932                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
933                 goto err;
934                 }
935
936         ok = 1;
937
938 err:    if (!ok)
939                 {
940                 if (ret) 
941                         EC_GROUP_clear_free(ret);
942                 ret = NULL;
943                 }
944
945         if (p)  
946                 BN_free(p);
947         if (a)  
948                 BN_free(a);
949         if (b)  
950                 BN_free(b);
951         if (point)      
952                 EC_POINT_free(point);
953         return(ret);
954 }
955
956 EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
957         {
958         EC_GROUP *ret=NULL;
959         int      tmp=0;
960
961         if (params == NULL)
962                 {
963                 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
964                       EC_R_MISSING_PARAMETERS);
965                 return NULL;
966                 }
967
968         if (params->type == 0)
969                 { /* the curve is given by an OID */
970                 tmp = OBJ_obj2nid(params->value.named_curve);
971                 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
972                         {
973                         ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
974                               EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
975                         return NULL;
976                         }
977                 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
978                 }
979         else if (params->type == 1)
980                 { /* the parameters are given by a ECPARAMETERS
981                    * structure */
982                 ret = ec_asn1_parameters2group(params->value.parameters);
983                 if (!ret)
984                         {
985                         ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
986                         return NULL;
987                         }
988                 EC_GROUP_set_asn1_flag(ret, 0x0);
989                 }
990         else if (params->type == 2)
991                 { /* implicitlyCA */
992                 return NULL;
993                 }
994         else
995                 {
996                 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
997                 return NULL;
998                 }
999
1000         return ret;
1001         }
1002
1003 /* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1004
1005 EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1006         {
1007         EC_GROUP        *group  = NULL;
1008         ECPKPARAMETERS  *params = NULL;
1009
1010         if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1011                 {
1012                 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1013                 ECPKPARAMETERS_free(params);
1014                 return NULL;
1015                 }
1016         
1017         if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1018                 {
1019                 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1020                 return NULL; 
1021                 }
1022
1023         
1024         if (a && *a)
1025                 EC_GROUP_clear_free(*a);
1026         if (a)
1027                 *a = group;
1028
1029         ECPKPARAMETERS_free(params);
1030         return(group);
1031         }
1032
1033 int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1034         {
1035         int             ret=0;
1036         ECPKPARAMETERS  *tmp = ec_asn1_group2pkparameters(a, NULL);
1037         if (tmp == NULL)
1038                 {
1039                 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1040                 return 0;
1041                 }
1042         if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1043                 {
1044                 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1045                 ECPKPARAMETERS_free(tmp);
1046                 return 0;
1047                 }       
1048         ECPKPARAMETERS_free(tmp);
1049         return(ret);
1050         }
1051
1052 /* some EC_KEY functions */
1053
1054 EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1055         {
1056         int             ok=0;
1057         EC_KEY          *ret=NULL;
1058         EC_PRIVATEKEY   *priv_key=NULL;
1059
1060         if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1061                 {
1062                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1063                 return NULL;
1064                 }
1065
1066         if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1067                 {
1068                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1069                 EC_PRIVATEKEY_free(priv_key);
1070                 return NULL;
1071                 }
1072
1073         if (a == NULL || *a == NULL)
1074                 {
1075                 if ((ret = EC_KEY_new()) == NULL)       
1076                         {
1077                         ECerr(EC_F_D2I_ECPRIVATEKEY,
1078                                  ERR_R_MALLOC_FAILURE);
1079                         goto err;
1080                         }
1081                 if (a)
1082                         *a = ret;
1083                 }
1084         else
1085                 ret = *a;
1086
1087         if (priv_key->parameters)
1088                 {
1089                 if (ret->group)
1090                         EC_GROUP_clear_free(ret->group);
1091                 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1092                 }
1093
1094         if (ret->group == NULL)
1095                 {
1096                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1097                 goto err;
1098                 }
1099
1100         ret->version = priv_key->version;
1101
1102         if (priv_key->privateKey)
1103                 {
1104                 ret->priv_key = BN_bin2bn(
1105                         M_ASN1_STRING_data(priv_key->privateKey),
1106                         M_ASN1_STRING_length(priv_key->privateKey),
1107                         ret->priv_key);
1108                 if (ret->priv_key == NULL)
1109                         {
1110                         ECerr(EC_F_D2I_ECPRIVATEKEY,
1111                               ERR_R_BN_LIB);
1112                         goto err;
1113                         }
1114                 }
1115         else
1116                 {
1117                 ECerr(EC_F_D2I_ECPRIVATEKEY, 
1118                       EC_R_MISSING_PRIVATE_KEY);
1119                 goto err;
1120                 }
1121
1122         if (priv_key->publicKey)
1123                 {
1124                 const unsigned char *pub_oct;
1125                 size_t pub_oct_len;
1126
1127                 if (ret->pub_key)
1128                         EC_POINT_clear_free(ret->pub_key);
1129                 ret->pub_key = EC_POINT_new(ret->group);
1130                 if (ret->pub_key == NULL)
1131                         {
1132                         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1133                         goto err;
1134                         }
1135                 pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
1136                 pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1137                 /* save the point conversion form */
1138                 ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
1139                 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1140                         pub_oct, pub_oct_len, NULL))
1141                         {
1142                         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1143                         goto err;
1144                         }
1145                 }
1146
1147         ok = 1;
1148 err:
1149         if (!ok)
1150                 {
1151                 if (ret)
1152                         EC_KEY_free(ret);
1153                 ret = NULL;
1154                 }
1155
1156         if (priv_key)
1157                 EC_PRIVATEKEY_free(priv_key);
1158
1159         return(ret);
1160         }
1161
1162 int     i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1163         {
1164         int             ret=0, ok=0;
1165         unsigned char   *buffer=NULL;
1166         size_t          buf_len=0, tmp_len;
1167         EC_PRIVATEKEY   *priv_key=NULL;
1168
1169         if (a == NULL || a->group == NULL || a->priv_key == NULL)
1170                 {
1171                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1172                       ERR_R_PASSED_NULL_PARAMETER);
1173                 goto err;
1174                 }
1175
1176         if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1177                 {
1178                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1179                       ERR_R_MALLOC_FAILURE);
1180                 goto err;
1181                 }
1182
1183         priv_key->version = a->version;
1184
1185         buf_len = (size_t)BN_num_bytes(a->priv_key);
1186         buffer = OPENSSL_malloc(buf_len);
1187         if (buffer == NULL)
1188                 {
1189                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1190                       ERR_R_MALLOC_FAILURE);
1191                 goto err;
1192                 }
1193         
1194         if (!BN_bn2bin(a->priv_key, buffer))
1195                 {
1196                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1197                 goto err;
1198                 }
1199
1200         if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1201                 {
1202                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1203                 goto err;
1204                 }       
1205
1206         if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1207                 {
1208                 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1209                         a->group, priv_key->parameters)) == NULL)
1210                         {
1211                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1212                         goto err;
1213                         }
1214                 }
1215
1216         if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1217                 {
1218                 priv_key->publicKey = M_ASN1_BIT_STRING_new();
1219                 if (priv_key->publicKey == NULL)
1220                         {
1221                         ECerr(EC_F_I2D_ECPRIVATEKEY,
1222                                 ERR_R_MALLOC_FAILURE);
1223                         goto err;
1224                         }
1225
1226                 tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 
1227                                 a->conv_form, NULL, 0, NULL);
1228
1229                 if (tmp_len > buf_len)
1230                         {
1231                         unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1232                         if (!tmp_buffer)
1233                                 {
1234                                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1235                                 goto err;
1236                                 }
1237                         buffer = tmp_buffer;
1238                         buf_len = tmp_len;
1239                         }
1240
1241                 if (!EC_POINT_point2oct(a->group, a->pub_key, 
1242                         a->conv_form, buffer, buf_len, NULL))
1243                         {
1244                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1245                         goto err;
1246                         }
1247
1248                 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
1249                                 buf_len))
1250                         {
1251                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1252                         goto err;
1253                         }
1254                 }
1255
1256         if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1257                 {
1258                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1259                 goto err;
1260                 }
1261         ok=1;
1262 err:
1263         if (buffer)
1264                 OPENSSL_free(buffer);
1265         if (priv_key)
1266                 EC_PRIVATEKEY_free(priv_key);
1267         return(ok?ret:0);
1268         }
1269
1270 int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1271         {
1272         if (a == NULL)
1273                 {
1274                 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1275                 return 0;
1276                 }
1277         return i2d_ECPKParameters(a->group, out);
1278         }
1279
1280 EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1281         {
1282         EC_KEY   *ret;
1283
1284         if (in == NULL || *in == NULL)
1285                 {
1286                 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1287                 return NULL;
1288                 }
1289
1290         if (a == NULL || *a == NULL)
1291                 {
1292                 if ((ret = EC_KEY_new()) == NULL)
1293                         {
1294                         ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1295                         return NULL;
1296                         }
1297                 if (a)
1298                         *a = ret;
1299                 }
1300         else
1301                 ret = *a;
1302
1303         if (!d2i_ECPKParameters(&ret->group, in, len))
1304                 {
1305                 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1306                 return NULL;
1307                 }
1308
1309         return ret;
1310         }
1311
1312 EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1313         {
1314         EC_KEY *ret=NULL;
1315
1316         if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1317                 {
1318                 /* sorry, but a EC_GROUP-structur is necessary
1319                  * to set the public key */
1320                 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1321                 return 0;
1322                 }
1323         ret = *a;
1324         if (ret->pub_key == NULL && 
1325                 (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1326                 {
1327                 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1328                 return 0;
1329                 }
1330         if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1331                 {
1332                 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1333                 return 0;
1334                 }
1335         /* save the point conversion form */
1336         ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1337         *in += len;
1338         return ret;
1339         }
1340
1341 int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1342         {
1343         size_t buf_len=0;
1344         int new_buffer = 0;
1345
1346         if (a == NULL) 
1347                 {
1348                 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1349                 return 0;
1350                 }
1351
1352         buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
1353                               a->conv_form, NULL, 0, NULL);
1354
1355         if (out == NULL || buf_len == 0)
1356         /* out == NULL => just return the length of the octet string */
1357                 return buf_len;
1358
1359         if (*out == NULL)
1360                 {
1361                 if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1362                         {
1363                         ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1364                         return 0;
1365                         }
1366                 new_buffer = 1;
1367                 }
1368         if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1369                                 *out, buf_len, NULL))
1370                 {
1371                 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1372                 OPENSSL_free(*out);
1373                 *out = NULL;
1374                 return 0;
1375                 }
1376         if (!new_buffer)
1377                 *out += buf_len;
1378         return buf_len;
1379         }