diff options
Diffstat (limited to 'src/lib/libcrypto/ec/ec_asn1.c')
-rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 1461 |
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 | |||
76 | int | ||
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 * | ||
429 | ECPARAMETERS_new(void) | ||
430 | { | ||
431 | return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it); | ||
432 | } | ||
433 | |||
434 | static void | ||
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 * | ||
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 | ||
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 * | ||
488 | ECPKPARAMETERS_new(void) | ||
489 | { | ||
490 | return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it); | ||
491 | } | ||
492 | |||
493 | static void | ||
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 * | ||
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 | ||
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 * | ||
554 | EC_PRIVATEKEY_new(void) | ||
555 | { | ||
556 | return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it); | ||
557 | } | ||
558 | |||
559 | static void | ||
560 | EC_PRIVATEKEY_free(EC_PRIVATEKEY *a) | ||
561 | { | ||
562 | ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it); | ||
563 | } | ||
564 | |||
565 | static int | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
701 | ec_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 | |||
708 | static int | ||
709 | ec_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 | |||
716 | static int | ||
717 | ec_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 | |||
774 | static ECPARAMETERS * | ||
775 | ec_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, ¶meters->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 | |||
844 | static ECPKPARAMETERS * | ||
845 | ec_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 | |||
880 | static int | ||
881 | ec_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 | |||
911 | static int | ||
912 | ec_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 | |||
959 | static int | ||
960 | ec_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 | |||
1007 | static int | ||
1008 | ec_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 | |||
1036 | static EC_GROUP * | ||
1037 | ec_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 | |||
1061 | static EC_GROUP * | ||
1062 | ec_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 | |||
1094 | EC_GROUP * | ||
1095 | d2i_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 | } | ||
1119 | LCRYPTO_ALIAS(d2i_ECPKParameters); | ||
1120 | |||
1121 | int | ||
1122 | i2d_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 | } | ||
1141 | LCRYPTO_ALIAS(i2d_ECPKParameters); | ||
1142 | |||
1143 | static int | ||
1144 | ec_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 | |||
1167 | static int | ||
1168 | ec_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 | |||
1196 | static int | ||
1197 | ec_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 | |||
1223 | EC_KEY * | ||
1224 | d2i_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 | } | ||
1262 | LCRYPTO_ALIAS(d2i_ECPrivateKey); | ||
1263 | |||
1264 | int | ||
1265 | i2d_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 | } | ||
1328 | LCRYPTO_ALIAS(i2d_ECPrivateKey); | ||
1329 | |||
1330 | int | ||
1331 | i2d_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 | } | ||
1339 | LCRYPTO_ALIAS(i2d_ECParameters); | ||
1340 | |||
1341 | EC_KEY * | ||
1342 | d2i_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 | } | ||
1373 | LCRYPTO_ALIAS(d2i_ECParameters); | ||
1374 | |||
1375 | EC_KEY * | ||
1376 | ECParameters_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 | } | ||
1395 | LCRYPTO_ALIAS(ECParameters_dup); | ||
1396 | |||
1397 | EC_KEY * | ||
1398 | o2i_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 | } | ||
1425 | LCRYPTO_ALIAS(o2i_ECPublicKey); | ||
1426 | |||
1427 | int | ||
1428 | i2o_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 | } | ||
1461 | LCRYPTO_ALIAS(i2o_ECPublicKey); | ||