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