summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ec_asn1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec/ec_asn1.c')
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c1461
1 files changed, 0 insertions, 1461 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
deleted file mode 100644
index ef318f8d43..0000000000
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ /dev/null
@@ -1,1461 +0,0 @@
1/* $OpenBSD: ec_asn1.c,v 1.111 2025/03/13 10:31:12 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
76int
77EC_GROUP_get_basis_type(const EC_GROUP *group)
78{
79 return 0;
80}
81LCRYPTO_ALIAS(EC_GROUP_get_basis_type);
82
83typedef struct x9_62_pentanomial_st {
84 long k1;
85 long k2;
86 long k3;
87} X9_62_PENTANOMIAL;
88
89typedef 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
105typedef 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
118typedef 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
124typedef 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
137typedef 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
146typedef struct ec_privatekey_st {
147 long version;
148 ASN1_OCTET_STRING *privateKey;
149 ECPKPARAMETERS *parameters;
150 ASN1_BIT_STRING *publicKey;
151} EC_PRIVATEKEY;
152
153static 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
177static 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
187static 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
195static 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
229static 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
238static 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
262static 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
272static 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
280static 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
303static 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
312static 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
329static 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
339static 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
363static 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
373static 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
418static 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
428static ECPARAMETERS *
429ECPARAMETERS_new(void)
430{
431 return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
432}
433
434static void
435ECPARAMETERS_free(ECPARAMETERS *a)
436{
437 ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
438}
439
440static 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
464static 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
474static ECPKPARAMETERS *
475d2i_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
481static int
482i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
483{
484 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
485}
486
487static ECPKPARAMETERS *
488ECPKPARAMETERS_new(void)
489{
490 return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
491}
492
493static void
494ECPKPARAMETERS_free(ECPKPARAMETERS *a)
495{
496 ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
497}
498
499static 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
530static 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
540static EC_PRIVATEKEY *
541d2i_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
547static int
548i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
549{
550 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
551}
552
553static EC_PRIVATEKEY *
554EC_PRIVATEKEY_new(void)
555{
556 return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
557}
558
559static void
560EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
561{
562 ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
563}
564
565static int
566ec_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
573static int
574ec_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
589static int
590ec_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
596static int
597ec_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
632static int
633ec_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
643static int
644ec_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
651static int
652ec_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
674static int
675ec_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
700static int
701ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn,
702 ASN1_OCTET_STRING *os)
703{
704 /* Zero-pad field element to byte length of p per SEC 1, 2.3.5. */
705 return ec_asn1_encode_bn(group, bn, BN_num_bytes(group->p), os);
706}
707
708static int
709ec_asn1_encode_private_key(const EC_GROUP *group, const BIGNUM *bn,
710 ASN1_OCTET_STRING *os)
711{
712 /* Zero-pad private key to byte length of order per SEC 1, C.4. */
713 return ec_asn1_encode_bn(group, bn, BN_num_bytes(group->order), os);
714}
715
716static int
717ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
718{
719 BIGNUM *a = NULL, *b = NULL;
720 int ret = 0;
721
722 if (group == NULL)
723 goto err;
724 if (curve == NULL || curve->a == NULL || curve->b == NULL)
725 goto err;
726
727 if ((a = BN_new()) == NULL || (b = BN_new()) == NULL) {
728 ECerror(ERR_R_MALLOC_FAILURE);
729 goto err;
730 }
731
732 if (!EC_GROUP_get_curve(group, NULL, a, b, NULL)) {
733 ECerror(ERR_R_EC_LIB);
734 goto err;
735 }
736
737 if (!ec_asn1_encode_field_element(group, a, curve->a)) {
738 ECerror(ERR_R_EC_LIB);
739 goto err;
740 }
741 if (!ec_asn1_encode_field_element(group, b, curve->b)) {
742 ECerror(ERR_R_EC_LIB);
743 goto err;
744 }
745
746 ASN1_BIT_STRING_free(curve->seed);
747 curve->seed = NULL;
748
749 if (group->seed != NULL) {
750 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
751 ECerror(ERR_R_MALLOC_FAILURE);
752 goto err;
753 }
754 if (!ASN1_BIT_STRING_set(curve->seed,
755 group->seed, group->seed_len)) {
756 ECerror(ERR_R_ASN1_LIB);
757 goto err;
758 }
759 if (!asn1_abs_set_unused_bits(curve->seed, 0)) {
760 ECerror(ERR_R_ASN1_LIB);
761 goto err;
762 }
763 }
764
765 ret = 1;
766
767 err:
768 BN_free(a);
769 BN_free(b);
770
771 return ret;
772}
773
774static ECPARAMETERS *
775ec_asn1_group2parameters(const EC_GROUP *group)
776{
777 ECPARAMETERS *parameters = NULL;
778 const EC_POINT *generator = NULL;
779 const BIGNUM *order, *cofactor;
780 uint8_t form;
781
782 if ((parameters = ECPARAMETERS_new()) == NULL) {
783 ECerror(ERR_R_MALLOC_FAILURE);
784 goto err;
785 }
786
787 parameters->version = 0x1;
788
789 if (!ec_asn1_group2fieldid(group, parameters->fieldID)) {
790 ECerror(ERR_R_EC_LIB);
791 goto err;
792 }
793
794 if (!ec_asn1_group2curve(group, parameters->curve)) {
795 ECerror(ERR_R_EC_LIB);
796 goto err;
797 }
798
799 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
800 ECerror(EC_R_UNDEFINED_GENERATOR);
801 goto err;
802 }
803
804 form = EC_GROUP_get_point_conversion_form(group);
805 if (!ec_point_to_asn1_octet_string(group, generator, form, &parameters->base))
806 goto err;
807
808 if ((order = EC_GROUP_get0_order(group)) == NULL) {
809 ECerror(ERR_R_EC_LIB);
810 goto err;
811 }
812 if (BN_is_zero(order)) {
813 ECerror(ERR_R_EC_LIB);
814 goto err;
815 }
816 ASN1_INTEGER_free(parameters->order);
817 if ((parameters->order = BN_to_ASN1_INTEGER(order, NULL)) == NULL) {
818 ECerror(ERR_R_ASN1_LIB);
819 goto err;
820 }
821
822 ASN1_INTEGER_free(parameters->cofactor);
823 parameters->cofactor = NULL;
824 if ((cofactor = EC_GROUP_get0_cofactor(group)) == NULL) {
825 ECerror(ERR_R_EC_LIB);
826 goto err;
827 }
828 if (!BN_is_zero(cofactor)) {
829 if ((parameters->cofactor = BN_to_ASN1_INTEGER(cofactor,
830 NULL)) == NULL) {
831 ECerror(ERR_R_ASN1_LIB);
832 goto err;
833 }
834 }
835
836 return parameters;
837
838 err:
839 ECPARAMETERS_free(parameters);
840
841 return NULL;
842}
843
844static ECPKPARAMETERS *
845ec_asn1_group2pkparameters(const EC_GROUP *group)
846{
847 ECPKPARAMETERS *pkparameters;
848 ECPARAMETERS *parameters;
849 ASN1_OBJECT *aobj;
850 int nid;
851
852 if ((pkparameters = ECPKPARAMETERS_new()) == NULL) {
853 ECerror(ERR_R_MALLOC_FAILURE);
854 goto err;
855 }
856
857 if ((EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) != 0) {
858 if ((nid = EC_GROUP_get_curve_name(group)) == NID_undef)
859 goto err;
860 if ((aobj = OBJ_nid2obj(nid)) == NULL)
861 goto err;
862 pkparameters->type = ECPK_PARAM_NAMED_CURVE;
863 pkparameters->value.named_curve = aobj;
864 } else {
865 if ((parameters = ec_asn1_group2parameters(group)) == NULL)
866 goto err;
867 pkparameters->type = ECPK_PARAM_EXPLICIT;
868 pkparameters->value.parameters = parameters;
869 parameters = NULL;
870 }
871
872 return pkparameters;
873
874 err:
875 ECPKPARAMETERS_free(pkparameters);
876
877 return NULL;
878}
879
880static int
881ec_asn1_is_prime_field(const X9_62_FIELDID *fieldid)
882{
883 int nid;
884
885 if (fieldid == NULL) {
886 ECerror(EC_R_ASN1_ERROR);
887 return 0;
888 }
889 if ((nid = OBJ_obj2nid(fieldid->fieldType)) == NID_undef) {
890 ECerror(EC_R_INVALID_FIELD);
891 return 0;
892 }
893 if (nid == NID_X9_62_characteristic_two_field) {
894 ECerror(EC_R_GF2M_NOT_SUPPORTED);
895 return 0;
896 }
897 if (nid != NID_X9_62_prime_field) {
898 ECerror(EC_R_UNSUPPORTED_FIELD);
899 return 0;
900 }
901
902 /* We can't check that this is actually a prime due to DoS risk. */
903 if (fieldid->p.prime == NULL) {
904 ECerror(EC_R_INVALID_FIELD);
905 return 0;
906 }
907
908 return 1;
909}
910
911static int
912ec_asn1_parameters_curve2group(const X9_62_CURVE *curve,
913 const ASN1_INTEGER *prime, EC_GROUP **out_group)
914{
915 EC_GROUP *group = NULL;
916 BIGNUM *p = NULL, *a = NULL, *b = NULL;
917 int ret = 0;
918
919 if (*out_group != NULL)
920 goto err;
921
922 if ((p = ASN1_INTEGER_to_BN(prime, NULL)) == NULL)
923 goto err;
924 if ((a = BN_bin2bn(curve->a->data, curve->a->length, NULL)) == NULL)
925 goto err;
926 if ((b = BN_bin2bn(curve->b->data, curve->b->length, NULL)) == NULL)
927 goto err;
928
929 /*
930 * XXX - move these checks to ec_GFp_simple_group_set_curve()?
931 * What about checking 0 <= a, b < p?
932 */
933 if (BN_is_zero(p) || BN_is_negative(p)) {
934 ECerror(EC_R_INVALID_FIELD);
935 goto err;
936 }
937 if (BN_num_bits(p) > OPENSSL_ECC_MAX_FIELD_BITS) {
938 ECerror(EC_R_FIELD_TOO_LARGE);
939 goto err;
940 }
941
942 if ((group = EC_GROUP_new_curve_GFp(p, a, b, NULL)) == NULL)
943 goto err;
944
945 *out_group = group;
946 group = NULL;
947
948 ret = 1;
949
950 err:
951 BN_free(p);
952 BN_free(a);
953 BN_free(b);
954 EC_GROUP_free(group);
955
956 return ret;
957}
958
959static int
960ec_asn1_set_group_parameters(const ECPARAMETERS *params, EC_GROUP *group)
961{
962 EC_POINT *generator = NULL;
963 BIGNUM *order = NULL, *cofactor = NULL;
964 const ASN1_BIT_STRING *seed;
965 uint8_t form;
966 int ret = 0;
967
968 if (!ec_point_from_asn1_octet_string(group, params->base, &generator, &form))
969 goto err;
970 EC_GROUP_set_point_conversion_form(group, form);
971
972 if ((order = ASN1_INTEGER_to_BN(params->order, NULL)) == NULL) {
973 ECerror(ERR_R_ASN1_LIB);
974 goto err;
975 }
976 if (params->cofactor != NULL) {
977 if ((cofactor = ASN1_INTEGER_to_BN(params->cofactor,
978 NULL)) == NULL) {
979 ECerror(ERR_R_ASN1_LIB);
980 goto err;
981 }
982 }
983
984 /* Checks the Hasse bound and sets the cofactor if possible or fails. */
985 if (!EC_GROUP_set_generator(group, generator, order, cofactor)) {
986 ECerror(ERR_R_EC_LIB);
987 goto err;
988 }
989
990 if ((seed = params->curve->seed) != NULL) {
991 if (EC_GROUP_set_seed(group, seed->data, seed->length) == 0) {
992 ECerror(ERR_R_MALLOC_FAILURE);
993 goto err;
994 }
995 }
996
997 ret = 1;
998
999 err:
1000 EC_POINT_free(generator);
1001 BN_free(order);
1002 BN_free(cofactor);
1003
1004 return ret;
1005}
1006
1007static int
1008ec_asn1_parameters_extract_prime_group(const ECPARAMETERS *params,
1009 EC_GROUP **out_group)
1010{
1011 EC_GROUP *group = NULL;
1012 int ret = 0;
1013
1014 if (*out_group != NULL)
1015 goto err;
1016
1017 if (!ec_asn1_is_prime_field(params->fieldID))
1018 goto err;
1019 if (!ec_asn1_parameters_curve2group(params->curve,
1020 params->fieldID->p.prime, &group))
1021 goto err;
1022 if (!ec_asn1_set_group_parameters(params, group))
1023 goto err;
1024
1025 *out_group = group;
1026 group = NULL;
1027
1028 ret = 1;
1029
1030 err:
1031 EC_GROUP_free(group);
1032
1033 return ret;
1034}
1035
1036static EC_GROUP *
1037ec_asn1_parameters2group(const ECPARAMETERS *params)
1038{
1039 EC_GROUP *group = NULL;
1040 int nid = NID_undef;
1041
1042 if (params == NULL) {
1043 ECerror(EC_R_ASN1_ERROR);
1044 goto err;
1045 }
1046
1047 if (!ec_asn1_parameters_extract_prime_group(params, &group))
1048 goto err;
1049 if (!ec_group_is_builtin_curve(group, &nid))
1050 goto err;
1051 EC_GROUP_set_curve_name(group, nid);
1052
1053 return group;
1054
1055 err:
1056 EC_GROUP_free(group);
1057
1058 return NULL;
1059}
1060
1061static EC_GROUP *
1062ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1063{
1064 EC_GROUP *group;
1065 int nid;
1066
1067 if (params->type == ECPK_PARAM_NAMED_CURVE) {
1068 if ((nid = OBJ_obj2nid(params->value.named_curve)) == NID_undef) {
1069 ECerror(EC_R_UNKNOWN_GROUP);
1070 return NULL;
1071 }
1072 if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
1073 ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1074 return NULL;
1075 }
1076 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
1077 } else if (params->type == ECPK_PARAM_EXPLICIT) {
1078 group = ec_asn1_parameters2group(params->value.parameters);
1079 if (group == NULL) {
1080 ECerror(ERR_R_EC_LIB);
1081 return NULL;
1082 }
1083 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1084 } else if (params->type == ECPK_PARAM_IMPLICITLY_CA) {
1085 return NULL;
1086 } else {
1087 ECerror(EC_R_ASN1_ERROR);
1088 return NULL;
1089 }
1090
1091 return group;
1092}
1093
1094EC_GROUP *
1095d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1096{
1097 EC_GROUP *group = NULL;
1098 ECPKPARAMETERS *params;
1099
1100 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
1101 ECerror(EC_R_D2I_ECPKPARAMETERS_FAILURE);
1102 goto err;
1103 }
1104 if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1105 ECerror(EC_R_PKPARAMETERS2GROUP_FAILURE);
1106 goto err;
1107 }
1108
1109 if (a != NULL) {
1110 EC_GROUP_free(*a);
1111 *a = group;
1112 }
1113
1114 err:
1115 ECPKPARAMETERS_free(params);
1116
1117 return group;
1118}
1119LCRYPTO_ALIAS(d2i_ECPKParameters);
1120
1121int
1122i2d_ECPKParameters(const EC_GROUP *group, unsigned char **out_der)
1123{
1124 ECPKPARAMETERS *parameters;
1125 int ret = 0;
1126
1127 if ((parameters = ec_asn1_group2pkparameters(group)) == NULL) {
1128 ECerror(EC_R_GROUP2PKPARAMETERS_FAILURE);
1129 goto err;
1130 }
1131 if ((ret = i2d_ECPKPARAMETERS(parameters, out_der)) <= 0) {
1132 ECerror(EC_R_I2D_ECPKPARAMETERS_FAILURE);
1133 goto err;
1134 }
1135
1136 err:
1137 ECPKPARAMETERS_free(parameters);
1138
1139 return ret;
1140}
1141LCRYPTO_ALIAS(i2d_ECPKParameters);
1142
1143static int
1144ec_key_set_group_from_parameters(EC_KEY *ec_key, const ECPKPARAMETERS *params)
1145{
1146 EC_GROUP *group = NULL;
1147 int ret = 0;
1148
1149 /* Use group in parameters, if any. Fall back to existing group. */
1150 if (params != NULL) {
1151 if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1152 goto err;
1153 if (!EC_KEY_set_group(ec_key, group))
1154 goto err;
1155 }
1156 if (ec_key->group == NULL)
1157 goto err;
1158
1159 ret = 1;
1160
1161 err:
1162 EC_GROUP_free(group);
1163
1164 return ret;
1165}
1166
1167static int
1168ec_key_set_private_key(EC_KEY *ec_key, const ASN1_OCTET_STRING *aos)
1169{
1170 BIGNUM *priv_key = NULL;
1171 int ret = 0;
1172
1173 if (aos == NULL) {
1174 ECerror(EC_R_MISSING_PRIVATE_KEY);
1175 goto err;
1176 }
1177
1178 /*
1179 * XXX - Sec 1, C.4 requires that this octet string be padded to the
1180 * byte length of the group's order. This can't be enforced because
1181 * i2d_ECPrivateKey() used to produce a semi-compatible ad hoc format.
1182 */
1183 if ((priv_key = BN_bin2bn(aos->data, aos->length, NULL)) == NULL)
1184 goto err;
1185 if (!EC_KEY_set_private_key(ec_key, priv_key))
1186 goto err;
1187
1188 ret = 1;
1189
1190 err:
1191 BN_free(priv_key);
1192
1193 return ret;
1194}
1195
1196static int
1197ec_key_set_public_key(EC_KEY *ec_key, const ASN1_BIT_STRING *abs)
1198{
1199 EC_POINT *pub_key = NULL;
1200 uint8_t form;
1201 int ret = 0;
1202
1203 if (abs == NULL) {
1204 ec_key->enc_flag |= EC_PKEY_NO_PUBKEY;
1205 return eckey_compute_pubkey(ec_key);
1206 }
1207
1208 /* XXX - SEC 1, 2.3.4 does not allow hybrid encoding. */
1209 if (!ec_point_from_asn1_bit_string(ec_key->group, abs, &pub_key, &form))
1210 goto err;
1211 if (!EC_KEY_set_public_key(ec_key, pub_key))
1212 goto err;
1213 EC_KEY_set_conv_form(ec_key, form);
1214
1215 ret = 1;
1216
1217 err:
1218 EC_POINT_free(pub_key);
1219
1220 return ret;
1221}
1222
1223EC_KEY *
1224d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len)
1225{
1226 EC_KEY *ec_key = NULL;
1227 EC_PRIVATEKEY *ec_privatekey = NULL;
1228
1229 if (out_ec_key == NULL || (ec_key = *out_ec_key) == NULL)
1230 ec_key = EC_KEY_new();
1231 if (ec_key == NULL)
1232 goto err;
1233
1234 if ((ec_privatekey = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) {
1235 ECerror(ERR_R_EC_LIB);
1236 goto err;
1237 }
1238
1239 ec_key->version = ec_privatekey->version;
1240 if (!ec_key_set_group_from_parameters(ec_key, ec_privatekey->parameters))
1241 goto err;
1242 if (!ec_key_set_private_key(ec_key, ec_privatekey->privateKey))
1243 goto err;
1244 if (!ec_key_set_public_key(ec_key, ec_privatekey->publicKey))
1245 goto err;
1246
1247 EC_PRIVATEKEY_free(ec_privatekey);
1248 ec_privatekey = NULL;
1249
1250 if (out_ec_key != NULL)
1251 *out_ec_key = ec_key;
1252
1253 return ec_key;
1254
1255 err:
1256 if (out_ec_key == NULL || *out_ec_key != ec_key)
1257 EC_KEY_free(ec_key);
1258 EC_PRIVATEKEY_free(ec_privatekey);
1259
1260 return NULL;
1261}
1262LCRYPTO_ALIAS(d2i_ECPrivateKey);
1263
1264int
1265i2d_ECPrivateKey(EC_KEY *ec_key, unsigned char **out)
1266{
1267 EC_PRIVATEKEY *ec_privatekey = NULL;
1268 const EC_GROUP *group;
1269 const BIGNUM *private_key;
1270 const EC_POINT *public_key = NULL;
1271 int ret = 0;
1272
1273 if (ec_key == NULL) {
1274 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1275 goto err;
1276 }
1277 if ((group = EC_KEY_get0_group(ec_key)) == NULL) {
1278 ECerror(EC_R_MISSING_PARAMETERS);
1279 goto err;
1280 }
1281 if ((private_key = EC_KEY_get0_private_key(ec_key)) == NULL) {
1282 ECerror(EC_R_KEYS_NOT_SET);
1283 goto err;
1284 }
1285 if ((ec_key->enc_flag & EC_PKEY_NO_PUBKEY) == 0) {
1286 if ((public_key = EC_KEY_get0_public_key(ec_key)) == NULL) {
1287 ECerror(EC_R_KEYS_NOT_SET);
1288 goto err;
1289 }
1290 }
1291
1292 if ((ec_privatekey = EC_PRIVATEKEY_new()) == NULL) {
1293 ECerror(ERR_R_MALLOC_FAILURE);
1294 goto err;
1295 }
1296 ec_privatekey->version = ec_key->version;
1297
1298 if (!ec_asn1_encode_private_key(group, private_key, ec_privatekey->privateKey))
1299 goto err;
1300 if ((ec_key->enc_flag & EC_PKEY_NO_PARAMETERS) == 0) {
1301 ECPKPARAMETERS *parameters;
1302
1303 if ((parameters = ec_asn1_group2pkparameters(group)) == NULL) {
1304 ECerror(ERR_R_EC_LIB);
1305 goto err;
1306 }
1307 ec_privatekey->parameters = parameters;
1308 }
1309 if (public_key != NULL) {
1310 uint8_t form;
1311
1312 form = EC_KEY_get_conv_form(ec_key);
1313 if (!ec_point_to_asn1_bit_string(group, public_key, form,
1314 &ec_privatekey->publicKey))
1315 goto err;
1316 }
1317
1318 if ((ret = i2d_EC_PRIVATEKEY(ec_privatekey, out)) <= 0) {
1319 ECerror(ERR_R_EC_LIB);
1320 goto err;
1321 }
1322
1323 err:
1324 EC_PRIVATEKEY_free(ec_privatekey);
1325
1326 return ret;
1327}
1328LCRYPTO_ALIAS(i2d_ECPrivateKey);
1329
1330int
1331i2d_ECParameters(EC_KEY *ec_key, unsigned char **out)
1332{
1333 if (ec_key == NULL) {
1334 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1335 return 0;
1336 }
1337 return i2d_ECPKParameters(ec_key->group, out);
1338}
1339LCRYPTO_ALIAS(i2d_ECParameters);
1340
1341EC_KEY *
1342d2i_ECParameters(EC_KEY **out_ec_key, const unsigned char **in, long len)
1343{
1344 EC_KEY *ec_key = NULL;
1345
1346 if (in == NULL || *in == NULL) {
1347 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1348 goto err;
1349 }
1350 if (out_ec_key == NULL || (ec_key = *out_ec_key) == NULL)
1351 ec_key = EC_KEY_new();
1352 if (ec_key == NULL) {
1353 ECerror(ERR_R_MALLOC_FAILURE);
1354 goto err;
1355 }
1356
1357 if (!d2i_ECPKParameters(&ec_key->group, in, len)) {
1358 ECerror(ERR_R_EC_LIB);
1359 goto err;
1360 }
1361
1362 if (out_ec_key != NULL)
1363 *out_ec_key = ec_key;
1364
1365 return ec_key;
1366
1367 err:
1368 if (out_ec_key == NULL || *out_ec_key != ec_key)
1369 EC_KEY_free(ec_key);
1370
1371 return NULL;
1372}
1373LCRYPTO_ALIAS(d2i_ECParameters);
1374
1375EC_KEY *
1376ECParameters_dup(EC_KEY *key)
1377{
1378 const unsigned char *p;
1379 unsigned char *der = NULL;
1380 EC_KEY *dup = NULL;
1381 int len;
1382
1383 if (key == NULL)
1384 return NULL;
1385
1386 if ((len = i2d_ECParameters(key, &der)) <= 0)
1387 return NULL;
1388
1389 p = der;
1390 dup = d2i_ECParameters(NULL, &p, len);
1391 freezero(der, len);
1392
1393 return dup;
1394}
1395LCRYPTO_ALIAS(ECParameters_dup);
1396
1397EC_KEY *
1398o2i_ECPublicKey(EC_KEY **in_ec_key, const unsigned char **in, long len)
1399{
1400 EC_KEY *ec_key = NULL;
1401 const EC_GROUP *group;
1402 uint8_t form;
1403
1404 if (in_ec_key == NULL || (ec_key = *in_ec_key) == NULL) {
1405 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1406 return NULL;
1407 }
1408 if ((group = ec_key->group) == NULL) {
1409 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1410 return NULL;
1411 }
1412 if (len < 0) {
1413 ECerror(EC_R_INVALID_ARGUMENT);
1414 return NULL;
1415 }
1416
1417 if (!ec_point_from_octets(group, *in, len, &ec_key->pub_key, &form, NULL))
1418 return NULL;
1419 EC_KEY_set_conv_form(ec_key, form);
1420
1421 *in += len;
1422
1423 return ec_key;
1424}
1425LCRYPTO_ALIAS(o2i_ECPublicKey);
1426
1427int
1428i2o_ECPublicKey(const EC_KEY *ec_key, unsigned char **out)
1429{
1430 unsigned char *buf = NULL;
1431 size_t buf_len = 0;
1432 int ret = 0;
1433
1434 if (ec_key == NULL) {
1435 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1436 goto err;
1437 }
1438
1439 if (!ec_point_to_octets(ec_key->group, ec_key->pub_key,
1440 ec_key->conv_form, &buf, &buf_len, NULL))
1441 goto err;
1442 if (buf_len > INT_MAX)
1443 goto err;
1444
1445 if (out != NULL && *out != NULL) {
1446 /* Muppet's answer to the Jackass show. */
1447 memcpy(*out, buf, buf_len);
1448 *out += buf_len;
1449 } else if (out != NULL) {
1450 *out = buf;
1451 buf = NULL;
1452 }
1453
1454 ret = buf_len;
1455
1456 err:
1457 freezero(buf, buf_len);
1458
1459 return ret;
1460}
1461LCRYPTO_ALIAS(i2o_ECPublicKey);