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