1 /* $OpenBSD: ec_asn1.c,v 1.110 2025/01/25 10:27:58 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 <limits.h>
60 #include <stddef.h>
61 #include <stdlib.h>
62 #include <string.h>
63
64 #include <openssl/opensslconf.h>
65
66 #include <openssl/asn1.h>
67 #include <openssl/bn.h>
68 #include <openssl/ec.h>
69 #include <openssl/err.h>
70 #include <openssl/asn1t.h>
71 #include <openssl/objects.h>
72
73 #include "asn1_local.h"
74 #include "ec_local.h"
75
76 int
EC_GROUP_get_basis_type(const EC_GROUP * group)77 EC_GROUP_get_basis_type(const EC_GROUP *group)
78 {
79 return 0;
80 }
81 LCRYPTO_ALIAS(EC_GROUP_get_basis_type);
82
83 typedef struct x9_62_pentanomial_st {
84 long k1;
85 long k2;
86 long k3;
87 } X9_62_PENTANOMIAL;
88
89 typedef struct x9_62_characteristic_two_st {
90 long m;
91 ASN1_OBJECT *type;
92 union {
93 char *ptr;
94 /* NID_X9_62_onBasis */
95 ASN1_NULL *onBasis;
96 /* NID_X9_62_tpBasis */
97 ASN1_INTEGER *tpBasis;
98 /* NID_X9_62_ppBasis */
99 X9_62_PENTANOMIAL *ppBasis;
100 /* anything else */
101 ASN1_TYPE *other;
102 } p;
103 } X9_62_CHARACTERISTIC_TWO;
104
105 typedef struct x9_62_fieldid_st {
106 ASN1_OBJECT *fieldType;
107 union {
108 char *ptr;
109 /* NID_X9_62_prime_field */
110 ASN1_INTEGER *prime;
111 /* NID_X9_62_characteristic_two_field */
112 X9_62_CHARACTERISTIC_TWO *char_two;
113 /* anything else */
114 ASN1_TYPE *other;
115 } p;
116 } X9_62_FIELDID;
117
118 typedef struct x9_62_curve_st {
119 ASN1_OCTET_STRING *a;
120 ASN1_OCTET_STRING *b;
121 ASN1_BIT_STRING *seed;
122 } X9_62_CURVE;
123
124 typedef struct ec_parameters_st {
125 long version;
126 X9_62_FIELDID *fieldID;
127 X9_62_CURVE *curve;
128 ASN1_OCTET_STRING *base;
129 ASN1_INTEGER *order;
130 ASN1_INTEGER *cofactor;
131 } ECPARAMETERS;
132
133 #define ECPK_PARAM_NAMED_CURVE 0
134 #define ECPK_PARAM_EXPLICIT 1
135 #define ECPK_PARAM_IMPLICITLY_CA 2
136
137 typedef struct ecpk_parameters_st {
138 int type;
139 union {
140 ASN1_OBJECT *named_curve;
141 ECPARAMETERS *parameters;
142 ASN1_NULL *implicitlyCA;
143 } value;
144 } ECPKPARAMETERS;
145
146 typedef struct ec_privatekey_st {
147 long version;
148 ASN1_OCTET_STRING *privateKey;
149 ECPKPARAMETERS *parameters;
150 ASN1_BIT_STRING *publicKey;
151 } EC_PRIVATEKEY;
152
153 static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = {
154 {
155 .flags = 0,
156 .tag = 0,
157 .offset = offsetof(X9_62_PENTANOMIAL, k1),
158 .field_name = "k1",
159 .item = &LONG_it,
160 },
161 {
162 .flags = 0,
163 .tag = 0,
164 .offset = offsetof(X9_62_PENTANOMIAL, k2),
165 .field_name = "k2",
166 .item = &LONG_it,
167 },
168 {
169 .flags = 0,
170 .tag = 0,
171 .offset = offsetof(X9_62_PENTANOMIAL, k3),
172 .field_name = "k3",
173 .item = &LONG_it,
174 },
175 };
176
177 static const ASN1_ITEM X9_62_PENTANOMIAL_it = {
178 .itype = ASN1_ITYPE_SEQUENCE,
179 .utype = V_ASN1_SEQUENCE,
180 .templates = X9_62_PENTANOMIAL_seq_tt,
181 .tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
182 .funcs = NULL,
183 .size = sizeof(X9_62_PENTANOMIAL),
184 .sname = "X9_62_PENTANOMIAL",
185 };
186
187 static const ASN1_TEMPLATE char_two_def_tt = {
188 .flags = 0,
189 .tag = 0,
190 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other),
191 .field_name = "p.other",
192 .item = &ASN1_ANY_it,
193 };
194
195 static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = {
196 {
197 .value = NID_X9_62_onBasis,
198 .tt = {
199 .flags = 0,
200 .tag = 0,
201 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis),
202 .field_name = "p.onBasis",
203 .item = &ASN1_NULL_it,
204 },
205 },
206 {
207 .value = NID_X9_62_tpBasis,
208 .tt = {
209 .flags = 0,
210 .tag = 0,
211 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis),
212 .field_name = "p.tpBasis",
213 .item = &ASN1_INTEGER_it,
214 },
215 },
216 {
217 .value = NID_X9_62_ppBasis,
218 .tt = {
219 .flags = 0,
220 .tag = 0,
221 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis),
222 .field_name = "p.ppBasis",
223 .item = &X9_62_PENTANOMIAL_it,
224 },
225
226 },
227 };
228
229 static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = {
230 .flags = 0,
231 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
232 .tbl = X9_62_CHARACTERISTIC_TWO_adbtbl,
233 .tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE),
234 .default_tt = &char_two_def_tt,
235 .null_tt = NULL,
236 };
237
238 static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = {
239 {
240 .flags = 0,
241 .tag = 0,
242 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, m),
243 .field_name = "m",
244 .item = &LONG_it,
245 },
246 {
247 .flags = 0,
248 .tag = 0,
249 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
250 .field_name = "type",
251 .item = &ASN1_OBJECT_it,
252 },
253 {
254 .flags = ASN1_TFLG_ADB_OID,
255 .tag = -1,
256 .offset = 0,
257 .field_name = "X9_62_CHARACTERISTIC_TWO",
258 .item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb,
259 },
260 };
261
262 static const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = {
263 .itype = ASN1_ITYPE_SEQUENCE,
264 .utype = V_ASN1_SEQUENCE,
265 .templates = X9_62_CHARACTERISTIC_TWO_seq_tt,
266 .tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE),
267 .funcs = NULL,
268 .size = sizeof(X9_62_CHARACTERISTIC_TWO),
269 .sname = "X9_62_CHARACTERISTIC_TWO",
270 };
271
272 static const ASN1_TEMPLATE fieldID_def_tt = {
273 .flags = 0,
274 .tag = 0,
275 .offset = offsetof(X9_62_FIELDID, p.other),
276 .field_name = "p.other",
277 .item = &ASN1_ANY_it,
278 };
279
280 static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = {
281 {
282 .value = NID_X9_62_prime_field,
283 .tt = {
284 .flags = 0,
285 .tag = 0,
286 .offset = offsetof(X9_62_FIELDID, p.prime),
287 .field_name = "p.prime",
288 .item = &ASN1_INTEGER_it,
289 },
290 },
291 {
292 .value = NID_X9_62_characteristic_two_field,
293 .tt = {
294 .flags = 0,
295 .tag = 0,
296 .offset = offsetof(X9_62_FIELDID, p.char_two),
297 .field_name = "p.char_two",
298 .item = &X9_62_CHARACTERISTIC_TWO_it,
299 },
300 },
301 };
302
303 static const ASN1_ADB X9_62_FIELDID_adb = {
304 .flags = 0,
305 .offset = offsetof(X9_62_FIELDID, fieldType),
306 .tbl = X9_62_FIELDID_adbtbl,
307 .tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE),
308 .default_tt = &fieldID_def_tt,
309 .null_tt = NULL,
310 };
311
312 static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = {
313 {
314 .flags = 0,
315 .tag = 0,
316 .offset = offsetof(X9_62_FIELDID, fieldType),
317 .field_name = "fieldType",
318 .item = &ASN1_OBJECT_it,
319 },
320 {
321 .flags = ASN1_TFLG_ADB_OID,
322 .tag = -1,
323 .offset = 0,
324 .field_name = "X9_62_FIELDID",
325 .item = (const ASN1_ITEM *)&X9_62_FIELDID_adb,
326 },
327 };
328
329 static const ASN1_ITEM X9_62_FIELDID_it = {
330 .itype = ASN1_ITYPE_SEQUENCE,
331 .utype = V_ASN1_SEQUENCE,
332 .templates = X9_62_FIELDID_seq_tt,
333 .tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE),
334 .funcs = NULL,
335 .size = sizeof(X9_62_FIELDID),
336 .sname = "X9_62_FIELDID",
337 };
338
339 static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = {
340 {
341 .flags = 0,
342 .tag = 0,
343 .offset = offsetof(X9_62_CURVE, a),
344 .field_name = "a",
345 .item = &ASN1_OCTET_STRING_it,
346 },
347 {
348 .flags = 0,
349 .tag = 0,
350 .offset = offsetof(X9_62_CURVE, b),
351 .field_name = "b",
352 .item = &ASN1_OCTET_STRING_it,
353 },
354 {
355 .flags = ASN1_TFLG_OPTIONAL,
356 .tag = 0,
357 .offset = offsetof(X9_62_CURVE, seed),
358 .field_name = "seed",
359 .item = &ASN1_BIT_STRING_it,
360 },
361 };
362
363 static const ASN1_ITEM X9_62_CURVE_it = {
364 .itype = ASN1_ITYPE_SEQUENCE,
365 .utype = V_ASN1_SEQUENCE,
366 .templates = X9_62_CURVE_seq_tt,
367 .tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE),
368 .funcs = NULL,
369 .size = sizeof(X9_62_CURVE),
370 .sname = "X9_62_CURVE",
371 };
372
373 static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = {
374 {
375 .flags = 0,
376 .tag = 0,
377 .offset = offsetof(ECPARAMETERS, version),
378 .field_name = "version",
379 .item = &LONG_it,
380 },
381 {
382 .flags = 0,
383 .tag = 0,
384 .offset = offsetof(ECPARAMETERS, fieldID),
385 .field_name = "fieldID",
386 .item = &X9_62_FIELDID_it,
387 },
388 {
389 .flags = 0,
390 .tag = 0,
391 .offset = offsetof(ECPARAMETERS, curve),
392 .field_name = "curve",
393 .item = &X9_62_CURVE_it,
394 },
395 {
396 .flags = 0,
397 .tag = 0,
398 .offset = offsetof(ECPARAMETERS, base),
399 .field_name = "base",
400 .item = &ASN1_OCTET_STRING_it,
401 },
402 {
403 .flags = 0,
404 .tag = 0,
405 .offset = offsetof(ECPARAMETERS, order),
406 .field_name = "order",
407 .item = &ASN1_INTEGER_it,
408 },
409 {
410 .flags = ASN1_TFLG_OPTIONAL,
411 .tag = 0,
412 .offset = offsetof(ECPARAMETERS, cofactor),
413 .field_name = "cofactor",
414 .item = &ASN1_INTEGER_it,
415 },
416 };
417
418 static const ASN1_ITEM ECPARAMETERS_it = {
419 .itype = ASN1_ITYPE_SEQUENCE,
420 .utype = V_ASN1_SEQUENCE,
421 .templates = ECPARAMETERS_seq_tt,
422 .tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE),
423 .funcs = NULL,
424 .size = sizeof(ECPARAMETERS),
425 .sname = "ECPARAMETERS",
426 };
427
428 static ECPARAMETERS *
ECPARAMETERS_new(void)429 ECPARAMETERS_new(void)
430 {
431 return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
432 }
433
434 static void
ECPARAMETERS_free(ECPARAMETERS * a)435 ECPARAMETERS_free(ECPARAMETERS *a)
436 {
437 ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
438 }
439
440 static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = {
441 {
442 .flags = 0,
443 .tag = 0,
444 .offset = offsetof(ECPKPARAMETERS, value.named_curve),
445 .field_name = "value.named_curve",
446 .item = &ASN1_OBJECT_it,
447 },
448 {
449 .flags = 0,
450 .tag = 0,
451 .offset = offsetof(ECPKPARAMETERS, value.parameters),
452 .field_name = "value.parameters",
453 .item = &ECPARAMETERS_it,
454 },
455 {
456 .flags = 0,
457 .tag = 0,
458 .offset = offsetof(ECPKPARAMETERS, value.implicitlyCA),
459 .field_name = "value.implicitlyCA",
460 .item = &ASN1_NULL_it,
461 },
462 };
463
464 static const ASN1_ITEM ECPKPARAMETERS_it = {
465 .itype = ASN1_ITYPE_CHOICE,
466 .utype = offsetof(ECPKPARAMETERS, type),
467 .templates = ECPKPARAMETERS_ch_tt,
468 .tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE),
469 .funcs = NULL,
470 .size = sizeof(ECPKPARAMETERS),
471 .sname = "ECPKPARAMETERS",
472 };
473
474 static ECPKPARAMETERS *
d2i_ECPKPARAMETERS(ECPKPARAMETERS ** a,const unsigned char ** in,long len)475 d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len)
476 {
477 return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
478 &ECPKPARAMETERS_it);
479 }
480
481 static int
i2d_ECPKPARAMETERS(const ECPKPARAMETERS * a,unsigned char ** out)482 i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
483 {
484 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
485 }
486
487 static ECPKPARAMETERS *
ECPKPARAMETERS_new(void)488 ECPKPARAMETERS_new(void)
489 {
490 return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
491 }
492
493 static void
ECPKPARAMETERS_free(ECPKPARAMETERS * a)494 ECPKPARAMETERS_free(ECPKPARAMETERS *a)
495 {
496 ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
497 }
498
499 static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = {
500 {
501 .flags = 0,
502 .tag = 0,
503 .offset = offsetof(EC_PRIVATEKEY, version),
504 .field_name = "version",
505 .item = &LONG_it,
506 },
507 {
508 .flags = 0,
509 .tag = 0,
510 .offset = offsetof(EC_PRIVATEKEY, privateKey),
511 .field_name = "privateKey",
512 .item = &ASN1_OCTET_STRING_it,
513 },
514 {
515 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
516 .tag = 0,
517 .offset = offsetof(EC_PRIVATEKEY, parameters),
518 .field_name = "parameters",
519 .item = &ECPKPARAMETERS_it,
520 },
521 {
522 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
523 .tag = 1,
524 .offset = offsetof(EC_PRIVATEKEY, publicKey),
525 .field_name = "publicKey",
526 .item = &ASN1_BIT_STRING_it,
527 },
528 };
529
530 static const ASN1_ITEM EC_PRIVATEKEY_it = {
531 .itype = ASN1_ITYPE_SEQUENCE,
532 .utype = V_ASN1_SEQUENCE,
533 .templates = EC_PRIVATEKEY_seq_tt,
534 .tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
535 .funcs = NULL,
536 .size = sizeof(EC_PRIVATEKEY),
537 .sname = "EC_PRIVATEKEY",
538 };
539
540 static EC_PRIVATEKEY *
d2i_EC_PRIVATEKEY(EC_PRIVATEKEY ** a,const unsigned char ** in,long len)541 d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len)
542 {
543 return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
544 &EC_PRIVATEKEY_it);
545 }
546
547 static int
i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY * a,unsigned char ** out)548 i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
549 {
550 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
551 }
552
553 static EC_PRIVATEKEY *
EC_PRIVATEKEY_new(void)554 EC_PRIVATEKEY_new(void)
555 {
556 return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
557 }
558
559 static void
EC_PRIVATEKEY_free(EC_PRIVATEKEY * a)560 EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
561 {
562 ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
563 }
564
565 static int
ec_point_from_asn1_string(const EC_GROUP * group,const ASN1_STRING * astr,EC_POINT ** out_point,uint8_t * out_form)566 ec_point_from_asn1_string(const EC_GROUP *group, const ASN1_STRING *astr,
567 EC_POINT **out_point, uint8_t *out_form)
568 {
569 return ec_point_from_octets(group, astr->data, astr->length,
570 out_point, out_form, NULL);
571 }
572
573 static int
ec_point_from_asn1_bit_string(const EC_GROUP * group,const ASN1_BIT_STRING * abs,EC_POINT ** out_point,uint8_t * out_form)574 ec_point_from_asn1_bit_string(const EC_GROUP *group, const ASN1_BIT_STRING *abs,
575 EC_POINT **out_point, uint8_t *out_form)
576 {
577 /*
578 * Per SEC 1, C.3, the bit string representing the public key comes from
579 * an octet string, therefore the unused bits octet must be 0x00.
580 * XXX - move this check to a helper in a_bitstr.c?
581 */
582 if ((abs->flags & ASN1_STRING_FLAG_BITS_LEFT) != 0 &&
583 (abs->flags & 0x07) != 0)
584 return 0;
585
586 return ec_point_from_asn1_string(group, abs, out_point, out_form);
587 }
588
589 static int
ec_point_from_asn1_octet_string(const EC_GROUP * group,const ASN1_OCTET_STRING * aos,EC_POINT ** out_point,uint8_t * out_form)590 ec_point_from_asn1_octet_string(const EC_GROUP *group, const ASN1_OCTET_STRING *aos,
591 EC_POINT **out_point, uint8_t *out_form)
592 {
593 return ec_point_from_asn1_string(group, aos, out_point, out_form);
594 }
595
596 static int
ec_point_to_asn1_string_type(const EC_GROUP * group,const EC_POINT * point,int form,int type,ASN1_STRING ** out_astr)597 ec_point_to_asn1_string_type(const EC_GROUP *group, const EC_POINT *point,
598 int form, int type, ASN1_STRING **out_astr)
599 {
600 ASN1_STRING *astr = NULL;
601 unsigned char *buf = NULL;
602 size_t len = 0;
603 int ret = 0;
604
605 if (*out_astr != NULL && ASN1_STRING_type(*out_astr) != type)
606 goto err;
607
608 if (!ec_point_to_octets(group, point, form, &buf, &len, NULL))
609 goto err;
610
611 if ((astr = *out_astr) == NULL)
612 astr = ASN1_STRING_type_new(type);
613 if (astr == NULL)
614 goto err;
615
616 ASN1_STRING_set0(astr, buf, len);
617 buf = NULL;
618 len = 0;
619
620 *out_astr = astr;
621 astr = NULL;
622
623 ret = 1;
624
625 err:
626 ASN1_STRING_free(astr);
627 freezero(buf, len);
628
629 return ret;
630 }
631
632 static int
ec_point_to_asn1_bit_string(const EC_GROUP * group,const EC_POINT * point,int form,ASN1_BIT_STRING ** out_abs)633 ec_point_to_asn1_bit_string(const EC_GROUP *group, const EC_POINT *point,
634 int form, ASN1_BIT_STRING **out_abs)
635 {
636 if (!ec_point_to_asn1_string_type(group, point, form,
637 V_ASN1_BIT_STRING, out_abs))
638 return 0;
639
640 return asn1_abs_set_unused_bits(*out_abs, 0);
641 }
642
643 static int
ec_point_to_asn1_octet_string(const EC_GROUP * group,const EC_POINT * point,int form,ASN1_OCTET_STRING ** out_aos)644 ec_point_to_asn1_octet_string(const EC_GROUP *group, const EC_POINT *point,
645 int form, ASN1_OCTET_STRING **out_aos)
646 {
647 return ec_point_to_asn1_string_type(group, point, form,
648 V_ASN1_OCTET_STRING, out_aos);
649 }
650
651 static int
ec_asn1_group2fieldid(const EC_GROUP * group,X9_62_FIELDID * field)652 ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
653 {
654 int ret = 0;
655
656 if (group == NULL || field == NULL)
657 goto err;
658
659 if ((field->fieldType = OBJ_nid2obj(NID_X9_62_prime_field)) == NULL) {
660 ECerror(ERR_R_OBJ_LIB);
661 goto err;
662 }
663 if ((field->p.prime = BN_to_ASN1_INTEGER(group->p, NULL)) == NULL) {
664 ECerror(ERR_R_ASN1_LIB);
665 goto err;
666 }
667
668 ret = 1;
669
670 err:
671 return ret;
672 }
673
674 static int
ec_asn1_encode_bn(const EC_GROUP * group,const BIGNUM * bn,int len,ASN1_OCTET_STRING * os)675 ec_asn1_encode_bn(const EC_GROUP *group, const BIGNUM *bn, int len,
676 ASN1_OCTET_STRING *os)
677 {
678 unsigned char *buf;
679 int ret = 0;
680
681 /* One extra byte for historic NUL termination of ASN1_STRINGs. */
682 if ((buf = calloc(1, len + 1)) == NULL)
683 goto err;
684
685 if (BN_bn2binpad(bn, buf, len) != len)
686 goto err;
687
688 ASN1_STRING_set0(os, buf, len);
689 buf = NULL;
690 len = 0;
691
692 ret = 1;
693
694 err:
695 freezero(buf, len);
696
697 return ret;
698 }
699
700 static int
ec_asn1_encode_field_element(const EC_GROUP * group,const BIGNUM * bn,ASN1_OCTET_STRING * os)701 ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn,
702 ASN1_OCTET_STRING *os)
703 {
704 int len;
705
706 /* Zero-pad field element to byte length of p per SEC 1, 2.3.5. */
707 len = (EC_GROUP_get_degree(group) + 7) / 8;
708 return ec_asn1_encode_bn(group, bn, len, os);
709 }
710
711 static int
ec_asn1_encode_private_key(const EC_GROUP * group,const BIGNUM * bn,ASN1_OCTET_STRING * os)712 ec_asn1_encode_private_key(const EC_GROUP *group, const BIGNUM *bn,
713 ASN1_OCTET_STRING *os)
714 {
715 const BIGNUM *order;
716
717 if ((order = EC_GROUP_get0_order(group)) == NULL) {
718 ECerror(EC_R_INVALID_GROUP_ORDER);
719 return 0;
720 }
721
722 /* Zero-pad private key to byte length of order per SEC 1, C.4. */
723 return ec_asn1_encode_bn(group, bn, BN_num_bytes(order), os);
724 }
725
726 static int
ec_asn1_group2curve(const EC_GROUP * group,X9_62_CURVE * curve)727 ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
728 {
729 BIGNUM *a = NULL, *b = NULL;
730 int ret = 0;
731
732 if (group == NULL)
733 goto err;
734 if (curve == NULL || curve->a == NULL || curve->b == NULL)
735 goto err;
736
737 if ((a = BN_new()) == NULL || (b = BN_new()) == NULL) {
738 ECerror(ERR_R_MALLOC_FAILURE);
739 goto err;
740 }
741
742 if (!EC_GROUP_get_curve(group, NULL, a, b, NULL)) {
743 ECerror(ERR_R_EC_LIB);
744 goto err;
745 }
746
747 if (!ec_asn1_encode_field_element(group, a, curve->a)) {
748 ECerror(ERR_R_EC_LIB);
749 goto err;
750 }
751 if (!ec_asn1_encode_field_element(group, b, curve->b)) {
752 ECerror(ERR_R_EC_LIB);
753 goto err;
754 }
755
756 ASN1_BIT_STRING_free(curve->seed);
757 curve->seed = NULL;
758
759 if (group->seed != NULL) {
760 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
761 ECerror(ERR_R_MALLOC_FAILURE);
762 goto err;
763 }
764 if (!ASN1_BIT_STRING_set(curve->seed,
765 group->seed, group->seed_len)) {
766 ECerror(ERR_R_ASN1_LIB);
767 goto err;
768 }
769 if (!asn1_abs_set_unused_bits(curve->seed, 0)) {
770 ECerror(ERR_R_ASN1_LIB);
771 goto err;
772 }
773 }
774
775 ret = 1;
776
777 err:
778 BN_free(a);
779 BN_free(b);
780
781 return ret;
782 }
783
784 static ECPARAMETERS *
ec_asn1_group2parameters(const EC_GROUP * group)785 ec_asn1_group2parameters(const EC_GROUP *group)
786 {
787 ECPARAMETERS *parameters = NULL;
788 const EC_POINT *generator = NULL;
789 const BIGNUM *order, *cofactor;
790 uint8_t form;
791
792 if ((parameters = ECPARAMETERS_new()) == NULL) {
793 ECerror(ERR_R_MALLOC_FAILURE);
794 goto err;
795 }
796
797 parameters->version = 0x1;
798
799 if (!ec_asn1_group2fieldid(group, parameters->fieldID)) {
800 ECerror(ERR_R_EC_LIB);
801 goto err;
802 }
803
804 if (!ec_asn1_group2curve(group, parameters->curve)) {
805 ECerror(ERR_R_EC_LIB);
806 goto err;
807 }
808
809 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
810 ECerror(EC_R_UNDEFINED_GENERATOR);
811 goto err;
812 }
813
814 form = EC_GROUP_get_point_conversion_form(group);
815 if (!ec_point_to_asn1_octet_string(group, generator, form, ¶meters->base))
816 goto err;
817
818 if ((order = EC_GROUP_get0_order(group)) == NULL) {
819 ECerror(ERR_R_EC_LIB);
820 goto err;
821 }
822 if (BN_is_zero(order)) {
823 ECerror(ERR_R_EC_LIB);
824 goto err;
825 }
826 ASN1_INTEGER_free(parameters->order);
827 if ((parameters->order = BN_to_ASN1_INTEGER(order, NULL)) == NULL) {
828 ECerror(ERR_R_ASN1_LIB);
829 goto err;
830 }
831
832 ASN1_INTEGER_free(parameters->cofactor);
833 parameters->cofactor = NULL;
834 if ((cofactor = EC_GROUP_get0_cofactor(group)) == NULL) {
835 ECerror(ERR_R_EC_LIB);
836 goto err;
837 }
838 if (!BN_is_zero(cofactor)) {
839 if ((parameters->cofactor = BN_to_ASN1_INTEGER(cofactor,
840 NULL)) == NULL) {
841 ECerror(ERR_R_ASN1_LIB);
842 goto err;
843 }
844 }
845
846 return parameters;
847
848 err:
849 ECPARAMETERS_free(parameters);
850
851 return NULL;
852 }
853
854 static ECPKPARAMETERS *
ec_asn1_group2pkparameters(const EC_GROUP * group)855 ec_asn1_group2pkparameters(const EC_GROUP *group)
856 {
857 ECPKPARAMETERS *pkparameters;
858 ECPARAMETERS *parameters;
859 ASN1_OBJECT *aobj;
860 int nid;
861
862 if ((pkparameters = ECPKPARAMETERS_new()) == NULL) {
863 ECerror(ERR_R_MALLOC_FAILURE);
864 goto err;
865 }
866
867 if ((EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) != 0) {
868 if ((nid = EC_GROUP_get_curve_name(group)) == NID_undef)
869 goto err;
870 if ((aobj = OBJ_nid2obj(nid)) == NULL)
871 goto err;
872 pkparameters->type = ECPK_PARAM_NAMED_CURVE;
873 pkparameters->value.named_curve = aobj;
874 } else {
875 if ((parameters = ec_asn1_group2parameters(group)) == NULL)
876 goto err;
877 pkparameters->type = ECPK_PARAM_EXPLICIT;
878 pkparameters->value.parameters = parameters;
879 parameters = NULL;
880 }
881
882 return pkparameters;
883
884 err:
885 ECPKPARAMETERS_free(pkparameters);
886
887 return NULL;
888 }
889
890 static int
ec_asn1_is_prime_field(const X9_62_FIELDID * fieldid)891 ec_asn1_is_prime_field(const X9_62_FIELDID *fieldid)
892 {
893 int nid;
894
895 if (fieldid == NULL) {
896 ECerror(EC_R_ASN1_ERROR);
897 return 0;
898 }
899 if ((nid = OBJ_obj2nid(fieldid->fieldType)) == NID_undef) {
900 ECerror(EC_R_INVALID_FIELD);
901 return 0;
902 }
903 if (nid == NID_X9_62_characteristic_two_field) {
904 ECerror(EC_R_GF2M_NOT_SUPPORTED);
905 return 0;
906 }
907 if (nid != NID_X9_62_prime_field) {
908 ECerror(EC_R_UNSUPPORTED_FIELD);
909 return 0;
910 }
911
912 /* We can't check that this is actually a prime due to DoS risk. */
913 if (fieldid->p.prime == NULL) {
914 ECerror(EC_R_INVALID_FIELD);
915 return 0;
916 }
917
918 return 1;
919 }
920
921 static int
ec_asn1_parameters_curve2group(const X9_62_CURVE * curve,const ASN1_INTEGER * prime,EC_GROUP ** out_group)922 ec_asn1_parameters_curve2group(const X9_62_CURVE *curve,
923 const ASN1_INTEGER *prime, EC_GROUP **out_group)
924 {
925 EC_GROUP *group = NULL;
926 BIGNUM *p = NULL, *a = NULL, *b = NULL;
927 int ret = 0;
928
929 if (*out_group != NULL)
930 goto err;
931
932 if ((p = ASN1_INTEGER_to_BN(prime, NULL)) == NULL)
933 goto err;
934 if ((a = BN_bin2bn(curve->a->data, curve->a->length, NULL)) == NULL)
935 goto err;
936 if ((b = BN_bin2bn(curve->b->data, curve->b->length, NULL)) == NULL)
937 goto err;
938
939 /*
940 * XXX - move these checks to ec_GFp_simple_group_set_curve()?
941 * What about checking 0 <= a, b < p?
942 */
943 if (BN_is_zero(p) || BN_is_negative(p)) {
944 ECerror(EC_R_INVALID_FIELD);
945 goto err;
946 }
947 if (BN_num_bits(p) > OPENSSL_ECC_MAX_FIELD_BITS) {
948 ECerror(EC_R_FIELD_TOO_LARGE);
949 goto err;
950 }
951
952 if ((group = EC_GROUP_new_curve_GFp(p, a, b, NULL)) == NULL)
953 goto err;
954
955 *out_group = group;
956 group = NULL;
957
958 ret = 1;
959
960 err:
961 BN_free(p);
962 BN_free(a);
963 BN_free(b);
964 EC_GROUP_free(group);
965
966 return ret;
967 }
968
969 static int
ec_asn1_set_group_parameters(const ECPARAMETERS * params,EC_GROUP * group)970 ec_asn1_set_group_parameters(const ECPARAMETERS *params, EC_GROUP *group)
971 {
972 EC_POINT *generator = NULL;
973 BIGNUM *order = NULL, *cofactor = NULL;
974 const ASN1_BIT_STRING *seed;
975 uint8_t form;
976 int ret = 0;
977
978 if (!ec_point_from_asn1_octet_string(group, params->base, &generator, &form))
979 goto err;
980 EC_GROUP_set_point_conversion_form(group, form);
981
982 if ((order = ASN1_INTEGER_to_BN(params->order, NULL)) == NULL) {
983 ECerror(ERR_R_ASN1_LIB);
984 goto err;
985 }
986 if (params->cofactor != NULL) {
987 if ((cofactor = ASN1_INTEGER_to_BN(params->cofactor,
988 NULL)) == NULL) {
989 ECerror(ERR_R_ASN1_LIB);
990 goto err;
991 }
992 }
993
994 /* Checks the Hasse bound and sets the cofactor if possible or fails. */
995 if (!EC_GROUP_set_generator(group, generator, order, cofactor)) {
996 ECerror(ERR_R_EC_LIB);
997 goto err;
998 }
999
1000 if ((seed = params->curve->seed) != NULL) {
1001 if (EC_GROUP_set_seed(group, seed->data, seed->length) == 0) {
1002 ECerror(ERR_R_MALLOC_FAILURE);
1003 goto err;
1004 }
1005 }
1006
1007 ret = 1;
1008
1009 err:
1010 EC_POINT_free(generator);
1011 BN_free(order);
1012 BN_free(cofactor);
1013
1014 return ret;
1015 }
1016
1017 static int
ec_asn1_parameters_extract_prime_group(const ECPARAMETERS * params,EC_GROUP ** out_group)1018 ec_asn1_parameters_extract_prime_group(const ECPARAMETERS *params,
1019 EC_GROUP **out_group)
1020 {
1021 EC_GROUP *group = NULL;
1022 int ret = 0;
1023
1024 if (*out_group != NULL)
1025 goto err;
1026
1027 if (!ec_asn1_is_prime_field(params->fieldID))
1028 goto err;
1029 if (!ec_asn1_parameters_curve2group(params->curve,
1030 params->fieldID->p.prime, &group))
1031 goto err;
1032 if (!ec_asn1_set_group_parameters(params, group))
1033 goto err;
1034
1035 *out_group = group;
1036 group = NULL;
1037
1038 ret = 1;
1039
1040 err:
1041 EC_GROUP_free(group);
1042
1043 return ret;
1044 }
1045
1046 static EC_GROUP *
ec_asn1_parameters2group(const ECPARAMETERS * params)1047 ec_asn1_parameters2group(const ECPARAMETERS *params)
1048 {
1049 EC_GROUP *group = NULL;
1050 int nid = NID_undef;
1051
1052 if (params == NULL) {
1053 ECerror(EC_R_ASN1_ERROR);
1054 goto err;
1055 }
1056
1057 if (!ec_asn1_parameters_extract_prime_group(params, &group))
1058 goto err;
1059 if (!ec_group_is_builtin_curve(group, &nid))
1060 goto err;
1061 EC_GROUP_set_curve_name(group, nid);
1062
1063 return group;
1064
1065 err:
1066 EC_GROUP_free(group);
1067
1068 return NULL;
1069 }
1070
1071 static EC_GROUP *
ec_asn1_pkparameters2group(const ECPKPARAMETERS * params)1072 ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1073 {
1074 EC_GROUP *group;
1075 int nid;
1076
1077 if (params->type == ECPK_PARAM_NAMED_CURVE) {
1078 if ((nid = OBJ_obj2nid(params->value.named_curve)) == NID_undef) {
1079 ECerror(EC_R_UNKNOWN_GROUP);
1080 return NULL;
1081 }
1082 if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
1083 ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1084 return NULL;
1085 }
1086 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
1087 } else if (params->type == ECPK_PARAM_EXPLICIT) {
1088 group = ec_asn1_parameters2group(params->value.parameters);
1089 if (group == NULL) {
1090 ECerror(ERR_R_EC_LIB);
1091 return NULL;
1092 }
1093 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1094 } else if (params->type == ECPK_PARAM_IMPLICITLY_CA) {
1095 return NULL;
1096 } else {
1097 ECerror(EC_R_ASN1_ERROR);
1098 return NULL;
1099 }
1100
1101 return group;
1102 }
1103
1104 EC_GROUP *
d2i_ECPKParameters(EC_GROUP ** a,const unsigned char ** in,long len)1105 d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1106 {
1107 EC_GROUP *group = NULL;
1108 ECPKPARAMETERS *params;
1109
1110 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
1111 ECerror(EC_R_D2I_ECPKPARAMETERS_FAILURE);
1112 goto err;
1113 }
1114 if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1115 ECerror(EC_R_PKPARAMETERS2GROUP_FAILURE);
1116 goto err;
1117 }
1118
1119 if (a != NULL) {
1120 EC_GROUP_free(*a);
1121 *a = group;
1122 }
1123
1124 err:
1125 ECPKPARAMETERS_free(params);
1126
1127 return group;
1128 }
1129 LCRYPTO_ALIAS(d2i_ECPKParameters);
1130
1131 int
i2d_ECPKParameters(const EC_GROUP * group,unsigned char ** out_der)1132 i2d_ECPKParameters(const EC_GROUP *group, unsigned char **out_der)
1133 {
1134 ECPKPARAMETERS *parameters;
1135 int ret = 0;
1136
1137 if ((parameters = ec_asn1_group2pkparameters(group)) == NULL) {
1138 ECerror(EC_R_GROUP2PKPARAMETERS_FAILURE);
1139 goto err;
1140 }
1141 if ((ret = i2d_ECPKPARAMETERS(parameters, out_der)) <= 0) {
1142 ECerror(EC_R_I2D_ECPKPARAMETERS_FAILURE);
1143 goto err;
1144 }
1145
1146 err:
1147 ECPKPARAMETERS_free(parameters);
1148
1149 return ret;
1150 }
1151 LCRYPTO_ALIAS(i2d_ECPKParameters);
1152
1153 static int
ec_key_set_group_from_parameters(EC_KEY * ec_key,const ECPKPARAMETERS * params)1154 ec_key_set_group_from_parameters(EC_KEY *ec_key, const ECPKPARAMETERS *params)
1155 {
1156 EC_GROUP *group = NULL;
1157 int ret = 0;
1158
1159 /* Use group in parameters, if any. Fall back to existing group. */
1160 if (params != NULL) {
1161 if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1162 goto err;
1163 if (!EC_KEY_set_group(ec_key, group))
1164 goto err;
1165 }
1166 if (ec_key->group == NULL)
1167 goto err;
1168
1169 ret = 1;
1170
1171 err:
1172 EC_GROUP_free(group);
1173
1174 return ret;
1175 }
1176
1177 static int
ec_key_set_private_key(EC_KEY * ec_key,const ASN1_OCTET_STRING * aos)1178 ec_key_set_private_key(EC_KEY *ec_key, const ASN1_OCTET_STRING *aos)
1179 {
1180 BIGNUM *priv_key = NULL;
1181 int ret = 0;
1182
1183 if (aos == NULL) {
1184 ECerror(EC_R_MISSING_PRIVATE_KEY);
1185 goto err;
1186 }
1187
1188 /*
1189 * XXX - Sec 1, C.4 requires that this octet string be padded to the
1190 * byte length of the group's order. This can't be enforced because
1191 * i2d_ECPrivateKey() used to produce a semi-compatible ad hoc format.
1192 */
1193 if ((priv_key = BN_bin2bn(aos->data, aos->length, NULL)) == NULL)
1194 goto err;
1195 if (!EC_KEY_set_private_key(ec_key, priv_key))
1196 goto err;
1197
1198 ret = 1;
1199
1200 err:
1201 BN_free(priv_key);
1202
1203 return ret;
1204 }
1205
1206 static int
ec_key_set_public_key(EC_KEY * ec_key,const ASN1_BIT_STRING * abs)1207 ec_key_set_public_key(EC_KEY *ec_key, const ASN1_BIT_STRING *abs)
1208 {
1209 EC_POINT *pub_key = NULL;
1210 uint8_t form;
1211 int ret = 0;
1212
1213 if (abs == NULL) {
1214 ec_key->enc_flag |= EC_PKEY_NO_PUBKEY;
1215 return eckey_compute_pubkey(ec_key);
1216 }
1217
1218 /* XXX - SEC 1, 2.3.4 does not allow hybrid encoding. */
1219 if (!ec_point_from_asn1_bit_string(ec_key->group, abs, &pub_key, &form))
1220 goto err;
1221 if (!EC_KEY_set_public_key(ec_key, pub_key))
1222 goto err;
1223 EC_KEY_set_conv_form(ec_key, form);
1224
1225 ret = 1;
1226
1227 err:
1228 EC_POINT_free(pub_key);
1229
1230 return ret;
1231 }
1232
1233 EC_KEY *
d2i_ECPrivateKey(EC_KEY ** out_ec_key,const unsigned char ** in,long len)1234 d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len)
1235 {
1236 EC_KEY *ec_key = NULL;
1237 EC_PRIVATEKEY *ec_privatekey = NULL;
1238
1239 if (out_ec_key == NULL || (ec_key = *out_ec_key) == NULL)
1240 ec_key = EC_KEY_new();
1241 if (ec_key == NULL)
1242 goto err;
1243
1244 if ((ec_privatekey = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) {
1245 ECerror(ERR_R_EC_LIB);
1246 goto err;
1247 }
1248
1249 ec_key->version = ec_privatekey->version;
1250 if (!ec_key_set_group_from_parameters(ec_key, ec_privatekey->parameters))
1251 goto err;
1252 if (!ec_key_set_private_key(ec_key, ec_privatekey->privateKey))
1253 goto err;
1254 if (!ec_key_set_public_key(ec_key, ec_privatekey->publicKey))
1255 goto err;
1256
1257 EC_PRIVATEKEY_free(ec_privatekey);
1258 ec_privatekey = NULL;
1259
1260 if (out_ec_key != NULL)
1261 *out_ec_key = ec_key;
1262
1263 return ec_key;
1264
1265 err:
1266 if (out_ec_key == NULL || *out_ec_key != ec_key)
1267 EC_KEY_free(ec_key);
1268 EC_PRIVATEKEY_free(ec_privatekey);
1269
1270 return NULL;
1271 }
1272 LCRYPTO_ALIAS(d2i_ECPrivateKey);
1273
1274 int
i2d_ECPrivateKey(EC_KEY * ec_key,unsigned char ** out)1275 i2d_ECPrivateKey(EC_KEY *ec_key, unsigned char **out)
1276 {
1277 EC_PRIVATEKEY *ec_privatekey = NULL;
1278 const EC_GROUP *group;
1279 const BIGNUM *private_key;
1280 const EC_POINT *public_key = NULL;
1281 int ret = 0;
1282
1283 if (ec_key == NULL) {
1284 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1285 goto err;
1286 }
1287 if ((group = EC_KEY_get0_group(ec_key)) == NULL) {
1288 ECerror(EC_R_MISSING_PARAMETERS);
1289 goto err;
1290 }
1291 if ((private_key = EC_KEY_get0_private_key(ec_key)) == NULL) {
1292 ECerror(EC_R_KEYS_NOT_SET);
1293 goto err;
1294 }
1295 if ((ec_key->enc_flag & EC_PKEY_NO_PUBKEY) == 0) {
1296 if ((public_key = EC_KEY_get0_public_key(ec_key)) == NULL) {
1297 ECerror(EC_R_KEYS_NOT_SET);
1298 goto err;
1299 }
1300 }
1301
1302 if ((ec_privatekey = EC_PRIVATEKEY_new()) == NULL) {
1303 ECerror(ERR_R_MALLOC_FAILURE);
1304 goto err;
1305 }
1306 ec_privatekey->version = ec_key->version;
1307
1308 if (!ec_asn1_encode_private_key(group, private_key, ec_privatekey->privateKey))
1309 goto err;
1310 if ((ec_key->enc_flag & EC_PKEY_NO_PARAMETERS) == 0) {
1311 ECPKPARAMETERS *parameters;
1312
1313 if ((parameters = ec_asn1_group2pkparameters(group)) == NULL) {
1314 ECerror(ERR_R_EC_LIB);
1315 goto err;
1316 }
1317 ec_privatekey->parameters = parameters;
1318 }
1319 if (public_key != NULL) {
1320 uint8_t form;
1321
1322 form = EC_KEY_get_conv_form(ec_key);
1323 if (!ec_point_to_asn1_bit_string(group, public_key, form,
1324 &ec_privatekey->publicKey))
1325 goto err;
1326 }
1327
1328 if ((ret = i2d_EC_PRIVATEKEY(ec_privatekey, out)) <= 0) {
1329 ECerror(ERR_R_EC_LIB);
1330 goto err;
1331 }
1332
1333 err:
1334 EC_PRIVATEKEY_free(ec_privatekey);
1335
1336 return ret;
1337 }
1338 LCRYPTO_ALIAS(i2d_ECPrivateKey);
1339
1340 int
i2d_ECParameters(EC_KEY * ec_key,unsigned char ** out)1341 i2d_ECParameters(EC_KEY *ec_key, unsigned char **out)
1342 {
1343 if (ec_key == NULL) {
1344 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1345 return 0;
1346 }
1347 return i2d_ECPKParameters(ec_key->group, out);
1348 }
1349 LCRYPTO_ALIAS(i2d_ECParameters);
1350
1351 EC_KEY *
d2i_ECParameters(EC_KEY ** out_ec_key,const unsigned char ** in,long len)1352 d2i_ECParameters(EC_KEY **out_ec_key, const unsigned char **in, long len)
1353 {
1354 EC_KEY *ec_key = NULL;
1355
1356 if (in == NULL || *in == NULL) {
1357 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1358 goto err;
1359 }
1360 if (out_ec_key == NULL || (ec_key = *out_ec_key) == NULL)
1361 ec_key = EC_KEY_new();
1362 if (ec_key == NULL) {
1363 ECerror(ERR_R_MALLOC_FAILURE);
1364 goto err;
1365 }
1366
1367 if (!d2i_ECPKParameters(&ec_key->group, in, len)) {
1368 ECerror(ERR_R_EC_LIB);
1369 goto err;
1370 }
1371
1372 if (out_ec_key != NULL)
1373 *out_ec_key = ec_key;
1374
1375 return ec_key;
1376
1377 err:
1378 if (out_ec_key == NULL || *out_ec_key != ec_key)
1379 EC_KEY_free(ec_key);
1380
1381 return NULL;
1382 }
1383 LCRYPTO_ALIAS(d2i_ECParameters);
1384
1385 EC_KEY *
ECParameters_dup(EC_KEY * key)1386 ECParameters_dup(EC_KEY *key)
1387 {
1388 const unsigned char *p;
1389 unsigned char *der = NULL;
1390 EC_KEY *dup = NULL;
1391 int len;
1392
1393 if (key == NULL)
1394 return NULL;
1395
1396 if ((len = i2d_ECParameters(key, &der)) <= 0)
1397 return NULL;
1398
1399 p = der;
1400 dup = d2i_ECParameters(NULL, &p, len);
1401 freezero(der, len);
1402
1403 return dup;
1404 }
1405 LCRYPTO_ALIAS(ECParameters_dup);
1406
1407 EC_KEY *
o2i_ECPublicKey(EC_KEY ** in_ec_key,const unsigned char ** in,long len)1408 o2i_ECPublicKey(EC_KEY **in_ec_key, const unsigned char **in, long len)
1409 {
1410 EC_KEY *ec_key = NULL;
1411 const EC_GROUP *group;
1412 uint8_t form;
1413
1414 if (in_ec_key == NULL || (ec_key = *in_ec_key) == NULL) {
1415 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1416 return NULL;
1417 }
1418 if ((group = ec_key->group) == NULL) {
1419 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1420 return NULL;
1421 }
1422 if (len < 0) {
1423 ECerror(EC_R_INVALID_ARGUMENT);
1424 return NULL;
1425 }
1426
1427 if (!ec_point_from_octets(group, *in, len, &ec_key->pub_key, &form, NULL))
1428 return NULL;
1429 EC_KEY_set_conv_form(ec_key, form);
1430
1431 *in += len;
1432
1433 return ec_key;
1434 }
1435 LCRYPTO_ALIAS(o2i_ECPublicKey);
1436
1437 int
i2o_ECPublicKey(const EC_KEY * ec_key,unsigned char ** out)1438 i2o_ECPublicKey(const EC_KEY *ec_key, unsigned char **out)
1439 {
1440 unsigned char *buf = NULL;
1441 size_t buf_len = 0;
1442 int ret = 0;
1443
1444 if (ec_key == NULL) {
1445 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1446 goto err;
1447 }
1448
1449 if (!ec_point_to_octets(ec_key->group, ec_key->pub_key,
1450 ec_key->conv_form, &buf, &buf_len, NULL))
1451 goto err;
1452 if (buf_len > INT_MAX)
1453 goto err;
1454
1455 if (out != NULL && *out != NULL) {
1456 /* Muppet's answer to the Jackass show. */
1457 memcpy(*out, buf, buf_len);
1458 *out += buf_len;
1459 } else if (out != NULL) {
1460 *out = buf;
1461 buf = NULL;
1462 }
1463
1464 ret = buf_len;
1465
1466 err:
1467 freezero(buf, buf_len);
1468
1469 return ret;
1470 }
1471 LCRYPTO_ALIAS(i2o_ECPublicKey);
1472