5693201a26a94c9e37030b15208e8c70e7760089
[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                 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         }