Update LibreSSL from version 2.4.4 => 2.9.1
[dragonfly.git] / crypto / libressl / crypto / ec / ec_asn1.c
1 /* $OpenBSD: ec_asn1.c,v 1.31 2018/09/01 16:23:15 tb Exp $ */
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
61 #include <openssl/opensslconf.h>
62
63 #include "ec_lcl.h"
64 #include <openssl/err.h>
65 #include <openssl/asn1t.h>
66 #include <openssl/objects.h>
67
68 int 
69 EC_GROUP_get_basis_type(const EC_GROUP * group)
70 {
71         int i = 0;
72
73         if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
74             NID_X9_62_characteristic_two_field)
75                 /* everything else is currently not supported */
76                 return 0;
77
78         while (group->poly[i] != 0)
79                 i++;
80
81         if (i == 4)
82                 return NID_X9_62_ppBasis;
83         else if (i == 2)
84                 return NID_X9_62_tpBasis;
85         else
86                 /* everything else is currently not supported */
87                 return 0;
88 }
89
90 #ifndef OPENSSL_NO_EC2M
91 int 
92 EC_GROUP_get_trinomial_basis(const EC_GROUP * group, unsigned int *k)
93 {
94         if (group == NULL)
95                 return 0;
96
97         if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
98             NID_X9_62_characteristic_two_field
99             || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) {
100                 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
101                 return 0;
102         }
103         if (k)
104                 *k = group->poly[1];
105
106         return 1;
107 }
108
109 int 
110 EC_GROUP_get_pentanomial_basis(const EC_GROUP * group, unsigned int *k1,
111     unsigned int *k2, unsigned int *k3)
112 {
113         if (group == NULL)
114                 return 0;
115
116         if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
117             NID_X9_62_characteristic_two_field
118             || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) {
119                 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
120                 return 0;
121         }
122         if (k1)
123                 *k1 = group->poly[3];
124         if (k2)
125                 *k2 = group->poly[2];
126         if (k3)
127                 *k3 = group->poly[1];
128
129         return 1;
130 }
131 #endif
132
133 /* some structures needed for the asn1 encoding */
134 typedef struct x9_62_pentanomial_st {
135         long k1;
136         long k2;
137         long k3;
138 } X9_62_PENTANOMIAL;
139
140 typedef struct x9_62_characteristic_two_st {
141         long m;
142         ASN1_OBJECT *type;
143         union {
144                 char *ptr;
145                 /* NID_X9_62_onBasis */
146                 ASN1_NULL *onBasis;
147                 /* NID_X9_62_tpBasis */
148                 ASN1_INTEGER *tpBasis;
149                 /* NID_X9_62_ppBasis */
150                 X9_62_PENTANOMIAL *ppBasis;
151                 /* anything else */
152                 ASN1_TYPE *other;
153         } p;
154 } X9_62_CHARACTERISTIC_TWO;
155
156 typedef struct x9_62_fieldid_st {
157         ASN1_OBJECT *fieldType;
158         union {
159                 char *ptr;
160                 /* NID_X9_62_prime_field */
161                 ASN1_INTEGER *prime;
162                 /* NID_X9_62_characteristic_two_field */
163                 X9_62_CHARACTERISTIC_TWO *char_two;
164                 /* anything else */
165                 ASN1_TYPE *other;
166         } p;
167 } X9_62_FIELDID;
168
169 typedef struct x9_62_curve_st {
170         ASN1_OCTET_STRING *a;
171         ASN1_OCTET_STRING *b;
172         ASN1_BIT_STRING *seed;
173 } X9_62_CURVE;
174
175 typedef struct ec_parameters_st {
176         long version;
177         X9_62_FIELDID *fieldID;
178         X9_62_CURVE *curve;
179         ASN1_OCTET_STRING *base;
180         ASN1_INTEGER *order;
181         ASN1_INTEGER *cofactor;
182 } ECPARAMETERS;
183
184 struct ecpk_parameters_st {
185         int type;
186         union {
187                 ASN1_OBJECT *named_curve;
188                 ECPARAMETERS *parameters;
189                 ASN1_NULL *implicitlyCA;
190         } value;
191 } /* ECPKPARAMETERS */ ;
192
193 /* SEC1 ECPrivateKey */
194 typedef struct ec_privatekey_st {
195         long version;
196         ASN1_OCTET_STRING *privateKey;
197         ECPKPARAMETERS *parameters;
198         ASN1_BIT_STRING *publicKey;
199 } EC_PRIVATEKEY;
200
201 /* the OpenSSL ASN.1 definitions */
202 static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = {
203         {
204                 .flags = 0,
205                 .tag = 0,
206                 .offset = offsetof(X9_62_PENTANOMIAL, k1),
207                 .field_name = "k1",
208                 .item = &LONG_it,
209         },
210         {
211                 .flags = 0,
212                 .tag = 0,
213                 .offset = offsetof(X9_62_PENTANOMIAL, k2),
214                 .field_name = "k2",
215                 .item = &LONG_it,
216         },
217         {
218                 .flags = 0,
219                 .tag = 0,
220                 .offset = offsetof(X9_62_PENTANOMIAL, k3),
221                 .field_name = "k3",
222                 .item = &LONG_it,
223         },
224 };
225
226 const ASN1_ITEM X9_62_PENTANOMIAL_it = {
227         .itype = ASN1_ITYPE_SEQUENCE,
228         .utype = V_ASN1_SEQUENCE,
229         .templates = X9_62_PENTANOMIAL_seq_tt,
230         .tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
231         .funcs = NULL,
232         .size = sizeof(X9_62_PENTANOMIAL),
233         .sname = "X9_62_PENTANOMIAL",
234 };
235
236 X9_62_PENTANOMIAL *X9_62_PENTANOMIAL_new(void);
237 void X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a);
238
239 X9_62_PENTANOMIAL *
240 X9_62_PENTANOMIAL_new(void)
241 {
242         return (X9_62_PENTANOMIAL*)ASN1_item_new(&X9_62_PENTANOMIAL_it);
243 }
244
245 void
246 X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a)
247 {
248         ASN1_item_free((ASN1_VALUE *)a, &X9_62_PENTANOMIAL_it);
249 }
250
251 static const ASN1_TEMPLATE char_two_def_tt = {
252         .flags = 0,
253         .tag = 0,
254         .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other),
255         .field_name = "p.other",
256         .item = &ASN1_ANY_it,
257 };
258
259 static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = {
260         {
261                 .value = NID_X9_62_onBasis,
262                 .tt = {
263                         .flags = 0,
264                         .tag = 0,
265                         .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis),
266                         .field_name = "p.onBasis",
267                         .item = &ASN1_NULL_it,
268                 },
269         
270         },
271         {
272                 .value = NID_X9_62_tpBasis,
273                 .tt = {
274                         .flags = 0,
275                         .tag = 0,
276                         .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis),
277                         .field_name = "p.tpBasis",
278                         .item = &ASN1_INTEGER_it,
279                 },
280         
281         },
282         {
283                 .value = NID_X9_62_ppBasis,
284                 .tt = {
285                         .flags = 0,
286                         .tag = 0,
287                         .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis),
288                         .field_name = "p.ppBasis",
289                         .item = &X9_62_PENTANOMIAL_it,
290                 },
291         
292         },
293 };
294
295 static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = {
296         .flags = 0,
297         .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
298         .app_items = 0,
299         .tbl = X9_62_CHARACTERISTIC_TWO_adbtbl,
300         .tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE),
301         .default_tt = &char_two_def_tt,
302         .null_tt = NULL,
303 };
304
305 static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = {
306         {
307                 .flags = 0,
308                 .tag = 0,
309                 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, m),
310                 .field_name = "m",
311                 .item = &LONG_it,
312         },
313         {
314                 .flags = 0,
315                 .tag = 0,
316                 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
317                 .field_name = "type",
318                 .item = &ASN1_OBJECT_it,
319         },
320         {
321                 .flags = ASN1_TFLG_ADB_OID,
322                 .tag = -1,
323                 .offset = 0,
324                 .field_name = "X9_62_CHARACTERISTIC_TWO",
325                 .item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb,
326         },
327 };
328
329 const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = {
330         .itype = ASN1_ITYPE_SEQUENCE,
331         .utype = V_ASN1_SEQUENCE,
332         .templates = X9_62_CHARACTERISTIC_TWO_seq_tt,
333         .tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE),
334         .funcs = NULL,
335         .size = sizeof(X9_62_CHARACTERISTIC_TWO),
336         .sname = "X9_62_CHARACTERISTIC_TWO",
337 };
338
339 X9_62_CHARACTERISTIC_TWO *X9_62_CHARACTERISTIC_TWO_new(void);
340 void X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a);
341
342 X9_62_CHARACTERISTIC_TWO *
343 X9_62_CHARACTERISTIC_TWO_new(void)
344 {
345         return (X9_62_CHARACTERISTIC_TWO*)ASN1_item_new(&X9_62_CHARACTERISTIC_TWO_it);
346 }
347
348 void
349 X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a)
350 {
351         ASN1_item_free((ASN1_VALUE *)a, &X9_62_CHARACTERISTIC_TWO_it);
352 }
353
354 static const ASN1_TEMPLATE fieldID_def_tt = {
355         .flags = 0,
356         .tag = 0,
357         .offset = offsetof(X9_62_FIELDID, p.other),
358         .field_name = "p.other",
359         .item = &ASN1_ANY_it,
360 };
361
362 static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = {
363         {
364                 .value = NID_X9_62_prime_field,
365                 .tt = {
366                         .flags = 0,
367                         .tag = 0,
368                         .offset = offsetof(X9_62_FIELDID, p.prime),
369                         .field_name = "p.prime",
370                         .item = &ASN1_INTEGER_it,
371                 },
372         
373         },
374         {
375                 .value = NID_X9_62_characteristic_two_field,
376                 .tt = {
377                         .flags = 0,
378                         .tag = 0,
379                         .offset = offsetof(X9_62_FIELDID, p.char_two),
380                         .field_name = "p.char_two",
381                         .item = &X9_62_CHARACTERISTIC_TWO_it,
382                 },
383         
384         },
385 };
386
387 static const ASN1_ADB X9_62_FIELDID_adb = {
388         .flags = 0,
389         .offset = offsetof(X9_62_FIELDID, fieldType),
390         .app_items = 0,
391         .tbl = X9_62_FIELDID_adbtbl,
392         .tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE),
393         .default_tt = &fieldID_def_tt,
394         .null_tt = NULL,
395 };
396
397 static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = {
398         {
399                 .flags = 0,
400                 .tag = 0,
401                 .offset = offsetof(X9_62_FIELDID, fieldType),
402                 .field_name = "fieldType",
403                 .item = &ASN1_OBJECT_it,
404         },
405         {
406                 .flags = ASN1_TFLG_ADB_OID,
407                 .tag = -1,
408                 .offset = 0,
409                 .field_name = "X9_62_FIELDID",
410                 .item = (const ASN1_ITEM *)&X9_62_FIELDID_adb,
411         },
412 };
413
414 const ASN1_ITEM X9_62_FIELDID_it = {
415         .itype = ASN1_ITYPE_SEQUENCE,
416         .utype = V_ASN1_SEQUENCE,
417         .templates = X9_62_FIELDID_seq_tt,
418         .tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE),
419         .funcs = NULL,
420         .size = sizeof(X9_62_FIELDID),
421         .sname = "X9_62_FIELDID",
422 };
423
424 static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = {
425         {
426                 .flags = 0,
427                 .tag = 0,
428                 .offset = offsetof(X9_62_CURVE, a),
429                 .field_name = "a",
430                 .item = &ASN1_OCTET_STRING_it,
431         },
432         {
433                 .flags = 0,
434                 .tag = 0,
435                 .offset = offsetof(X9_62_CURVE, b),
436                 .field_name = "b",
437                 .item = &ASN1_OCTET_STRING_it,
438         },
439         {
440                 .flags = ASN1_TFLG_OPTIONAL,
441                 .tag = 0,
442                 .offset = offsetof(X9_62_CURVE, seed),
443                 .field_name = "seed",
444                 .item = &ASN1_BIT_STRING_it,
445         },
446 };
447
448 const ASN1_ITEM X9_62_CURVE_it = {
449         .itype = ASN1_ITYPE_SEQUENCE,
450         .utype = V_ASN1_SEQUENCE,
451         .templates = X9_62_CURVE_seq_tt,
452         .tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE),
453         .funcs = NULL,
454         .size = sizeof(X9_62_CURVE),
455         .sname = "X9_62_CURVE",
456 };
457
458 static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = {
459         {
460                 .flags = 0,
461                 .tag = 0,
462                 .offset = offsetof(ECPARAMETERS, version),
463                 .field_name = "version",
464                 .item = &LONG_it,
465         },
466         {
467                 .flags = 0,
468                 .tag = 0,
469                 .offset = offsetof(ECPARAMETERS, fieldID),
470                 .field_name = "fieldID",
471                 .item = &X9_62_FIELDID_it,
472         },
473         {
474                 .flags = 0,
475                 .tag = 0,
476                 .offset = offsetof(ECPARAMETERS, curve),
477                 .field_name = "curve",
478                 .item = &X9_62_CURVE_it,
479         },
480         {
481                 .flags = 0,
482                 .tag = 0,
483                 .offset = offsetof(ECPARAMETERS, base),
484                 .field_name = "base",
485                 .item = &ASN1_OCTET_STRING_it,
486         },
487         {
488                 .flags = 0,
489                 .tag = 0,
490                 .offset = offsetof(ECPARAMETERS, order),
491                 .field_name = "order",
492                 .item = &ASN1_INTEGER_it,
493         },
494         {
495                 .flags = ASN1_TFLG_OPTIONAL,
496                 .tag = 0,
497                 .offset = offsetof(ECPARAMETERS, cofactor),
498                 .field_name = "cofactor",
499                 .item = &ASN1_INTEGER_it,
500         },
501 };
502
503 const ASN1_ITEM ECPARAMETERS_it = {
504         .itype = ASN1_ITYPE_SEQUENCE,
505         .utype = V_ASN1_SEQUENCE,
506         .templates = ECPARAMETERS_seq_tt,
507         .tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE),
508         .funcs = NULL,
509         .size = sizeof(ECPARAMETERS),
510         .sname = "ECPARAMETERS",
511 };
512
513 ECPARAMETERS *ECPARAMETERS_new(void);
514 void ECPARAMETERS_free(ECPARAMETERS *a);
515
516 ECPARAMETERS *
517 ECPARAMETERS_new(void)
518 {
519         return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
520 }
521
522 void
523 ECPARAMETERS_free(ECPARAMETERS *a)
524 {
525         ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
526 }
527
528 static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = {
529         {
530                 .flags = 0,
531                 .tag = 0,
532                 .offset = offsetof(ECPKPARAMETERS, value.named_curve),
533                 .field_name = "value.named_curve",
534                 .item = &ASN1_OBJECT_it,
535         },
536         {
537                 .flags = 0,
538                 .tag = 0,
539                 .offset = offsetof(ECPKPARAMETERS, value.parameters),
540                 .field_name = "value.parameters",
541                 .item = &ECPARAMETERS_it,
542         },
543         {
544                 .flags = 0,
545                 .tag = 0,
546                 .offset = offsetof(ECPKPARAMETERS, value.implicitlyCA),
547                 .field_name = "value.implicitlyCA",
548                 .item = &ASN1_NULL_it,
549         },
550 };
551
552 const ASN1_ITEM ECPKPARAMETERS_it = {
553         .itype = ASN1_ITYPE_CHOICE,
554         .utype = offsetof(ECPKPARAMETERS, type),
555         .templates = ECPKPARAMETERS_ch_tt,
556         .tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE),
557         .funcs = NULL,
558         .size = sizeof(ECPKPARAMETERS),
559         .sname = "ECPKPARAMETERS",
560 };
561
562 ECPKPARAMETERS *ECPKPARAMETERS_new(void);
563 void ECPKPARAMETERS_free(ECPKPARAMETERS *a);
564 ECPKPARAMETERS *d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len);
565 int i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out);
566
567 ECPKPARAMETERS *
568 d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len)
569 {
570         return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
571             &ECPKPARAMETERS_it);
572 }
573
574 int
575 i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
576 {
577         return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
578 }
579
580 ECPKPARAMETERS *
581 ECPKPARAMETERS_new(void)
582 {
583         return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
584 }
585
586 void
587 ECPKPARAMETERS_free(ECPKPARAMETERS *a)
588 {
589         ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
590 }
591
592 static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = {
593         {
594                 .flags = 0,
595                 .tag = 0,
596                 .offset = offsetof(EC_PRIVATEKEY, version),
597                 .field_name = "version",
598                 .item = &LONG_it,
599         },
600         {
601                 .flags = 0,
602                 .tag = 0,
603                 .offset = offsetof(EC_PRIVATEKEY, privateKey),
604                 .field_name = "privateKey",
605                 .item = &ASN1_OCTET_STRING_it,
606         },
607         {
608                 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
609                 .tag = 0,
610                 .offset = offsetof(EC_PRIVATEKEY, parameters),
611                 .field_name = "parameters",
612                 .item = &ECPKPARAMETERS_it,
613         },
614         {
615                 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
616                 .tag = 1,
617                 .offset = offsetof(EC_PRIVATEKEY, publicKey),
618                 .field_name = "publicKey",
619                 .item = &ASN1_BIT_STRING_it,
620         },
621 };
622
623 const ASN1_ITEM EC_PRIVATEKEY_it = {
624         .itype = ASN1_ITYPE_SEQUENCE,
625         .utype = V_ASN1_SEQUENCE,
626         .templates = EC_PRIVATEKEY_seq_tt,
627         .tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
628         .funcs = NULL,
629         .size = sizeof(EC_PRIVATEKEY),
630         .sname = "EC_PRIVATEKEY",
631 };
632
633 EC_PRIVATEKEY *EC_PRIVATEKEY_new(void);
634 void EC_PRIVATEKEY_free(EC_PRIVATEKEY *a);
635 EC_PRIVATEKEY *d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len);
636 int i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out);
637
638 EC_PRIVATEKEY *
639 d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len)
640 {
641         return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
642             &EC_PRIVATEKEY_it);
643 }
644
645 int
646 i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
647 {
648         return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
649 }
650
651 EC_PRIVATEKEY *
652 EC_PRIVATEKEY_new(void)
653 {
654         return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
655 }
656
657 void
658 EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
659 {
660         ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
661 }
662
663 /* some declarations of internal function */
664
665 /* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
666 static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
667 /* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
668 static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
669 /* ec_asn1_parameters2group() creates a EC_GROUP object from a
670  * ECPARAMETERS object */
671 static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
672 /* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
673  * EC_GROUP object */
674 static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, ECPARAMETERS *);
675 /* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
676  * ECPKPARAMETERS object */
677 static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
678 /* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
679  * EC_GROUP object */
680 static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
681     ECPKPARAMETERS *);
682
683 /* the function definitions */
684
685 static int
686 ec_asn1_group2fieldid(const EC_GROUP * group, X9_62_FIELDID * field)
687 {
688         int ok = 0, nid;
689         BIGNUM *tmp = NULL;
690
691         if (group == NULL || field == NULL)
692                 return 0;
693
694         /* clear the old values (if necessary) */
695         if (field->fieldType != NULL)
696                 ASN1_OBJECT_free(field->fieldType);
697         if (field->p.other != NULL)
698                 ASN1_TYPE_free(field->p.other);
699
700         nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
701         /* set OID for the field */
702         if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
703                 ECerror(ERR_R_OBJ_LIB);
704                 goto err;
705         }
706         if (nid == NID_X9_62_prime_field) {
707                 if ((tmp = BN_new()) == NULL) {
708                         ECerror(ERR_R_MALLOC_FAILURE);
709                         goto err;
710                 }
711                 /* the parameters are specified by the prime number p */
712                 if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
713                         ECerror(ERR_R_EC_LIB);
714                         goto err;
715                 }
716                 /* set the prime number */
717                 field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
718                 if (field->p.prime == NULL) {
719                         ECerror(ERR_R_ASN1_LIB);
720                         goto err;
721                 }
722         } else                  /* nid == NID_X9_62_characteristic_two_field */
723 #ifdef OPENSSL_NO_EC2M
724         {
725                 ECerror(EC_R_GF2M_NOT_SUPPORTED);
726                 goto err;
727         }
728 #else
729         {
730                 int field_type;
731                 X9_62_CHARACTERISTIC_TWO *char_two;
732
733                 field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
734                 char_two = field->p.char_two;
735
736                 if (char_two == NULL) {
737                         ECerror(ERR_R_MALLOC_FAILURE);
738                         goto err;
739                 }
740                 char_two->m = (long) EC_GROUP_get_degree(group);
741
742                 field_type = EC_GROUP_get_basis_type(group);
743
744                 if (field_type == 0) {
745                         ECerror(ERR_R_EC_LIB);
746                         goto err;
747                 }
748                 /* set base type OID */
749                 if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
750                         ECerror(ERR_R_OBJ_LIB);
751                         goto err;
752                 }
753                 if (field_type == NID_X9_62_tpBasis) {
754                         unsigned int k;
755
756                         if (!EC_GROUP_get_trinomial_basis(group, &k))
757                                 goto err;
758
759                         char_two->p.tpBasis = ASN1_INTEGER_new();
760                         if (!char_two->p.tpBasis) {
761                                 ECerror(ERR_R_MALLOC_FAILURE);
762                                 goto err;
763                         }
764                         if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long) k)) {
765                                 ECerror(ERR_R_ASN1_LIB);
766                                 goto err;
767                         }
768                 } else if (field_type == NID_X9_62_ppBasis) {
769                         unsigned int k1, k2, k3;
770
771                         if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
772                                 goto err;
773
774                         char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
775                         if (!char_two->p.ppBasis) {
776                                 ECerror(ERR_R_MALLOC_FAILURE);
777                                 goto err;
778                         }
779                         /* set k? values */
780                         char_two->p.ppBasis->k1 = (long) k1;
781                         char_two->p.ppBasis->k2 = (long) k2;
782                         char_two->p.ppBasis->k3 = (long) k3;
783                 } else {        /* field_type == NID_X9_62_onBasis */
784                         /* for ONB the parameters are (asn1) NULL */
785                         char_two->p.onBasis = ASN1_NULL_new();
786                         if (!char_two->p.onBasis) {
787                                 ECerror(ERR_R_MALLOC_FAILURE);
788                                 goto err;
789                         }
790                 }
791         }
792 #endif
793
794         ok = 1;
795
796  err:
797         BN_free(tmp);
798         return (ok);
799 }
800
801 static int 
802 ec_asn1_group2curve(const EC_GROUP * group, X9_62_CURVE * curve)
803 {
804         int ok = 0, nid;
805         BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
806         unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL,
807         *b_buf = NULL;
808         size_t len_1, len_2;
809         unsigned char char_zero = 0;
810
811         if (!group || !curve || !curve->a || !curve->b)
812                 return 0;
813
814         if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
815                 ECerror(ERR_R_MALLOC_FAILURE);
816                 goto err;
817         }
818         nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
819
820         /* get a and b */
821         if (nid == NID_X9_62_prime_field) {
822                 if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
823                         ECerror(ERR_R_EC_LIB);
824                         goto err;
825                 }
826         }
827 #ifndef OPENSSL_NO_EC2M
828         else {                  /* nid == NID_X9_62_characteristic_two_field */
829                 if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
830                         ECerror(ERR_R_EC_LIB);
831                         goto err;
832                 }
833         }
834 #endif
835         len_1 = (size_t) BN_num_bytes(tmp_1);
836         len_2 = (size_t) BN_num_bytes(tmp_2);
837
838         if (len_1 == 0) {
839                 /* len_1 == 0 => a == 0 */
840                 a_buf = &char_zero;
841                 len_1 = 1;
842         } else {
843                 if ((buffer_1 = malloc(len_1)) == NULL) {
844                         ECerror(ERR_R_MALLOC_FAILURE);
845                         goto err;
846                 }
847                 if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
848                         ECerror(ERR_R_BN_LIB);
849                         goto err;
850                 }
851                 a_buf = buffer_1;
852         }
853
854         if (len_2 == 0) {
855                 /* len_2 == 0 => b == 0 */
856                 b_buf = &char_zero;
857                 len_2 = 1;
858         } else {
859                 if ((buffer_2 = malloc(len_2)) == NULL) {
860                         ECerror(ERR_R_MALLOC_FAILURE);
861                         goto err;
862                 }
863                 if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
864                         ECerror(ERR_R_BN_LIB);
865                         goto err;
866                 }
867                 b_buf = buffer_2;
868         }
869
870         /* set a and b */
871         if (!ASN1_STRING_set(curve->a, a_buf, len_1) ||
872             !ASN1_STRING_set(curve->b, b_buf, len_2)) {
873                 ECerror(ERR_R_ASN1_LIB);
874                 goto err;
875         }
876         /* set the seed (optional) */
877         if (group->seed) {
878                 if (!curve->seed)
879                         if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
880                                 ECerror(ERR_R_MALLOC_FAILURE);
881                                 goto err;
882                         }
883                 curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
884                 curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
885                 if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
886                         (int) group->seed_len)) {
887                         ECerror(ERR_R_ASN1_LIB);
888                         goto err;
889                 }
890         } else {
891                 if (curve->seed) {
892                         ASN1_BIT_STRING_free(curve->seed);
893                         curve->seed = NULL;
894                 }
895         }
896
897         ok = 1;
898
899  err:
900         free(buffer_1);
901         free(buffer_2);
902         BN_free(tmp_1);
903         BN_free(tmp_2);
904         return (ok);
905 }
906
907 static ECPARAMETERS *
908 ec_asn1_group2parameters(const EC_GROUP * group, ECPARAMETERS * param)
909 {
910         int ok = 0;
911         size_t len = 0;
912         ECPARAMETERS *ret = NULL;
913         BIGNUM *tmp = NULL;
914         unsigned char *buffer = NULL;
915         const EC_POINT *point = NULL;
916         point_conversion_form_t form;
917
918         if ((tmp = BN_new()) == NULL) {
919                 ECerror(ERR_R_MALLOC_FAILURE);
920                 goto err;
921         }
922         if (param == NULL) {
923                 if ((ret = ECPARAMETERS_new()) == NULL) {
924                         ECerror(ERR_R_MALLOC_FAILURE);
925                         goto err;
926                 }
927         } else
928                 ret = param;
929
930         /* set the version (always one) */
931         ret->version = (long) 0x1;
932
933         /* set the fieldID */
934         if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
935                 ECerror(ERR_R_EC_LIB);
936                 goto err;
937         }
938         /* set the curve */
939         if (!ec_asn1_group2curve(group, ret->curve)) {
940                 ECerror(ERR_R_EC_LIB);
941                 goto err;
942         }
943         /* set the base point */
944         if ((point = EC_GROUP_get0_generator(group)) == NULL) {
945                 ECerror(EC_R_UNDEFINED_GENERATOR);
946                 goto err;
947         }
948         form = EC_GROUP_get_point_conversion_form(group);
949
950         len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
951         if (len == 0) {
952                 ECerror(ERR_R_EC_LIB);
953                 goto err;
954         }
955         if ((buffer = malloc(len)) == NULL) {
956                 ECerror(ERR_R_MALLOC_FAILURE);
957                 goto err;
958         }
959         if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
960                 ECerror(ERR_R_EC_LIB);
961                 goto err;
962         }
963         if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
964                 ECerror(ERR_R_MALLOC_FAILURE);
965                 goto err;
966         }
967         if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
968                 ECerror(ERR_R_ASN1_LIB);
969                 goto err;
970         }
971         /* set the order */
972         if (!EC_GROUP_get_order(group, tmp, NULL)) {
973                 ECerror(ERR_R_EC_LIB);
974                 goto err;
975         }
976         ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
977         if (ret->order == NULL) {
978                 ECerror(ERR_R_ASN1_LIB);
979                 goto err;
980         }
981         /* set the cofactor (optional) */
982         if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
983                 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
984                 if (ret->cofactor == NULL) {
985                         ECerror(ERR_R_ASN1_LIB);
986                         goto err;
987                 }
988         }
989         ok = 1;
990
991  err:
992         if (!ok) {
993                 if (ret && !param)
994                         ECPARAMETERS_free(ret);
995                 ret = NULL;
996         }
997         BN_free(tmp);
998         free(buffer);
999         return (ret);
1000 }
1001
1002 ECPKPARAMETERS *
1003 ec_asn1_group2pkparameters(const EC_GROUP * group, ECPKPARAMETERS * params)
1004 {
1005         int ok = 1, tmp;
1006         ECPKPARAMETERS *ret = params;
1007
1008         if (ret == NULL) {
1009                 if ((ret = ECPKPARAMETERS_new()) == NULL) {
1010                         ECerror(ERR_R_MALLOC_FAILURE);
1011                         return NULL;
1012                 }
1013         } else {
1014                 if (ret->type == 0 && ret->value.named_curve)
1015                         ASN1_OBJECT_free(ret->value.named_curve);
1016                 else if (ret->type == 1 && ret->value.parameters)
1017                         ECPARAMETERS_free(ret->value.parameters);
1018         }
1019
1020         if (EC_GROUP_get_asn1_flag(group)) {
1021                 /*
1022                  * use the asn1 OID to describe the elliptic curve
1023                  * parameters
1024                  */
1025                 tmp = EC_GROUP_get_curve_name(group);
1026                 if (tmp) {
1027                         ret->type = 0;
1028                         if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
1029                                 ok = 0;
1030                 } else
1031                         /* we don't kmow the nid => ERROR */
1032                         ok = 0;
1033         } else {
1034                 /* use the ECPARAMETERS structure */
1035                 ret->type = 1;
1036                 if ((ret->value.parameters = ec_asn1_group2parameters(
1037                             group, NULL)) == NULL)
1038                         ok = 0;
1039         }
1040
1041         if (!ok) {
1042                 ECPKPARAMETERS_free(ret);
1043                 return NULL;
1044         }
1045         return ret;
1046 }
1047
1048 static EC_GROUP *
1049 ec_asn1_parameters2group(const ECPARAMETERS * params)
1050 {
1051         int ok = 0, tmp;
1052         EC_GROUP *ret = NULL;
1053         BIGNUM *p = NULL, *a = NULL, *b = NULL;
1054         EC_POINT *point = NULL;
1055         long field_bits;
1056
1057         if (!params->fieldID || !params->fieldID->fieldType ||
1058             !params->fieldID->p.ptr) {
1059                 ECerror(EC_R_ASN1_ERROR);
1060                 goto err;
1061         }
1062         /* now extract the curve parameters a and b */
1063         if (!params->curve || !params->curve->a ||
1064             !params->curve->a->data || !params->curve->b ||
1065             !params->curve->b->data) {
1066                 ECerror(EC_R_ASN1_ERROR);
1067                 goto err;
1068         }
1069         a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
1070         if (a == NULL) {
1071                 ECerror(ERR_R_BN_LIB);
1072                 goto err;
1073         }
1074         b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
1075         if (b == NULL) {
1076                 ECerror(ERR_R_BN_LIB);
1077                 goto err;
1078         }
1079         /* get the field parameters */
1080         tmp = OBJ_obj2nid(params->fieldID->fieldType);
1081         if (tmp == NID_X9_62_characteristic_two_field)
1082 #ifdef OPENSSL_NO_EC2M
1083         {
1084                 ECerror(EC_R_GF2M_NOT_SUPPORTED);
1085                 goto err;
1086         }
1087 #else
1088         {
1089                 X9_62_CHARACTERISTIC_TWO *char_two;
1090
1091                 char_two = params->fieldID->p.char_two;
1092
1093                 field_bits = char_two->m;
1094                 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
1095                         ECerror(EC_R_FIELD_TOO_LARGE);
1096                         goto err;
1097                 }
1098                 if ((p = BN_new()) == NULL) {
1099                         ECerror(ERR_R_MALLOC_FAILURE);
1100                         goto err;
1101                 }
1102                 /* get the base type */
1103                 tmp = OBJ_obj2nid(char_two->type);
1104
1105                 if (tmp == NID_X9_62_tpBasis) {
1106                         long tmp_long;
1107
1108                         if (!char_two->p.tpBasis) {
1109                                 ECerror(EC_R_ASN1_ERROR);
1110                                 goto err;
1111                         }
1112                         tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
1113
1114                         if (!(char_two->m > tmp_long && tmp_long > 0)) {
1115                                 ECerror(EC_R_INVALID_TRINOMIAL_BASIS);
1116                                 goto err;
1117                         }
1118                         /* create the polynomial */
1119                         if (!BN_set_bit(p, (int) char_two->m))
1120                                 goto err;
1121                         if (!BN_set_bit(p, (int) tmp_long))
1122                                 goto err;
1123                         if (!BN_set_bit(p, 0))
1124                                 goto err;
1125                 } else if (tmp == NID_X9_62_ppBasis) {
1126                         X9_62_PENTANOMIAL *penta;
1127
1128                         penta = char_two->p.ppBasis;
1129                         if (!penta) {
1130                                 ECerror(EC_R_ASN1_ERROR);
1131                                 goto err;
1132                         }
1133                         if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) {
1134                                 ECerror(EC_R_INVALID_PENTANOMIAL_BASIS);
1135                                 goto err;
1136                         }
1137                         /* create the polynomial */
1138                         if (!BN_set_bit(p, (int) char_two->m))
1139                                 goto err;
1140                         if (!BN_set_bit(p, (int) penta->k1))
1141                                 goto err;
1142                         if (!BN_set_bit(p, (int) penta->k2))
1143                                 goto err;
1144                         if (!BN_set_bit(p, (int) penta->k3))
1145                                 goto err;
1146                         if (!BN_set_bit(p, 0))
1147                                 goto err;
1148                 } else if (tmp == NID_X9_62_onBasis) {
1149                         ECerror(EC_R_NOT_IMPLEMENTED);
1150                         goto err;
1151                 } else {        /* error */
1152                         ECerror(EC_R_ASN1_ERROR);
1153                         goto err;
1154                 }
1155
1156                 /* create the EC_GROUP structure */
1157                 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
1158         }
1159 #endif
1160         else if (tmp == NID_X9_62_prime_field) {
1161                 /* we have a curve over a prime field */
1162                 /* extract the prime number */
1163                 if (!params->fieldID->p.prime) {
1164                         ECerror(EC_R_ASN1_ERROR);
1165                         goto err;
1166                 }
1167                 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
1168                 if (p == NULL) {
1169                         ECerror(ERR_R_ASN1_LIB);
1170                         goto err;
1171                 }
1172                 if (BN_is_negative(p) || BN_is_zero(p)) {
1173                         ECerror(EC_R_INVALID_FIELD);
1174                         goto err;
1175                 }
1176                 field_bits = BN_num_bits(p);
1177                 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
1178                         ECerror(EC_R_FIELD_TOO_LARGE);
1179                         goto err;
1180                 }
1181                 /* create the EC_GROUP structure */
1182                 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
1183         } else {
1184                 ECerror(EC_R_INVALID_FIELD);
1185                 goto err;
1186         }
1187
1188         if (ret == NULL) {
1189                 ECerror(ERR_R_EC_LIB);
1190                 goto err;
1191         }
1192         /* extract seed (optional) */
1193         if (params->curve->seed != NULL) {
1194                 free(ret->seed);
1195                 if (!(ret->seed = malloc(params->curve->seed->length))) {
1196                         ECerror(ERR_R_MALLOC_FAILURE);
1197                         goto err;
1198                 }
1199                 memcpy(ret->seed, params->curve->seed->data,
1200                     params->curve->seed->length);
1201                 ret->seed_len = params->curve->seed->length;
1202         }
1203         if (!params->order || !params->base || !params->base->data) {
1204                 ECerror(EC_R_ASN1_ERROR);
1205                 goto err;
1206         }
1207         if ((point = EC_POINT_new(ret)) == NULL)
1208                 goto err;
1209
1210         /* set the point conversion form */
1211         EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
1212             (params->base->data[0] & ~0x01));
1213
1214         /* extract the ec point */
1215         if (!EC_POINT_oct2point(ret, point, params->base->data,
1216                 params->base->length, NULL)) {
1217                 ECerror(ERR_R_EC_LIB);
1218                 goto err;
1219         }
1220         /* extract the order */
1221         if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
1222                 ECerror(ERR_R_ASN1_LIB);
1223                 goto err;
1224         }
1225         if (BN_is_negative(a) || BN_is_zero(a)) {
1226                 ECerror(EC_R_INVALID_GROUP_ORDER);
1227                 goto err;
1228         }
1229         if (BN_num_bits(a) > (int) field_bits + 1) {    /* Hasse bound */
1230                 ECerror(EC_R_INVALID_GROUP_ORDER);
1231                 goto err;
1232         }
1233         /* extract the cofactor (optional) */
1234         if (params->cofactor == NULL) {
1235                 BN_free(b);
1236                 b = NULL;
1237         } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
1238                 ECerror(ERR_R_ASN1_LIB);
1239                 goto err;
1240         }
1241         /* set the generator, order and cofactor (if present) */
1242         if (!EC_GROUP_set_generator(ret, point, a, b)) {
1243                 ECerror(ERR_R_EC_LIB);
1244                 goto err;
1245         }
1246         ok = 1;
1247
1248  err:
1249         if (!ok) {
1250                 EC_GROUP_clear_free(ret);
1251                 ret = NULL;
1252         }
1253         BN_free(p);
1254         BN_free(a);
1255         BN_free(b);
1256         EC_POINT_free(point);
1257         return (ret);
1258 }
1259
1260 EC_GROUP *
1261 ec_asn1_pkparameters2group(const ECPKPARAMETERS * params)
1262 {
1263         EC_GROUP *ret = NULL;
1264         int tmp = 0;
1265
1266         if (params == NULL) {
1267                 ECerror(EC_R_MISSING_PARAMETERS);
1268                 return NULL;
1269         }
1270         if (params->type == 0) {/* the curve is given by an OID */
1271                 tmp = OBJ_obj2nid(params->value.named_curve);
1272                 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
1273                         ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1274                         return NULL;
1275                 }
1276                 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1277         } else if (params->type == 1) { /* the parameters are given by a
1278                                          * ECPARAMETERS structure */
1279                 ret = ec_asn1_parameters2group(params->value.parameters);
1280                 if (!ret) {
1281                         ECerror(ERR_R_EC_LIB);
1282                         return NULL;
1283                 }
1284                 EC_GROUP_set_asn1_flag(ret, 0x0);
1285         } else if (params->type == 2) { /* implicitlyCA */
1286                 return NULL;
1287         } else {
1288                 ECerror(EC_R_ASN1_ERROR);
1289                 return NULL;
1290         }
1291
1292         return ret;
1293 }
1294
1295 /* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1296
1297 EC_GROUP *
1298 d2i_ECPKParameters(EC_GROUP ** a, const unsigned char **in, long len)
1299 {
1300         EC_GROUP *group = NULL;
1301         ECPKPARAMETERS *params = NULL;
1302
1303         if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
1304                 ECerror(EC_R_D2I_ECPKPARAMETERS_FAILURE);
1305                 goto err;
1306         }
1307         if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1308                 ECerror(EC_R_PKPARAMETERS2GROUP_FAILURE);
1309                 goto err;
1310         }
1311
1312         if (a != NULL) {
1313                 EC_GROUP_clear_free(*a);
1314                 *a = group;
1315         }
1316
1317  err:
1318         ECPKPARAMETERS_free(params);
1319         return (group);
1320 }
1321
1322 int 
1323 i2d_ECPKParameters(const EC_GROUP * a, unsigned char **out)
1324 {
1325         int ret = 0;
1326         ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1327         if (tmp == NULL) {
1328                 ECerror(EC_R_GROUP2PKPARAMETERS_FAILURE);
1329                 return 0;
1330         }
1331         if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
1332                 ECerror(EC_R_I2D_ECPKPARAMETERS_FAILURE);
1333                 ECPKPARAMETERS_free(tmp);
1334                 return 0;
1335         }
1336         ECPKPARAMETERS_free(tmp);
1337         return (ret);
1338 }
1339
1340 /* some EC_KEY functions */
1341
1342 EC_KEY *
1343 d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
1344 {
1345         EC_KEY *ret = NULL;
1346         EC_PRIVATEKEY *priv_key = NULL;
1347
1348         if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1349                 ECerror(ERR_R_MALLOC_FAILURE);
1350                 return NULL;
1351         }
1352         if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) {
1353                 ECerror(ERR_R_EC_LIB);
1354                 EC_PRIVATEKEY_free(priv_key);
1355                 return NULL;
1356         }
1357         if (a == NULL || *a == NULL) {
1358                 if ((ret = EC_KEY_new()) == NULL) {
1359                         ECerror(ERR_R_MALLOC_FAILURE);
1360                         goto err;
1361                 }
1362         } else
1363                 ret = *a;
1364
1365         if (priv_key->parameters) {
1366                 EC_GROUP_clear_free(ret->group);
1367                 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1368         }
1369         if (ret->group == NULL) {
1370                 ECerror(ERR_R_EC_LIB);
1371                 goto err;
1372         }
1373         ret->version = priv_key->version;
1374
1375         if (priv_key->privateKey) {
1376                 ret->priv_key = BN_bin2bn(
1377                     ASN1_STRING_data(priv_key->privateKey),
1378                     ASN1_STRING_length(priv_key->privateKey),
1379                     ret->priv_key);
1380                 if (ret->priv_key == NULL) {
1381                         ECerror(ERR_R_BN_LIB);
1382                         goto err;
1383                 }
1384         } else {
1385                 ECerror(EC_R_MISSING_PRIVATE_KEY);
1386                 goto err;
1387         }
1388
1389         if (ret->pub_key)
1390                 EC_POINT_clear_free(ret->pub_key);
1391         ret->pub_key = EC_POINT_new(ret->group);
1392         if (ret->pub_key == NULL) {
1393                 ECerror(ERR_R_EC_LIB);
1394                 goto err;
1395         }
1396
1397         if (priv_key->publicKey) {
1398                 const unsigned char *pub_oct;
1399                 size_t pub_oct_len;
1400
1401                 pub_oct = ASN1_STRING_data(priv_key->publicKey);
1402                 pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
1403                 if (pub_oct == NULL || pub_oct_len <= 0) {
1404                         ECerror(EC_R_BUFFER_TOO_SMALL);
1405                         goto err;
1406                 }
1407
1408                 /* save the point conversion form */
1409                 ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
1410                 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1411                         pub_oct, pub_oct_len, NULL)) {
1412                         ECerror(ERR_R_EC_LIB);
1413                         goto err;
1414                 }
1415         } else {
1416                 if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key,
1417                         NULL, NULL, NULL)) {
1418                         ECerror(ERR_R_EC_LIB);
1419                         goto err;
1420                 }
1421                 /* Remember the original private-key-only encoding. */
1422                 ret->enc_flag |= EC_PKEY_NO_PUBKEY;
1423         }
1424
1425         EC_PRIVATEKEY_free(priv_key);
1426         if (a != NULL)
1427                 *a = ret;
1428         return (ret);
1429
1430  err:
1431         if (a == NULL || *a != ret)
1432                 EC_KEY_free(ret);
1433         if (priv_key)
1434                 EC_PRIVATEKEY_free(priv_key);
1435
1436         return (NULL);
1437 }
1438
1439 int 
1440 i2d_ECPrivateKey(EC_KEY * a, unsigned char **out)
1441 {
1442         int ret = 0, ok = 0;
1443         unsigned char *buffer = NULL;
1444         size_t buf_len = 0, tmp_len;
1445         EC_PRIVATEKEY *priv_key = NULL;
1446
1447         if (a == NULL || a->group == NULL || a->priv_key == NULL ||
1448             (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
1449                 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1450                 goto err;
1451         }
1452         if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1453                 ECerror(ERR_R_MALLOC_FAILURE);
1454                 goto err;
1455         }
1456         priv_key->version = a->version;
1457
1458         buf_len = (size_t) BN_num_bytes(a->priv_key);
1459         buffer = malloc(buf_len);
1460         if (buffer == NULL) {
1461                 ECerror(ERR_R_MALLOC_FAILURE);
1462                 goto err;
1463         }
1464         if (!BN_bn2bin(a->priv_key, buffer)) {
1465                 ECerror(ERR_R_BN_LIB);
1466                 goto err;
1467         }
1468         if (!ASN1_STRING_set(priv_key->privateKey, buffer, buf_len)) {
1469                 ECerror(ERR_R_ASN1_LIB);
1470                 goto err;
1471         }
1472         if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1473                 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1474                             a->group, priv_key->parameters)) == NULL) {
1475                         ECerror(ERR_R_EC_LIB);
1476                         goto err;
1477                 }
1478         }
1479         if (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key != NULL) {
1480                 priv_key->publicKey = ASN1_BIT_STRING_new();
1481                 if (priv_key->publicKey == NULL) {
1482                         ECerror(ERR_R_MALLOC_FAILURE);
1483                         goto err;
1484                 }
1485                 tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1486                     a->conv_form, NULL, 0, NULL);
1487
1488                 if (tmp_len > buf_len) {
1489                         unsigned char *tmp_buffer = realloc(buffer, tmp_len);
1490                         if (!tmp_buffer) {
1491                                 ECerror(ERR_R_MALLOC_FAILURE);
1492                                 goto err;
1493                         }
1494                         buffer = tmp_buffer;
1495                         buf_len = tmp_len;
1496                 }
1497                 if (!EC_POINT_point2oct(a->group, a->pub_key,
1498                         a->conv_form, buffer, buf_len, NULL)) {
1499                         ECerror(ERR_R_EC_LIB);
1500                         goto err;
1501                 }
1502                 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
1503                 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1504                 if (!ASN1_STRING_set(priv_key->publicKey, buffer,
1505                         buf_len)) {
1506                         ECerror(ERR_R_ASN1_LIB);
1507                         goto err;
1508                 }
1509         }
1510         if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
1511                 ECerror(ERR_R_EC_LIB);
1512                 goto err;
1513         }
1514         ok = 1;
1515  err:
1516         free(buffer);
1517         if (priv_key)
1518                 EC_PRIVATEKEY_free(priv_key);
1519         return (ok ? ret : 0);
1520 }
1521
1522 int 
1523 i2d_ECParameters(EC_KEY * a, unsigned char **out)
1524 {
1525         if (a == NULL) {
1526                 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1527                 return 0;
1528         }
1529         return i2d_ECPKParameters(a->group, out);
1530 }
1531
1532 EC_KEY *
1533 d2i_ECParameters(EC_KEY ** a, const unsigned char **in, long len)
1534 {
1535         EC_KEY *ret;
1536
1537         if (in == NULL || *in == NULL) {
1538                 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1539                 return NULL;
1540         }
1541         if (a == NULL || *a == NULL) {
1542                 if ((ret = EC_KEY_new()) == NULL) {
1543                         ECerror(ERR_R_MALLOC_FAILURE);
1544                         return NULL;
1545                 }
1546         } else
1547                 ret = *a;
1548
1549         if (!d2i_ECPKParameters(&ret->group, in, len)) {
1550                 ECerror(ERR_R_EC_LIB);
1551                 if (a == NULL || *a != ret)
1552                         EC_KEY_free(ret);
1553                 return NULL;
1554         }
1555
1556         if (a != NULL)
1557                 *a = ret;
1558         return ret;
1559 }
1560
1561 EC_KEY *
1562 o2i_ECPublicKey(EC_KEY ** a, const unsigned char **in, long len)
1563 {
1564         EC_KEY *ret = NULL;
1565
1566         if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
1567                 /* An EC_GROUP structure is necessary to set the public key. */
1568                 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1569                 return 0;
1570         }
1571         ret = *a;
1572         if (ret->pub_key == NULL &&
1573             (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
1574                 ECerror(ERR_R_MALLOC_FAILURE);
1575                 return 0;
1576         }
1577         if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
1578                 ECerror(ERR_R_EC_LIB);
1579                 return 0;
1580         }
1581         /* save the point conversion form */
1582         ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
1583         *in += len;
1584         return ret;
1585 }
1586
1587 int 
1588 i2o_ECPublicKey(const EC_KEY * a, unsigned char **out)
1589 {
1590         size_t buf_len = 0;
1591         int new_buffer = 0;
1592
1593         if (a == NULL) {
1594                 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1595                 return 0;
1596         }
1597         buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1598             a->conv_form, NULL, 0, NULL);
1599
1600         if (out == NULL || buf_len == 0)
1601                 /* out == NULL => just return the length of the octet string */
1602                 return buf_len;
1603
1604         if (*out == NULL) {
1605                 if ((*out = malloc(buf_len)) == NULL) {
1606                         ECerror(ERR_R_MALLOC_FAILURE);
1607                         return 0;
1608                 }
1609                 new_buffer = 1;
1610         }
1611         if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1612                 *out, buf_len, NULL)) {
1613                 ECerror(ERR_R_EC_LIB);
1614                 if (new_buffer) {
1615                         free(*out);
1616                         *out = NULL;
1617                 }
1618                 return 0;
1619         }
1620         if (!new_buffer)
1621                 *out += buf_len;
1622         return buf_len;
1623 }