Import OpenSSL 0.9.8l
[dragonfly.git] / crypto / openssl / 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                 curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
533                 curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
534                 if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 
535                                          (int)group->seed_len))
536                         {
537                         ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
538                         goto err;
539                         }
540                 }
541         else
542                 {
543                 if (curve->seed)
544                         {
545                         ASN1_BIT_STRING_free(curve->seed);
546                         curve->seed = NULL;
547                         }
548                 }
549
550         ok = 1;
551
552 err:    if (buffer_1)
553                 OPENSSL_free(buffer_1);
554         if (buffer_2)
555                 OPENSSL_free(buffer_2);
556         if (tmp_1)
557                 BN_free(tmp_1);
558         if (tmp_2)
559                 BN_free(tmp_2);
560         return(ok);
561         }
562
563 static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
564                                               ECPARAMETERS *param)
565         {
566         int     ok=0;
567         size_t  len=0;
568         ECPARAMETERS   *ret=NULL;
569         BIGNUM         *tmp=NULL;
570         unsigned char  *buffer=NULL;
571         const EC_POINT *point=NULL;
572         point_conversion_form_t form;
573
574         if ((tmp = BN_new()) == NULL)
575                 {
576                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
577                 goto err;
578                 }
579
580         if (param == NULL)
581         {
582                 if ((ret = ECPARAMETERS_new()) == NULL)
583                         {
584                         ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, 
585                               ERR_R_MALLOC_FAILURE);
586                         goto err;
587                         }
588         }
589         else
590                 ret = param;
591
592         /* set the version (always one) */
593         ret->version = (long)0x1;
594
595         /* set the fieldID */
596         if (!ec_asn1_group2fieldid(group, ret->fieldID))
597                 {
598                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
599                 goto err;
600                 }
601
602         /* set the curve */
603         if (!ec_asn1_group2curve(group, ret->curve))
604                 {
605                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
606                 goto err;
607                 }
608
609         /* set the base point */
610         if ((point = EC_GROUP_get0_generator(group)) == NULL)
611                 {
612                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
613                 goto err;
614                 }
615
616         form = EC_GROUP_get_point_conversion_form(group);
617
618         len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
619         if (len == 0)
620                 {
621                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
622                 goto err;
623                 }
624         if ((buffer = OPENSSL_malloc(len)) == NULL)
625                 {
626                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
627                 goto err;
628                 }
629         if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
630                 {
631                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
632                 goto err;
633                 }
634         if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
635                 {
636                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
637                 goto err;
638                 }
639         if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
640                 {
641                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
642                 goto err;
643                 }
644
645         /* set the order */
646         if (!EC_GROUP_get_order(group, tmp, NULL))
647                 {
648                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
649                 goto err;
650                 }
651         ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
652         if (ret->order == NULL)
653                 {
654                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
655                 goto err;
656                 }
657
658         /* set the cofactor (optional) */
659         if (EC_GROUP_get_cofactor(group, tmp, NULL))
660                 {
661                 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
662                 if (ret->cofactor == NULL)
663                         {
664                         ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
665                         goto err;
666                         }
667                 }
668
669         ok = 1;
670
671 err :   if(!ok)
672                 {
673                 if (ret && !param)
674                         ECPARAMETERS_free(ret);
675                 ret = NULL;
676                 }
677         if (tmp)
678                 BN_free(tmp);
679         if (buffer)
680                 OPENSSL_free(buffer);
681         return(ret);
682         }
683
684 ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 
685                                            ECPKPARAMETERS *params)
686         {
687         int            ok = 1, tmp;
688         ECPKPARAMETERS *ret = params;
689
690         if (ret == NULL)
691                 {
692                 if ((ret = ECPKPARAMETERS_new()) == NULL)
693                         {
694                         ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, 
695                               ERR_R_MALLOC_FAILURE);
696                         return NULL;
697                         }
698                 }
699         else
700                 {
701                 if (ret->type == 0 && ret->value.named_curve)
702                         ASN1_OBJECT_free(ret->value.named_curve);
703                 else if (ret->type == 1 && ret->value.parameters)
704                         ECPARAMETERS_free(ret->value.parameters);
705                 }
706
707         if (EC_GROUP_get_asn1_flag(group))
708                 {
709                 /* use the asn1 OID to describe the
710                  * the elliptic curve parameters
711                  */
712                 tmp = EC_GROUP_get_curve_name(group);
713                 if (tmp)
714                         {
715                         ret->type = 0;
716                         if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
717                                 ok = 0;
718                         }
719                 else
720                         /* we don't kmow the nid => ERROR */
721                         ok = 0;
722                 }
723         else
724                 {       
725                 /* use the ECPARAMETERS structure */
726                 ret->type = 1;
727                 if ((ret->value.parameters = ec_asn1_group2parameters(
728                      group, NULL)) == NULL)
729                         ok = 0;
730                 }
731
732         if (!ok)
733                 {
734                 ECPKPARAMETERS_free(ret);
735                 return NULL;
736                 }
737         return ret;
738         }
739
740 static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
741         {
742         int                     ok = 0, tmp;
743         EC_GROUP                *ret = NULL;
744         BIGNUM                  *p = NULL, *a = NULL, *b = NULL;
745         EC_POINT                *point=NULL;
746         long                    field_bits;
747
748         if (!params->fieldID || !params->fieldID->fieldType || 
749             !params->fieldID->p.ptr)
750                 {
751                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
752                 goto err;
753                 }
754
755         /* now extract the curve parameters a and b */
756         if (!params->curve || !params->curve->a || 
757             !params->curve->a->data || !params->curve->b ||
758             !params->curve->b->data)
759                 {
760                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
761                 goto err;
762                 }
763         a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
764         if (a == NULL)
765                 {
766                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
767                 goto err;
768                 }
769         b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
770         if (b == NULL)
771                 {
772                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
773                 goto err;
774                 }
775
776         /* get the field parameters */
777         tmp = OBJ_obj2nid(params->fieldID->fieldType);
778
779         if (tmp == NID_X9_62_characteristic_two_field)
780                 {
781                 X9_62_CHARACTERISTIC_TWO *char_two;
782
783                 char_two = params->fieldID->p.char_two;
784
785                 field_bits = char_two->m;
786                 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
787                         {
788                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
789                         goto err;
790                         }
791
792                 if ((p = BN_new()) == NULL)
793                         {
794                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
795                         goto err;
796                         }
797
798                 /* get the base type */
799                 tmp = OBJ_obj2nid(char_two->type);
800
801                 if (tmp ==  NID_X9_62_tpBasis)
802                         {
803                         long tmp_long;
804
805                         if (!char_two->p.tpBasis)
806                                 {
807                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
808                                 goto err;
809                                 }
810
811                         tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
812
813                         if (!(char_two->m > tmp_long && tmp_long > 0))
814                                 {
815                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
816                                 goto err;
817                                 }
818                         
819                         /* create the polynomial */
820                         if (!BN_set_bit(p, (int)char_two->m))
821                                 goto err;
822                         if (!BN_set_bit(p, (int)tmp_long))
823                                 goto err;
824                         if (!BN_set_bit(p, 0))
825                                 goto err;
826                         }
827                 else if (tmp == NID_X9_62_ppBasis)
828                         {
829                         X9_62_PENTANOMIAL *penta;
830
831                         penta = char_two->p.ppBasis;
832                         if (!penta)
833                                 {
834                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
835                                 goto err;
836                                 }
837
838                         if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
839                                 {
840                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
841                                 goto err;
842                                 }
843                         
844                         /* create the polynomial */
845                         if (!BN_set_bit(p, (int)char_two->m)) goto err;
846                         if (!BN_set_bit(p, (int)penta->k1)) goto err;
847                         if (!BN_set_bit(p, (int)penta->k2)) goto err;
848                         if (!BN_set_bit(p, (int)penta->k3)) goto err;
849                         if (!BN_set_bit(p, 0)) goto err;
850                         }
851                 else if (tmp == NID_X9_62_onBasis)
852                         {
853                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
854                         goto err;
855                         }
856                 else /* error */
857                         {
858                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
859                         goto err;
860                         }
861
862                 /* create the EC_GROUP structure */
863                 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
864                 }
865         else if (tmp == NID_X9_62_prime_field)
866                 {
867                 /* we have a curve over a prime field */
868                 /* extract the prime number */
869                 if (!params->fieldID->p.prime)
870                         {
871                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
872                         goto err;
873                         }
874                 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
875                 if (p == NULL)
876                         {
877                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
878                         goto err;
879                         }
880
881                 if (BN_is_negative(p) || BN_is_zero(p))
882                         {
883                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
884                         goto err;
885                         }
886
887                 field_bits = BN_num_bits(p);
888                 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
889                         {
890                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
891                         goto err;
892                         }
893
894                 /* create the EC_GROUP structure */
895                 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
896                 }
897         else
898                 {
899                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
900                 goto err;
901                 }
902
903         if (ret == NULL)
904                 {
905                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
906                 goto err;
907                 }
908
909         /* extract seed (optional) */
910         if (params->curve->seed != NULL)
911                 {
912                 if (ret->seed != NULL)
913                         OPENSSL_free(ret->seed);
914                 if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
915                         {
916                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
917                               ERR_R_MALLOC_FAILURE);
918                         goto err;
919                         }
920                 memcpy(ret->seed, params->curve->seed->data, 
921                        params->curve->seed->length);
922                 ret->seed_len = params->curve->seed->length;
923                 }
924
925         if (!params->order || !params->base || !params->base->data)
926                 {
927                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
928                 goto err;
929                 }
930
931         if ((point = EC_POINT_new(ret)) == NULL) goto err;
932
933         /* set the point conversion form */
934         EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
935                                 (params->base->data[0] & ~0x01));
936
937         /* extract the ec point */
938         if (!EC_POINT_oct2point(ret, point, params->base->data, 
939                                 params->base->length, NULL))
940                 {
941                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
942                 goto err;
943                 }
944
945         /* extract the order */
946         if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
947                 {
948                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
949                 goto err;
950                 }
951         if (BN_is_negative(a) || BN_is_zero(a))
952                 {
953                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
954                 goto err;
955                 }
956         if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
957                 {
958                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
959                 goto err;
960                 }
961         
962         /* extract the cofactor (optional) */
963         if (params->cofactor == NULL)
964                 {
965                 if (b)
966                         {
967                         BN_free(b);
968                         b = NULL;
969                         }
970                 }
971         else
972                 if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
973                         {
974                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
975                         goto err;
976                         }
977         /* set the generator, order and cofactor (if present) */
978         if (!EC_GROUP_set_generator(ret, point, a, b))
979                 {
980                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
981                 goto err;
982                 }
983
984         ok = 1;
985
986 err:    if (!ok)
987                 {
988                 if (ret) 
989                         EC_GROUP_clear_free(ret);
990                 ret = NULL;
991                 }
992
993         if (p)  
994                 BN_free(p);
995         if (a)  
996                 BN_free(a);
997         if (b)  
998                 BN_free(b);
999         if (point)      
1000                 EC_POINT_free(point);
1001         return(ret);
1002 }
1003
1004 EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1005         {
1006         EC_GROUP *ret=NULL;
1007         int      tmp=0;
1008
1009         if (params == NULL)
1010                 {
1011                 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
1012                       EC_R_MISSING_PARAMETERS);
1013                 return NULL;
1014                 }
1015
1016         if (params->type == 0)
1017                 { /* the curve is given by an OID */
1018                 tmp = OBJ_obj2nid(params->value.named_curve);
1019                 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
1020                         {
1021                         ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
1022                               EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1023                         return NULL;
1024                         }
1025                 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1026                 }
1027         else if (params->type == 1)
1028                 { /* the parameters are given by a ECPARAMETERS
1029                    * structure */
1030                 ret = ec_asn1_parameters2group(params->value.parameters);
1031                 if (!ret)
1032                         {
1033                         ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1034                         return NULL;
1035                         }
1036                 EC_GROUP_set_asn1_flag(ret, 0x0);
1037                 }
1038         else if (params->type == 2)
1039                 { /* implicitlyCA */
1040                 return NULL;
1041                 }
1042         else
1043                 {
1044                 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1045                 return NULL;
1046                 }
1047
1048         return ret;
1049         }
1050
1051 /* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1052
1053 EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1054         {
1055         EC_GROUP        *group  = NULL;
1056         ECPKPARAMETERS  *params = NULL;
1057
1058         if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1059                 {
1060                 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1061                 ECPKPARAMETERS_free(params);
1062                 return NULL;
1063                 }
1064         
1065         if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1066                 {
1067                 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1068                 return NULL; 
1069                 }
1070
1071         
1072         if (a && *a)
1073                 EC_GROUP_clear_free(*a);
1074         if (a)
1075                 *a = group;
1076
1077         ECPKPARAMETERS_free(params);
1078         return(group);
1079         }
1080
1081 int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1082         {
1083         int             ret=0;
1084         ECPKPARAMETERS  *tmp = ec_asn1_group2pkparameters(a, NULL);
1085         if (tmp == NULL)
1086                 {
1087                 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1088                 return 0;
1089                 }
1090         if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1091                 {
1092                 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1093                 ECPKPARAMETERS_free(tmp);
1094                 return 0;
1095                 }       
1096         ECPKPARAMETERS_free(tmp);
1097         return(ret);
1098         }
1099
1100 /* some EC_KEY functions */
1101
1102 EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1103         {
1104         int             ok=0;
1105         EC_KEY          *ret=NULL;
1106         EC_PRIVATEKEY   *priv_key=NULL;
1107
1108         if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1109                 {
1110                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1111                 return NULL;
1112                 }
1113
1114         if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1115                 {
1116                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1117                 EC_PRIVATEKEY_free(priv_key);
1118                 return NULL;
1119                 }
1120
1121         if (a == NULL || *a == NULL)
1122                 {
1123                 if ((ret = EC_KEY_new()) == NULL)       
1124                         {
1125                         ECerr(EC_F_D2I_ECPRIVATEKEY,
1126                                  ERR_R_MALLOC_FAILURE);
1127                         goto err;
1128                         }
1129                 if (a)
1130                         *a = ret;
1131                 }
1132         else
1133                 ret = *a;
1134
1135         if (priv_key->parameters)
1136                 {
1137                 if (ret->group)
1138                         EC_GROUP_clear_free(ret->group);
1139                 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1140                 }
1141
1142         if (ret->group == NULL)
1143                 {
1144                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1145                 goto err;
1146                 }
1147
1148         ret->version = priv_key->version;
1149
1150         if (priv_key->privateKey)
1151                 {
1152                 ret->priv_key = BN_bin2bn(
1153                         M_ASN1_STRING_data(priv_key->privateKey),
1154                         M_ASN1_STRING_length(priv_key->privateKey),
1155                         ret->priv_key);
1156                 if (ret->priv_key == NULL)
1157                         {
1158                         ECerr(EC_F_D2I_ECPRIVATEKEY,
1159                               ERR_R_BN_LIB);
1160                         goto err;
1161                         }
1162                 }
1163         else
1164                 {
1165                 ECerr(EC_F_D2I_ECPRIVATEKEY, 
1166                       EC_R_MISSING_PRIVATE_KEY);
1167                 goto err;
1168                 }
1169
1170         if (priv_key->publicKey)
1171                 {
1172                 const unsigned char *pub_oct;
1173                 size_t pub_oct_len;
1174
1175                 if (ret->pub_key)
1176                         EC_POINT_clear_free(ret->pub_key);
1177                 ret->pub_key = EC_POINT_new(ret->group);
1178                 if (ret->pub_key == NULL)
1179                         {
1180                         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1181                         goto err;
1182                         }
1183                 pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
1184                 pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1185                 /* save the point conversion form */
1186                 ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
1187                 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1188                         pub_oct, pub_oct_len, NULL))
1189                         {
1190                         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1191                         goto err;
1192                         }
1193                 }
1194
1195         ok = 1;
1196 err:
1197         if (!ok)
1198                 {
1199                 if (ret)
1200                         EC_KEY_free(ret);
1201                 ret = NULL;
1202                 }
1203
1204         if (priv_key)
1205                 EC_PRIVATEKEY_free(priv_key);
1206
1207         return(ret);
1208         }
1209
1210 int     i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1211         {
1212         int             ret=0, ok=0;
1213         unsigned char   *buffer=NULL;
1214         size_t          buf_len=0, tmp_len;
1215         EC_PRIVATEKEY   *priv_key=NULL;
1216
1217         if (a == NULL || a->group == NULL || a->priv_key == NULL)
1218                 {
1219                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1220                       ERR_R_PASSED_NULL_PARAMETER);
1221                 goto err;
1222                 }
1223
1224         if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1225                 {
1226                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1227                       ERR_R_MALLOC_FAILURE);
1228                 goto err;
1229                 }
1230
1231         priv_key->version = a->version;
1232
1233         buf_len = (size_t)BN_num_bytes(a->priv_key);
1234         buffer = OPENSSL_malloc(buf_len);
1235         if (buffer == NULL)
1236                 {
1237                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1238                       ERR_R_MALLOC_FAILURE);
1239                 goto err;
1240                 }
1241         
1242         if (!BN_bn2bin(a->priv_key, buffer))
1243                 {
1244                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1245                 goto err;
1246                 }
1247
1248         if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1249                 {
1250                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1251                 goto err;
1252                 }       
1253
1254         if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1255                 {
1256                 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1257                         a->group, priv_key->parameters)) == NULL)
1258                         {
1259                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1260                         goto err;
1261                         }
1262                 }
1263
1264         if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1265                 {
1266                 priv_key->publicKey = M_ASN1_BIT_STRING_new();
1267                 if (priv_key->publicKey == NULL)
1268                         {
1269                         ECerr(EC_F_I2D_ECPRIVATEKEY,
1270                                 ERR_R_MALLOC_FAILURE);
1271                         goto err;
1272                         }
1273
1274                 tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 
1275                                 a->conv_form, NULL, 0, NULL);
1276
1277                 if (tmp_len > buf_len)
1278                         {
1279                         unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1280                         if (!tmp_buffer)
1281                                 {
1282                                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1283                                 goto err;
1284                                 }
1285                         buffer = tmp_buffer;
1286                         buf_len = tmp_len;
1287                         }
1288
1289                 if (!EC_POINT_point2oct(a->group, a->pub_key, 
1290                         a->conv_form, buffer, buf_len, NULL))
1291                         {
1292                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1293                         goto err;
1294                         }
1295
1296                 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
1297                 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1298                 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
1299                                 buf_len))
1300                         {
1301                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1302                         goto err;
1303                         }
1304                 }
1305
1306         if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1307                 {
1308                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1309                 goto err;
1310                 }
1311         ok=1;
1312 err:
1313         if (buffer)
1314                 OPENSSL_free(buffer);
1315         if (priv_key)
1316                 EC_PRIVATEKEY_free(priv_key);
1317         return(ok?ret:0);
1318         }
1319
1320 int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1321         {
1322         if (a == NULL)
1323                 {
1324                 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1325                 return 0;
1326                 }
1327         return i2d_ECPKParameters(a->group, out);
1328         }
1329
1330 EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1331         {
1332         EC_KEY   *ret;
1333
1334         if (in == NULL || *in == NULL)
1335                 {
1336                 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1337                 return NULL;
1338                 }
1339
1340         if (a == NULL || *a == NULL)
1341                 {
1342                 if ((ret = EC_KEY_new()) == NULL)
1343                         {
1344                         ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1345                         return NULL;
1346                         }
1347                 if (a)
1348                         *a = ret;
1349                 }
1350         else
1351                 ret = *a;
1352
1353         if (!d2i_ECPKParameters(&ret->group, in, len))
1354                 {
1355                 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1356                 return NULL;
1357                 }
1358
1359         return ret;
1360         }
1361
1362 EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1363         {
1364         EC_KEY *ret=NULL;
1365
1366         if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1367                 {
1368                 /* sorry, but a EC_GROUP-structur is necessary
1369                  * to set the public key */
1370                 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1371                 return 0;
1372                 }
1373         ret = *a;
1374         if (ret->pub_key == NULL && 
1375                 (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1376                 {
1377                 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1378                 return 0;
1379                 }
1380         if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1381                 {
1382                 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1383                 return 0;
1384                 }
1385         /* save the point conversion form */
1386         ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1387         *in += len;
1388         return ret;
1389         }
1390
1391 int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1392         {
1393         size_t buf_len=0;
1394         int new_buffer = 0;
1395
1396         if (a == NULL) 
1397                 {
1398                 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1399                 return 0;
1400                 }
1401
1402         buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
1403                               a->conv_form, NULL, 0, NULL);
1404
1405         if (out == NULL || buf_len == 0)
1406         /* out == NULL => just return the length of the octet string */
1407                 return buf_len;
1408
1409         if (*out == NULL)
1410                 {
1411                 if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1412                         {
1413                         ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1414                         return 0;
1415                         }
1416                 new_buffer = 1;
1417                 }
1418         if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1419                                 *out, buf_len, NULL))
1420                 {
1421                 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1422                 OPENSSL_free(*out);
1423                 *out = NULL;
1424                 return 0;
1425                 }
1426         if (!new_buffer)
1427                 *out += buf_len;
1428         return buf_len;
1429         }