less specific interface for EC_GROUP_get_basis_type
[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
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_SIMPLE(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 */
719         if (!EC_GROUP_get_cofactor(group, tmp, NULL))
720                 {
721                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
722                 goto err;
723                 }
724         ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
725         if (ret->cofactor == NULL)
726                 {
727                 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
728                 goto err;
729                 }
730
731         ok = 1;
732
733 err :   if(!ok)
734                 {
735                 if (ret && !param)
736                         ECPARAMETERS_free(ret);
737                 ret = NULL;
738                 }
739         if (tmp)
740                 BN_free(tmp);
741         if (buffer)
742                 OPENSSL_free(buffer);
743         return(ret);
744         }
745
746 ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 
747                                            ECPKPARAMETERS *params)
748         {
749         int            ok = 1, tmp;
750         ECPKPARAMETERS *ret = params;
751
752         if (ret == NULL)
753                 {
754                 if ((ret = ECPKPARAMETERS_new()) == NULL)
755                         {
756                         ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, 
757                               ERR_R_MALLOC_FAILURE);
758                         return NULL;
759                         }
760                 }
761         else
762                 {
763                 if (ret->type == 0 && ret->value.named_curve)
764                         ASN1_OBJECT_free(ret->value.named_curve);
765                 else if (ret->type == 1 && ret->value.parameters)
766                         ECPARAMETERS_free(ret->value.parameters);
767                 }
768
769         if (EC_GROUP_get_asn1_flag(group))
770                 {
771                 /* use the asn1 OID to describe the
772                  * the elliptic curve parameters
773                  */
774                 tmp = EC_GROUP_get_nid(group);
775                 if (tmp)
776                         {
777                         ret->type = 0;
778                         if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
779                                 ok = 0;
780                         }
781                 else
782                         /* we don't kmow the nid => ERROR */
783                         ok = 0;
784                 }
785         else
786                 {       
787                 /* use the ECPARAMETERS structure */
788                 ret->type = 1;
789                 if ((ret->value.parameters = ec_asn1_group2parameters(
790                      group, NULL)) == NULL)
791                         ok = 0;
792                 }
793
794         if (!ok)
795                 {
796                 ECPKPARAMETERS_free(ret);
797                 return NULL;
798                 }
799         return ret;
800         }
801
802 static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
803         {
804         int                     ok = 0, tmp;
805         EC_GROUP                *ret = NULL;
806         BIGNUM                  *p = NULL, *a = NULL, *b = NULL;
807         EC_POINT                *point=NULL;
808         X9_62_CHARACTERISTIC_TWO *char_two = NULL;
809         X9_62_PENTANOMIAL       *penta = NULL;
810         unsigned char           *pp;
811
812         if (!params->fieldID || !params->fieldID->fieldType || 
813             !params->fieldID->parameters)
814                 {
815                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
816                 goto err;
817                 }
818
819         /* now extract the curve parameters a and b */
820         if (!params->curve || !params->curve->a || 
821             !params->curve->a->data || !params->curve->b ||
822             !params->curve->b->data)
823                 {
824                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
825                 goto err;
826                 }
827         a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
828         if (a == NULL)
829                 {
830                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
831                 goto err;
832                 }
833         b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
834         if (b == NULL)
835                 {
836                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
837                 goto err;
838                 }
839
840         /* get the field parameters */
841         tmp = OBJ_obj2nid(params->fieldID->fieldType);
842
843         if (tmp == NID_X9_62_characteristic_two_field)
844                 {
845                 ASN1_TYPE *parameters = params->fieldID->parameters;
846
847                 if (parameters->type !=  V_ASN1_SEQUENCE)
848                         {
849                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
850                         goto err;
851                         }
852
853                 if ((p = BN_new()) == NULL)
854                         {
855                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
856                               ERR_R_MALLOC_FAILURE);
857                         goto err;
858                         }
859
860                 /* extract the X9_62_CHARACTERISTIC_TWO object */
861                 pp = M_ASN1_STRING_data(parameters->value.sequence);
862                 char_two = d2i_X9_62_CHARACTERISTIC_TWO(NULL, 
863                         (const unsigned char **) &pp,
864                         M_ASN1_STRING_length(parameters->value.sequence));
865                 if (char_two == NULL)
866                         {
867                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
868                         goto err;
869                         }
870                 /* get the base type */
871                 tmp = OBJ_obj2nid(char_two->basis);
872
873                 if (tmp ==  NID_X9_62_tpBasis)
874                         {
875                         long tmp_long;
876
877                         if (char_two->parameters->type != V_ASN1_INTEGER ||
878                                 char_two->parameters->value.integer == NULL)
879                                 {
880                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
881                                         EC_R_ASN1_ERROR);
882                                 goto err;
883                                 }
884
885                         tmp_long = ASN1_INTEGER_get(char_two->parameters->value.integer);
886                         /* create the polynomial */
887                         if (!BN_set_bit(p, (int)char_two->m)) goto err;
888                         if (!BN_set_bit(p, (int)tmp_long)) goto err;
889                         if (!BN_set_bit(p, 0)) goto err;
890                         }
891                 else if (tmp == NID_X9_62_ppBasis)
892                         {
893                         if (char_two->parameters->type != V_ASN1_SEQUENCE ||
894                                 char_two->parameters->value.sequence == NULL)
895                                 {
896                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
897                                         EC_R_ASN1_ERROR);
898                                 goto err;
899                                 }
900                         /* extract the pentanomial data */
901                         pp = M_ASN1_STRING_data(
902                                 char_two->parameters->value.sequence);
903                         penta = d2i_X9_62_PENTANOMIAL(NULL,
904                                 (const unsigned char **) &pp,
905                                 M_ASN1_STRING_length(
906                                 char_two->parameters->value.sequence));
907                         if (penta == NULL)
908                                 {
909                                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
910                                         ERR_R_ASN1_LIB);
911                                 goto err;
912                                 }
913                         /* create the polynomial */
914                         if (!BN_set_bit(p, (int)char_two->m)) goto err;
915                         if (!BN_set_bit(p, (int)penta->k1)) goto err;
916                         if (!BN_set_bit(p, (int)penta->k2)) goto err;
917                         if (!BN_set_bit(p, (int)penta->k3)) goto err;
918                         if (!BN_set_bit(p, 0)) goto err;
919                         }
920                 else if (tmp == NID_X9_62_onBasis)
921                         {
922                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
923                                 EC_R_NOT_IMPLEMENTED);
924                         goto err;
925                         }
926                 else /* error */
927                         {
928                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
929                         goto err;
930                         }
931
932                 /* create the EC_GROUP structure */
933                 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
934                 if (ret == NULL)
935                         {
936                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
937                         goto err;
938                         }
939                 }
940         else if (tmp == NID_X9_62_prime_field)
941                 {
942                 /* we have a curve over a prime field */
943                 /* extract the prime number */
944                 if (params->fieldID->parameters->type != V_ASN1_INTEGER ||
945                     !params->fieldID->parameters->value.integer)
946                         {
947                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
948                         goto err;
949                         }
950                 p = ASN1_INTEGER_to_BN(params->fieldID->parameters->value.integer, NULL);
951                 if (p == NULL)
952                         {
953                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
954                         goto err;
955                         }
956                 /* create the EC_GROUP structure */
957                 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
958                 if (ret == NULL)
959                         {
960                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
961                         goto err;
962                         }
963                 }
964
965         /* extract seed (optional) */
966         if (params->curve->seed != NULL)
967                 {
968                 if (ret->seed != NULL)
969                         OPENSSL_free(ret->seed);
970                 if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
971                         {
972                         ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
973                               ERR_R_MALLOC_FAILURE);
974                         goto err;
975                         }
976                 memcpy(ret->seed, params->curve->seed->data, 
977                        params->curve->seed->length);
978                 ret->seed_len = params->curve->seed->length;
979                 }
980
981         /* extract the order, cofactor and generator */
982         if (!params->order || !params->cofactor || !params->base ||
983             !params->base->data)
984                 {
985                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
986                 goto err;
987                 }
988
989         if ((point = EC_POINT_new(ret)) == NULL) goto err;
990
991         a = ASN1_INTEGER_to_BN(params->order, a);
992         b = ASN1_INTEGER_to_BN(params->cofactor, b);
993         if (!a || !b)
994                 {
995                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
996                 goto err;
997                 }
998
999         if (!EC_POINT_oct2point(ret, point, params->base->data, 
1000                                 params->base->length, NULL))
1001                 {
1002                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
1003                 goto err;
1004                 }
1005
1006         /* set the point conversion form */
1007         EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
1008                                 (params->base->data[0] & ~0x01));
1009
1010         if (!EC_GROUP_set_generator(ret, point, a, b))
1011                 {
1012                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
1013                 goto err;
1014                 }
1015
1016         ok = 1;
1017
1018 err:    if (!ok)
1019                 {
1020                 if (ret) 
1021                         EC_GROUP_clear_free(ret);
1022                 ret = NULL;
1023                 }
1024
1025         if (p)  
1026                 BN_free(p);
1027         if (a)  
1028                 BN_free(a);
1029         if (b)  
1030                 BN_free(b);
1031         if (point)      
1032                 EC_POINT_free(point);
1033         if (char_two)
1034                 X9_62_CHARACTERISTIC_TWO_free(char_two);
1035         if (penta)
1036                 X9_62_PENTANOMIAL_free(penta);
1037         return(ret);
1038 }
1039
1040 EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1041         {
1042         EC_GROUP *ret=NULL;
1043         int      tmp=0;
1044
1045         if (params == NULL)
1046                 {
1047                 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
1048                       EC_R_MISSING_PARAMETERS);
1049                 return NULL;
1050                 }
1051
1052         if (params->type == 0)
1053                 { /* the curve is given by an OID */
1054                 tmp = OBJ_obj2nid(params->value.named_curve);
1055                 if ((ret = EC_GROUP_new_by_nid(tmp)) == NULL)
1056                         {
1057                         ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
1058                               EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1059                         return NULL;
1060                         }
1061                 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1062                 }
1063         else if (params->type == 1)
1064                 { /* the parameters are given by a ECPARAMETERS
1065                    * structure */
1066                 ret = ec_asn1_parameters2group(params->value.parameters);
1067                 if (!ret)
1068                         {
1069                         ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1070                         return NULL;
1071                         }
1072                 EC_GROUP_set_asn1_flag(ret, 0x0);
1073                 }
1074         else if (params->type == 2)
1075                 { /* implicitlyCA */
1076                 return NULL;
1077                 }
1078         else
1079                 {
1080                 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1081                 return NULL;
1082                 }
1083
1084         return ret;
1085         }
1086
1087 /* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1088
1089 EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1090         {
1091         EC_GROUP        *group  = NULL;
1092         ECPKPARAMETERS  *params = NULL;
1093
1094         if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1095                 {
1096                 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1097                 ECPKPARAMETERS_free(params);
1098                 return NULL;
1099                 }
1100         
1101         if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1102                 {
1103                 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1104                 return NULL; 
1105                 }
1106
1107         
1108         if (a && *a)
1109                 EC_GROUP_clear_free(*a);
1110         if (a)
1111                 *a = group;
1112
1113         ECPKPARAMETERS_free(params);
1114         return(group);
1115         }
1116
1117 int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1118         {
1119         int             ret=0;
1120         ECPKPARAMETERS  *tmp = ec_asn1_group2pkparameters(a, NULL);
1121         if (tmp == NULL)
1122                 {
1123                 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1124                 return 0;
1125                 }
1126         if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1127                 {
1128                 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1129                 ECPKPARAMETERS_free(tmp);
1130                 return 0;
1131                 }       
1132         ECPKPARAMETERS_free(tmp);
1133         return(ret);
1134         }
1135
1136 /* some EC_KEY functions */
1137
1138 EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1139         {
1140         int             ok=0;
1141         EC_KEY          *ret=NULL;
1142         EC_PRIVATEKEY   *priv_key=NULL;
1143
1144         if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1145                 {
1146                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1147                 return NULL;
1148                 }
1149
1150         if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1151                 {
1152                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1153                 EC_PRIVATEKEY_free(priv_key);
1154                 return NULL;
1155                 }
1156
1157         if (a == NULL || *a == NULL)
1158                 {
1159                 if ((ret = EC_KEY_new()) == NULL)       
1160                         {
1161                         ECerr(EC_F_D2I_ECPRIVATEKEY,
1162                                  ERR_R_MALLOC_FAILURE);
1163                         goto err;
1164                         }
1165                 if (a)
1166                         *a = ret;
1167                 }
1168         else
1169                 ret = *a;
1170
1171         if (priv_key->parameters)
1172                 {
1173                 if (ret->group)
1174                         EC_GROUP_clear_free(ret->group);
1175                 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1176                 }
1177
1178         if (ret->group == NULL)
1179                 {
1180                 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1181                 goto err;
1182                 }
1183
1184         ret->version = priv_key->version;
1185
1186         if (priv_key->privateKey)
1187                 {
1188                 ret->priv_key = BN_bin2bn(
1189                         M_ASN1_STRING_data(priv_key->privateKey),
1190                         M_ASN1_STRING_length(priv_key->privateKey),
1191                         ret->priv_key);
1192                 if (ret->priv_key == NULL)
1193                         {
1194                         ECerr(EC_F_D2I_ECPRIVATEKEY,
1195                               ERR_R_BN_LIB);
1196                         goto err;
1197                         }
1198                 }
1199         else
1200                 {
1201                 ECerr(EC_F_D2I_ECPRIVATEKEY, 
1202                       EC_R_MISSING_PRIVATE_KEY);
1203                 goto err;
1204                 }
1205
1206         if (priv_key->publicKey)
1207                 {
1208                 if (ret->pub_key)
1209                         EC_POINT_clear_free(ret->pub_key);
1210                 ret->pub_key = EC_POINT_new(ret->group);
1211                 if (ret->pub_key == NULL)
1212                         {
1213                         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1214                         goto err;
1215                         }
1216                 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1217                         M_ASN1_STRING_data(priv_key->publicKey),
1218                         M_ASN1_STRING_length(priv_key->publicKey), NULL))
1219                         {
1220                         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1221                         goto err;
1222                         }
1223                 }
1224
1225         ok = 1;
1226 err:
1227         if (!ok)
1228                 {
1229                 if (ret)
1230                         EC_KEY_free(ret);
1231                 ret = NULL;
1232                 }
1233
1234         if (priv_key)
1235                 EC_PRIVATEKEY_free(priv_key);
1236
1237         return(ret);
1238         }
1239
1240 int     i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1241         {
1242         int             ret=0, ok=0;
1243         unsigned char   *buffer=NULL;
1244         size_t          buf_len=0, tmp_len;
1245         EC_PRIVATEKEY   *priv_key=NULL;
1246
1247         if (a == NULL || a->group == NULL || a->priv_key == NULL)
1248                 {
1249                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1250                       ERR_R_PASSED_NULL_PARAMETER);
1251                 goto err;
1252                 }
1253
1254         if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1255                 {
1256                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1257                       ERR_R_MALLOC_FAILURE);
1258                 goto err;
1259                 }
1260
1261         priv_key->version = a->version;
1262
1263         buf_len = (size_t)BN_num_bytes(a->priv_key);
1264         buffer = OPENSSL_malloc(buf_len);
1265         if (buffer == NULL)
1266                 {
1267                 ECerr(EC_F_I2D_ECPRIVATEKEY,
1268                       ERR_R_MALLOC_FAILURE);
1269                 goto err;
1270                 }
1271         
1272         if (!BN_bn2bin(a->priv_key, buffer))
1273                 {
1274                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1275                 goto err;
1276                 }
1277
1278         if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1279                 {
1280                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1281                 goto err;
1282                 }       
1283
1284         if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1285                 {
1286                 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1287                         a->group, priv_key->parameters)) == NULL)
1288                         {
1289                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1290                         goto err;
1291                         }
1292                 }
1293
1294         if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1295                 {
1296                 priv_key->publicKey = M_ASN1_BIT_STRING_new();
1297                 if (priv_key->publicKey == NULL)
1298                         {
1299                         ECerr(EC_F_I2D_ECPRIVATEKEY,
1300                                 ERR_R_MALLOC_FAILURE);
1301                         goto err;
1302                         }
1303
1304                 tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 
1305                                 a->conv_form, NULL, 0, NULL);
1306
1307                 if (tmp_len > buf_len)
1308                         buffer = OPENSSL_realloc(buffer, tmp_len);
1309                 if (buffer == NULL)
1310                         {
1311                         ECerr(EC_F_I2D_ECPRIVATEKEY,
1312                                 ERR_R_MALLOC_FAILURE);
1313                         goto err;
1314                         }
1315
1316                 buf_len = tmp_len;
1317
1318                 if (!EC_POINT_point2oct(a->group, a->pub_key, 
1319                         a->conv_form, buffer, buf_len, NULL))
1320                         {
1321                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1322                         goto err;
1323                         }
1324
1325                 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
1326                                 buf_len))
1327                         {
1328                         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1329                         goto err;
1330                         }
1331                 }
1332
1333         if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1334                 {
1335                 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1336                 goto err;
1337                 }
1338         ok=1;
1339 err:
1340         if (buffer)
1341                 OPENSSL_free(buffer);
1342         if (priv_key)
1343                 EC_PRIVATEKEY_free(priv_key);
1344         return(ok?ret:0);
1345         }
1346
1347 int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1348         {
1349         if (a == NULL)
1350                 {
1351                 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1352                 return 0;
1353                 }
1354         return i2d_ECPKParameters(a->group, out);
1355         }
1356
1357 EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1358         {
1359         EC_GROUP *group;
1360         EC_KEY   *ret;
1361
1362         if (in == NULL || *in == NULL)
1363                 {
1364                 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1365                 return NULL;
1366                 }
1367
1368         group = d2i_ECPKParameters(NULL, in, len);
1369
1370         if (group == NULL)
1371                 {
1372                 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1373                 return NULL;
1374                 }
1375
1376         if (a == NULL || *a == NULL)
1377                 {
1378                 if ((ret = EC_KEY_new()) == NULL)
1379                         {
1380                         ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1381                         return NULL;
1382                         }
1383                 if (a)
1384                         *a = ret;
1385                 }
1386         else
1387                 ret = *a;
1388
1389         if (ret->group)
1390                 EC_GROUP_clear_free(ret->group);
1391
1392         ret->group = group;
1393         
1394         return ret;
1395         }
1396
1397 EC_KEY *ECPublicKey_set_octet_string(EC_KEY **a, const unsigned char **in, 
1398                                         long len)
1399         {
1400         EC_KEY *ret=NULL;
1401
1402         if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1403                 {
1404                 /* sorry, but a EC_GROUP-structur is necessary
1405                  * to set the public key */
1406                 ECerr(EC_F_ECPUBLICKEY_SET_OCTET, ERR_R_PASSED_NULL_PARAMETER);
1407                 return 0;
1408                 }
1409         ret = *a;
1410         if (ret->pub_key == NULL && 
1411                 (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1412                 {
1413                 ECerr(EC_F_ECPUBLICKEY_SET_OCTET, ERR_R_MALLOC_FAILURE);
1414                 return 0;
1415                 }
1416         if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1417                 {
1418                 ECerr(EC_F_ECPUBLICKEY_SET_OCTET, ERR_R_EC_LIB);
1419                 return 0;
1420                 }
1421         /* save the point conversion form */
1422         ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1423         return ret;
1424         }
1425
1426 int ECPublicKey_get_octet_string(EC_KEY *a, unsigned char **out)
1427         {
1428         size_t  buf_len=0;
1429
1430         if (a == NULL) 
1431                 {
1432                 ECerr(EC_F_ECPUBLICKEY_GET_OCTET, ERR_R_PASSED_NULL_PARAMETER);
1433                 return 0;
1434                 }
1435
1436         buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
1437                               a->conv_form, NULL, 0, NULL);
1438
1439         if (out == NULL || buf_len == 0)
1440         /* out == NULL => just return the length of the octet string */
1441                 return buf_len;
1442
1443         if (*out == NULL)
1444                 if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1445                         {
1446                         ECerr(EC_F_ECPUBLICKEY_GET_OCTET, 
1447                                 ERR_R_MALLOC_FAILURE);
1448                         return 0;
1449                         }
1450         if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1451                                 *out, buf_len, NULL))
1452                 {
1453                 ECerr(EC_F_ECPUBLICKEY_GET_OCTET, ERR_R_EC_LIB);
1454                 OPENSSL_free(*out);
1455                 *out = NULL;
1456                 return 0;
1457                 }
1458         return buf_len;
1459         }