Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * All rights reserved.
5 : : * Copyright (c) 2021 Kyle Evans <kevans@FreeBSD.org>
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : * 1. Redistributions of source code must retain the above copyright
11 : : * notice, this list of conditions and the following disclaimer
12 : : * in this position and unchanged.
13 : : * 2. Redistributions in binary form must reproduce the above copyright
14 : : * notice, this list of conditions and the following disclaimer in the
15 : : * documentation and/or other materials provided with the distribution.
16 : : *
17 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
18 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
21 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : : */
28 : :
29 : : #include <sys/stat.h>
30 : : #include <sys/param.h>
31 : :
32 : : #include <ctype.h>
33 : : #include <fcntl.h>
34 : : #include <strings.h>
35 : :
36 : : #include <libder.h>
37 : :
38 : : #define WITH_STDLIB
39 : : #include <libecc/libsig.h>
40 : : #undef WITH_STDLIB
41 : :
42 : : #include "pkg.h"
43 : : #include "private/event.h"
44 : : #include "private/pkg.h"
45 : : #include "private/pkgsign.h"
46 : :
47 : : struct ecc_sign_ctx {
48 : : struct pkgsign_ctx sctx;
49 : : ec_params params;
50 : : ec_key_pair keypair;
51 : : ec_alg_type sig_alg;
52 : : hash_alg_type sig_hash;
53 : : bool loaded;
54 : : };
55 : :
56 : : /* Grab the ossl context from a pkgsign_ctx. */
57 : : #define ECC_CTX(c) ((struct ecc_sign_ctx *)(c))
58 : :
59 : : #define PUBKEY_UNCOMPRESSED 0x04
60 : :
61 : : #ifndef MAX
62 : : #define MAX(a,b) (((a)>(b))?(a):(b))
63 : : #endif
64 : :
65 : : static const uint8_t oid_ecpubkey[] = \
66 : : { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 };
67 : :
68 : : static const uint8_t oid_secp[] = \
69 : : { 0x2b, 0x81, 0x04, 0x00 };
70 : : static const uint8_t oid_secp256k1[] = \
71 : : { 0x2b, 0x81, 0x04, 0x00, 0x0a };
72 : : static const uint8_t oid_brainpoolP[] = \
73 : : { 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01 };
74 : :
75 : : #define ENTRY(name, params) { #name, sizeof(#name) - 1, params }
76 : : static const struct pkgkey_map_entry {
77 : : const char *name;
78 : : size_t namesz;
79 : : const ec_str_params *params;
80 : : } pkgkey_map[] = {
81 : : ENTRY(WEI25519, &wei25519_str_params),
82 : : ENTRY(SECP256K1, &secp256k1_str_params),
83 : : ENTRY(SECP384R1, &secp384r1_str_params),
84 : : ENTRY(SECP512R1, &secp521r1_str_params),
85 : : ENTRY(BRAINPOOLP256R1, &brainpoolp256r1_str_params),
86 : : ENTRY(BRAINPOOLP256T1, &brainpoolp256t1_str_params),
87 : : ENTRY(BRAINPOOLP320R1, &brainpoolp320r1_str_params),
88 : : ENTRY(BRAINPOOLP320T1, &brainpoolp320t1_str_params),
89 : : ENTRY(BRAINPOOLP384R1, &brainpoolp384r1_str_params),
90 : : ENTRY(BRAINPOOLP384T1, &brainpoolp384t1_str_params),
91 : : ENTRY(BRAINPOOLP512R1, &brainpoolp512r1_str_params),
92 : : ENTRY(BRAINPOOLP512T1, &brainpoolp512t1_str_params),
93 : : };
94 : :
95 : : static const char pkgkey_app[] = "pkg";
96 : : static const char pkgkey_signer[] = "ecc";
97 : :
98 : : static const ec_str_params *
99 : 2 : ecc_pkgkey_params(const uint8_t *curve, size_t curvesz)
100 : : {
101 : : const struct pkgkey_map_entry *entry;
102 : :
103 [ + - ]: 3 : for (size_t i = 0; i < NELEM(pkgkey_map); i++) {
104 : 3 : entry = &pkgkey_map[i];
105 [ + + ]: 3 : if (curvesz != entry->namesz)
106 : 1 : continue;
107 [ + - ]: 2 : if (memcmp(curve, entry->name, curvesz) == 0)
108 : 2 : return (entry->params);
109 : 0 : }
110 : :
111 : 0 : return (NULL);
112 : 2 : }
113 : :
114 : : /*
115 : : * PKCS#8 Key:
116 : : * PublicKeyInfo ::= SEQUENCE {
117 : : * algorithm AlgorithmIdentifier,
118 : : * PublicKey BIT STRING
119 : : * }
120 : : *
121 : : * AlgorithmIdentifier ::= SEQUENCE {
122 : : * algorithm OBJECT IDENTIFIER,
123 : : * parameters ANY DEFINED BY algorithm OPTIONAL
124 : : * }
125 : : *
126 : : */
127 : : /* XXX Should eventually support other kinds of keys. */
128 : : static int
129 : 2 : ecc_pubkey_write_pkcs8(const uint8_t *keydata, size_t keysz,
130 : : uint8_t **buf, size_t *buflen)
131 : : {
132 : : uint8_t keybuf[EC_PUB_KEY_MAX_SIZE + 2], *outbuf;
133 : : struct libder_ctx *ctx;
134 : : struct libder_object *keybits, *oid, *params, *root;
135 : : int rc;
136 : : bool ok;
137 : :
138 [ - + ]: 2 : if (keysz > sizeof(keybuf) - 2)
139 : 0 : return (EPKG_FATAL);
140 : :
141 : 2 : ctx = libder_open();
142 [ + - ]: 2 : if (ctx == NULL)
143 : 0 : return (EPKG_FATAL);
144 : :
145 : 2 : rc = EPKG_FATAL;
146 : 2 : root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
147 [ + - ]: 2 : if (root == NULL)
148 : 0 : goto out;
149 : :
150 : 2 : params = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
151 [ + - ]: 2 : if (params == NULL)
152 : 0 : goto out;
153 : :
154 : 2 : ok = libder_obj_append(root, params);
155 [ + - ]: 2 : assert(ok);
156 : :
157 : : /* id-ecPublicKey */
158 : 2 : oid = libder_obj_alloc_simple(ctx, BT_OID, oid_ecpubkey,
159 : : sizeof(oid_ecpubkey));
160 [ + - ]: 2 : if (oid == NULL)
161 : 0 : goto out;
162 : 2 : ok = libder_obj_append(params, oid);
163 [ + - ]: 2 : assert(ok);
164 : :
165 : : /*
166 : : * secp256k1, we should eventually allow other curves and actually
167 : : * construct the OID.
168 : : */
169 : 2 : oid = libder_obj_alloc_simple(ctx, BT_OID, oid_secp256k1,
170 : : sizeof(oid_secp256k1));
171 [ + - ]: 2 : if (oid == NULL)
172 : 0 : goto out;
173 : 2 : ok = libder_obj_append(params, oid);
174 [ + - ]: 2 : assert(ok);
175 : :
176 : 2 : memset(keybuf, 0, sizeof(keybuf));
177 : 2 : keybuf[0] = 0; /* No unused bits */
178 : 2 : keybuf[1] = PUBKEY_UNCOMPRESSED;
179 : 2 : memcpy(&keybuf[2], keydata, keysz);
180 : :
181 : 4 : keybits = libder_obj_alloc_simple(ctx, BT_BITSTRING, &keybuf[0],
182 : 2 : keysz + 2);
183 [ + - ]: 2 : if (keybits == NULL)
184 : 0 : goto out;
185 : 2 : ok = libder_obj_append(root, keybits);
186 [ + - ]: 2 : assert(ok);
187 : :
188 : : /* Finally, write it out. */
189 : 2 : *buflen = 0;
190 : 2 : outbuf = libder_write(ctx, root, NULL, buflen);
191 [ + - ]: 4 : if (outbuf != NULL) {
192 : 2 : *buf = outbuf;
193 : 2 : rc = EPKG_OK;
194 : 2 : }
195 : :
196 : : out:
197 : 2 : libder_obj_free(root);
198 : 2 : libder_close(ctx);
199 : 2 : return (rc);
200 : 2 : }
201 : :
202 : : /*
203 : : * pkg key (only for EdDSA):
204 : : * PkgPublicKeyInfo ::= SEQUENCE {
205 : : * Application UTF8String
206 : : * Version INTEGER
207 : : * Signer UTF8String
208 : : * KeyType UTF8String
209 : : * Public BOOLEAN
210 : : * Key BIT STRING
211 : : * }
212 : : *
213 : : * "Application" will literally contain the string: "pkg"
214 : : * "Version" must be 1
215 : : * "Signer" must contain the part after "pkgsign_"
216 : : * "KeyType" is signer-defined; for ECC, it must be the curve_name
217 : : * "Public" is self-explanatory
218 : : * "Key" is the key data itself, encoded as the PKCS#8 public key bit string
219 : : * with a lead byte indicating uncompressed (0x04)
220 : : */
221 : : static int
222 : 8 : ecc_write_pkgkey(const ec_params *params, uint8_t public,
223 : : const uint8_t *keydata, size_t keysz, uint8_t **buf, size_t *buflen)
224 : : {
225 : : uint8_t keybuf[MAX(EC_PRIV_KEY_MAX_SIZE, EC_PUB_KEY_MAX_SIZE) + 2];
226 : : uint8_t *outbuf;
227 : : struct libder_ctx *ctx;
228 : : struct libder_object *keybits, *obj, *root;
229 : : int rc;
230 : 8 : uint8_t version = 1;
231 : : bool ok;
232 : :
233 [ - + ]: 8 : if (keysz > sizeof(keybuf) - 2)
234 : 0 : return (EPKG_FATAL);
235 : :
236 : 8 : ctx = libder_open();
237 [ + - ]: 8 : if (ctx == NULL)
238 : 0 : return (EPKG_FATAL);
239 : :
240 : 8 : rc = EPKG_FATAL;
241 : 8 : root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
242 [ + - ]: 8 : if (root == NULL)
243 : 0 : goto out;
244 : :
245 : : /* Application */
246 : 8 : obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, pkgkey_app,
247 : : sizeof(pkgkey_app) - 1);
248 [ + - ]: 8 : if (obj == NULL)
249 : 0 : goto out;
250 : 8 : ok = libder_obj_append(root, obj);
251 [ + - ]: 8 : assert(ok);
252 : :
253 : : /* Version */
254 : 8 : obj = libder_obj_alloc_simple(ctx, BT_INTEGER, &version, sizeof(version));
255 [ + - ]: 8 : if (obj == NULL)
256 : 0 : goto out;
257 : 8 : ok = libder_obj_append(root, obj);
258 [ + - ]: 8 : assert(ok);
259 : :
260 : : /* Signer */
261 : 8 : obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, pkgkey_signer,
262 : : sizeof(pkgkey_signer) - 1);
263 [ + - ]: 8 : if (obj == NULL)
264 : 0 : goto out;
265 : 8 : ok = libder_obj_append(root, obj);
266 [ + - ]: 8 : assert(ok);
267 : :
268 : : /* KeyType */
269 : 16 : obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, params->curve_name,
270 : 8 : strlen(params->curve_name));
271 [ + - ]: 8 : if (obj == NULL)
272 : 0 : goto out;
273 : 8 : ok = libder_obj_append(root, obj);
274 [ + - ]: 8 : assert(ok);
275 : :
276 : : /* Public */
277 : 8 : obj = libder_obj_alloc_simple(ctx, BT_BOOLEAN, &public, sizeof(public));
278 [ + - ]: 8 : if (obj == NULL)
279 : 0 : goto out;
280 : 8 : ok = libder_obj_append(root, obj);
281 [ + - ]: 8 : assert(ok);
282 : :
283 : 8 : memset(keybuf, 0, sizeof(keybuf));
284 : 8 : keybuf[0] = 0; /* No unused bits */
285 : 8 : keybuf[1] = PUBKEY_UNCOMPRESSED;
286 : 8 : memcpy(&keybuf[2], keydata, keysz);
287 : :
288 : 16 : keybits = libder_obj_alloc_simple(ctx, BT_BITSTRING, &keybuf[0],
289 : 8 : keysz + 2);
290 [ + - ]: 8 : if (keybits == NULL)
291 : 0 : goto out;
292 : 8 : ok = libder_obj_append(root, keybits);
293 [ + - ]: 8 : assert(ok);
294 : :
295 : : /* Finally, write it out. */
296 : 8 : *buflen = 0;
297 : 8 : outbuf = libder_write(ctx, root, NULL, buflen);
298 [ - + ]: 16 : if (outbuf != NULL) {
299 : 8 : *buf = outbuf;
300 : 8 : rc = EPKG_OK;
301 : 8 : }
302 : :
303 : : out:
304 : 8 : libder_obj_free(root);
305 : 8 : libder_close(ctx);
306 : 8 : return (rc);
307 : 8 : }
308 : :
309 : : static int
310 : 2 : ecc_read_pkgkey(struct libder_object *root, ec_params *params, int public,
311 : : uint8_t *rawkey, size_t *rawlen)
312 : : {
313 : : struct libder_object *obj;
314 : : const uint8_t *data;
315 : : const ec_str_params *sparams;
316 : : size_t datasz;
317 : : int ret;
318 : :
319 [ - + ]: 2 : if (libder_obj_type_simple(root) != BT_SEQUENCE)
320 : 0 : return (EPKG_FATAL);
321 : :
322 : : /* Application */
323 : 2 : obj = libder_obj_child(root, 0);
324 [ + - - + ]: 2 : if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
325 : 0 : return (EPKG_FATAL);
326 : 2 : data = libder_obj_data(obj, &datasz);
327 [ + - - + ]: 2 : if (datasz != sizeof(pkgkey_app) - 1 ||
328 : 2 : memcmp(data, pkgkey_app, datasz) != 0)
329 : 0 : return (EPKG_FATAL);
330 : :
331 : : /* Version */
332 : 2 : obj = libder_obj_child(root, 1);
333 [ + - - + ]: 2 : if (obj == NULL || libder_obj_type_simple(obj) != BT_INTEGER)
334 : 0 : return (EPKG_FATAL);
335 : 2 : data = libder_obj_data(obj, &datasz);
336 [ + - - + ]: 2 : if (datasz != 1 || *data != 1 /* XXX */)
337 : 0 : return (EPKG_FATAL);
338 : :
339 : : /* Signer */
340 : 2 : obj = libder_obj_child(root, 2);
341 [ + - - + ]: 2 : if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
342 : 0 : return (EPKG_FATAL);
343 : 2 : data = libder_obj_data(obj, &datasz);
344 [ + - - + ]: 2 : if (datasz != sizeof(pkgkey_signer) - 1 ||
345 : 2 : memcmp(data, pkgkey_signer, datasz) != 0)
346 : 0 : return (EPKG_FATAL);
347 : :
348 : : /* KeyType (curve) */
349 : 2 : obj = libder_obj_child(root, 3);
350 [ + - - + ]: 2 : if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
351 : 0 : return (EPKG_FATAL);
352 : 2 : data = libder_obj_data(obj, &datasz);
353 : 2 : sparams = ecc_pkgkey_params(data, datasz);
354 [ + - ]: 2 : if (sparams == NULL)
355 : 0 : return (EPKG_FATAL);
356 : :
357 : 2 : ret = import_params(params, sparams);
358 [ - + ]: 2 : if (ret != 0)
359 : 0 : return (EPKG_FATAL);
360 : :
361 : : /* Public? */
362 : 2 : obj = libder_obj_child(root, 4);
363 [ + - - + ]: 2 : if (obj == NULL || libder_obj_type_simple(obj) != BT_BOOLEAN)
364 : 0 : return (EPKG_FATAL);
365 : 2 : data = libder_obj_data(obj, &datasz);
366 [ + - - + ]: 2 : if (datasz != 1 || !data[0] != !public)
367 : 0 : return (EPKG_FATAL);
368 : :
369 : : /* Key */
370 : 2 : obj = libder_obj_child(root, 5);
371 [ + - - + ]: 2 : if (obj == NULL || libder_obj_type_simple(obj) != BT_BITSTRING)
372 : 0 : return (EPKG_FATAL);
373 : 2 : data = libder_obj_data(obj, &datasz);
374 [ + - - + : 2 : if (datasz <= 2 || data[0] != 0 || data[1] != PUBKEY_UNCOMPRESSED)
- + ]
375 : 0 : return (EPKG_FATAL);
376 : :
377 : 2 : data += 2;
378 : 2 : datasz -= 2;
379 : :
380 [ - + ]: 2 : if (datasz > *rawlen)
381 : 0 : return (EPKG_FATAL);
382 : :
383 : :
384 : 2 : memcpy(rawkey, data, datasz);
385 : 2 : *rawlen = datasz;
386 : :
387 : 2 : return (EPKG_OK);
388 : 2 : }
389 : :
390 : : static int
391 : 10 : ecc_write_signature_component(struct libder_ctx *ctx, struct libder_object *root,
392 : : const uint8_t *sigpart, size_t partlen)
393 : : {
394 : : uint8_t sigbounce[EC_MAX_SIGLEN];
395 : : struct libder_object *obj;
396 : : size_t curlen;
397 : : bool ok;
398 : :
399 : : /*
400 : : * If we need a leading 0 because the sign bit is set, we may need to
401 : : * bounce through sigbounce. We may also need to bounce if there's some
402 : : * leading zeros.
403 : : */
404 : 10 : curlen = partlen;
405 [ + - + - : 10 : while (curlen > 0 && sigpart[0] == 0) {
- + ]
406 : 0 : curlen--;
407 : 0 : sigpart++;
408 : : }
409 : :
410 [ + + ]: 10 : if ((sigpart[0] & 0x80) != 0) {
411 : : /*
412 : : * If the high bit is set, we need to bounce it through
413 : : * sigbounce and insert a leading 0.
414 : : */
415 : 4 : sigbounce[0] = 0;
416 : 4 : memcpy(&sigbounce[1], sigpart, curlen);
417 : :
418 : 8 : obj = libder_obj_alloc_simple(ctx, BT_INTEGER, sigbounce,
419 : 4 : curlen + 1);
420 : 4 : } else {
421 : : /*
422 : : * Otherwise, we can just leave it be.
423 : : */
424 : :
425 : 6 : obj = libder_obj_alloc_simple(ctx, BT_INTEGER, sigpart, curlen);
426 : : }
427 : :
428 [ + - ]: 10 : if (obj == NULL)
429 : 0 : return (EPKG_FATAL);
430 : :
431 : 10 : ok = libder_obj_append(root, obj);
432 [ + - ]: 10 : assert(ok);
433 : 10 : return (EPKG_OK);
434 : 10 : }
435 : :
436 : : /*
437 : : * Ecdsa-Sig-Value ::= SEQUENCE {
438 : : * r INTEGER,
439 : : * s INTEGER }
440 : : */
441 : : static int
442 : 5 : ecc_write_signature(const uint8_t *sig, size_t siglen, uint8_t **sigret,
443 : : size_t *sigretlen)
444 : : {
445 : : struct libder_ctx *ctx;
446 : : struct libder_object *obj, *root;
447 : : uint8_t *outbuf;
448 : : size_t complen;
449 : : int rc;
450 : :
451 : 5 : ctx = libder_open();
452 [ + - ]: 5 : if (ctx == NULL)
453 : 0 : return (EPKG_FATAL);
454 : :
455 : 5 : rc = EPKG_FATAL;
456 : 5 : obj = NULL;
457 : 5 : root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
458 [ + - ]: 5 : if (root == NULL)
459 : 0 : goto out;
460 : :
461 : 5 : complen = siglen / 2;
462 : 5 : rc = ecc_write_signature_component(ctx, root, sig, complen);
463 [ - + ]: 5 : if (rc != EPKG_OK)
464 : 0 : goto out;
465 : :
466 : 5 : sig += complen;
467 : 5 : siglen -= complen;
468 : 5 : rc = ecc_write_signature_component(ctx, root, sig, complen);
469 [ - + ]: 5 : if (rc != EPKG_OK)
470 : 0 : goto out;
471 : :
472 : 5 : *sigretlen = 0;
473 : 5 : outbuf = libder_write(ctx, root, NULL, sigretlen);
474 [ - + ]: 10 : if (outbuf != NULL) {
475 : 5 : *sigret = outbuf;
476 : 5 : rc = EPKG_OK;
477 : 5 : }
478 : : out:
479 : 5 : libder_obj_free(obj);
480 : 5 : libder_close(ctx);
481 : 5 : return (rc);
482 : 5 : }
483 : :
484 : : static int
485 : 0 : ecc_extract_signature(const uint8_t *sig, size_t siglen, uint8_t *rawsig,
486 : : size_t rawlen)
487 : : {
488 : : struct libder_ctx *ctx;
489 : : struct libder_object *obj, *root;
490 : : const uint8_t *sigdata;
491 : : size_t compsz, datasz, sigoff;
492 : : int rc;
493 : :
494 : 0 : ctx = libder_open();
495 [ # # ]: 0 : if (ctx == NULL)
496 : 0 : return (EPKG_FATAL);
497 : :
498 : 0 : rc = EPKG_FATAL;
499 : 0 : root = libder_read(ctx, sig, &siglen);
500 [ # # # # ]: 0 : if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
501 : 0 : goto out;
502 : :
503 : : /* Descend into the sequence's payload, extract both numbers. */
504 : 0 : compsz = rawlen / 2;
505 : 0 : sigoff = 0;
506 [ # # ]: 0 : for (int i = 0; i < 2; i++) {
507 : 0 : obj = libder_obj_child(root, i);
508 [ # # ]: 0 : if (libder_obj_type_simple(obj) != BT_INTEGER)
509 : 0 : goto out;
510 : :
511 : 0 : sigdata = libder_obj_data(obj, &datasz);
512 [ # # # # ]: 0 : if (datasz < 2 || datasz > compsz + 1)
513 : 0 : goto out;
514 : :
515 : : /*
516 : : * We may see an extra lead byte if our high bit of the first
517 : : * byte was set, since these numbers are positive by definition.
518 : : */
519 [ # # # # ]: 0 : if (sigdata[0] == 0 && (sigdata[1] & 0x80) != 0) {
520 : 0 : sigdata++;
521 : 0 : datasz--;
522 : 0 : }
523 : :
524 : : /* Sanity check: don't overflow the output. */
525 [ # # ]: 0 : if (sigoff + datasz > rawlen)
526 : 0 : goto out;
527 : :
528 : : /* Padding to the significant end if we're too small. */
529 [ # # ]: 0 : if (datasz < compsz) {
530 : 0 : memset(&rawsig[sigoff], 0, compsz - datasz);
531 : 0 : sigoff += compsz - datasz;
532 : 0 : }
533 : :
534 : 0 : memcpy(&rawsig[sigoff], sigdata, datasz);
535 : 0 : sigoff += datasz;
536 : 0 : }
537 : :
538 : : /* Sanity check: must have exactly the required # of signature bits. */
539 : 0 : rc = (sigoff == rawlen) ? EPKG_OK : EPKG_FATAL;
540 : :
541 : : out:
542 : 0 : libder_obj_free(root);
543 : 0 : libder_close(ctx);
544 : 0 : return (rc);
545 : 0 : }
546 : :
547 : : static int
548 : 0 : ecc_extract_pubkey_string(const uint8_t *data, size_t datalen, uint8_t *rawkey,
549 : : size_t *rawlen)
550 : : {
551 : : uint8_t prefix, usebit;
552 : :
553 [ # # ]: 0 : if (datalen <= 2)
554 : 0 : return (EPKG_FATAL);
555 : :
556 : 0 : usebit = *data++;
557 : 0 : datalen--;
558 : :
559 [ # # ]: 0 : if (usebit != 0)
560 : 0 : return (EPKG_FATAL);
561 : :
562 : 0 : prefix = *data++;
563 : 0 : datalen--;
564 : :
565 [ # # ]: 0 : if (prefix != PUBKEY_UNCOMPRESSED)
566 : 0 : return (EPKG_FATAL);
567 : :
568 [ # # ]: 0 : if (datalen > *rawlen)
569 : 0 : return (EPKG_FATAL);
570 : :
571 : 0 : memcpy(rawkey, data, datalen);
572 : 0 : *rawlen = datalen;
573 : :
574 : 0 : return (EPKG_OK);
575 : 0 : }
576 : :
577 : : static int
578 : 1 : ecc_extract_key_params(const uint8_t *oid, size_t oidlen,
579 : : ec_params *rawparams)
580 : : {
581 : : int ret;
582 : :
583 [ + - - + ]: 1 : if (oidlen >= sizeof(oid_secp) &&
584 : 1 : memcmp(oid, oid_secp, sizeof(oid_secp)) >= 0) {
585 : 1 : oid += sizeof(oid_secp);
586 : 1 : oidlen -= sizeof(oid_secp);
587 : :
588 [ - + ]: 1 : if (oidlen != 1)
589 : 0 : return (EPKG_FATAL);
590 : :
591 : 1 : ret = -1;
592 [ - - + - ]: 1 : switch (*oid) {
593 : : case 0x0a: /* secp256k1 */
594 : 1 : ret = import_params(rawparams, &secp256k1_str_params);
595 : 1 : break;
596 : : case 0x22: /* secp384r1 */
597 : 0 : ret = import_params(rawparams, &secp384r1_str_params);
598 : 0 : break;
599 : : case 0x23: /* secp521r1 */
600 : 0 : ret = import_params(rawparams, &secp521r1_str_params);
601 : 0 : break;
602 : : default:
603 : 0 : return (EPKG_FATAL);
604 : : }
605 : :
606 [ - + ]: 1 : if (ret == 0)
607 : 1 : return (EPKG_OK);
608 : 0 : return (EPKG_FATAL);
609 : : }
610 : :
611 [ # # # # ]: 0 : if (oidlen >= sizeof(oid_brainpoolP) &&
612 : 0 : memcmp(oid, oid_brainpoolP, sizeof(oid_brainpoolP)) >= 0) {
613 : 0 : oid += sizeof(oid_brainpoolP);
614 : 0 : oidlen -= sizeof(oid_brainpoolP);
615 : :
616 [ # # ]: 0 : if (oidlen != 1)
617 : 0 : return (EPKG_FATAL);
618 : :
619 : 0 : ret = -1;
620 [ # # # # : 0 : switch (*oid) {
# # # #
# ]
621 : : case 0x07: /* brainpoolP256r1 */
622 : 0 : ret = import_params(rawparams, &brainpoolp256r1_str_params);
623 : 0 : break;
624 : : case 0x08: /* brainpoolP256t1 */
625 : 0 : ret = import_params(rawparams, &brainpoolp256t1_str_params);
626 : 0 : break;
627 : : case 0x09: /* brainpoolP320r1 */
628 : 0 : ret = import_params(rawparams, &brainpoolp320r1_str_params);
629 : 0 : break;
630 : : case 0x0a: /* brainpoolP320t1 */
631 : 0 : ret = import_params(rawparams, &brainpoolp320t1_str_params);
632 : 0 : break;
633 : : case 0x0b: /* brainpoolP384r1 */
634 : 0 : ret = import_params(rawparams, &brainpoolp384r1_str_params);
635 : 0 : break;
636 : : case 0x0c: /* brainpoolP384t1 */
637 : 0 : ret = import_params(rawparams, &brainpoolp384t1_str_params);
638 : 0 : break;
639 : : case 0x0d: /* brainpoolP512r1 */
640 : 0 : ret = import_params(rawparams, &brainpoolp512r1_str_params);
641 : 0 : break;
642 : : case 0x0e: /* brainpoolP512t1 */
643 : 0 : ret = import_params(rawparams, &brainpoolp512t1_str_params);
644 : 0 : break;
645 : : default:
646 : 0 : return (EPKG_FATAL);
647 : : }
648 : :
649 [ # # ]: 0 : if (ret == 0)
650 : 0 : return (EPKG_OK);
651 : 0 : return (EPKG_FATAL);
652 : : }
653 : :
654 : : #ifdef ECC_DEBUG
655 : : for (size_t i = 0; i < oidlen; i++) {
656 : : fprintf(stderr, "%.02x ", oid[i]);
657 : : }
658 : :
659 : : fprintf(stderr, "\n");
660 : : #endif
661 : :
662 : 0 : return (EPKG_FATAL);
663 : 1 : }
664 : :
665 : : /*
666 : : * On entry, *rawparams should point to an ec_params that we can import the
667 : : * key parameters to. We'll either do that, or we'll set it to NULL if we could
668 : : * not deduce the curve.
669 : : */
670 : : static int
671 : 0 : ecc_extract_pubkey(const uint8_t *key, size_t keylen, uint8_t *rawkey,
672 : : size_t *rawlen, ec_params *rawparams)
673 : : {
674 : : const uint8_t *oidp;
675 : : struct libder_ctx *ctx;
676 : : struct libder_object *keydata, *oid, *params, *root;
677 : : size_t oidsz;
678 : : int rc;
679 : :
680 : 0 : ctx = libder_open();
681 [ # # ]: 0 : if (ctx == NULL)
682 : 0 : return (EPKG_FATAL);
683 : :
684 : 0 : rc = EPKG_FATAL;
685 : 0 : root = libder_read(ctx, key, &keylen);
686 [ # # # # ]: 0 : if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
687 : 0 : goto out;
688 : :
689 : 0 : params = libder_obj_child(root, 0);
690 : :
691 [ # # ]: 0 : if (params == NULL) {
692 : 0 : goto out;
693 [ # # ]: 0 : } else if (libder_obj_type_simple(params) != BT_SEQUENCE) {
694 : 0 : rc = ecc_read_pkgkey(root, rawparams, 1, rawkey, rawlen);
695 : 0 : goto out;
696 : : }
697 : :
698 : : /* Is a sequence */
699 : 0 : keydata = libder_obj_child(root, 1);
700 [ # # # # ]: 0 : if (keydata == NULL || libder_obj_type_simple(keydata) != BT_BITSTRING)
701 : 0 : goto out;
702 : :
703 : : /* Key type */
704 : 0 : oid = libder_obj_child(params, 0);
705 [ # # # # ]: 0 : if (oid == NULL || libder_obj_type_simple(oid) != BT_OID)
706 : 0 : goto out;
707 : :
708 : 0 : oidp = libder_obj_data(oid, &oidsz);
709 [ # # # # ]: 0 : if (oidsz != sizeof(oid_ecpubkey) ||
710 : 0 : memcmp(oidp, oid_ecpubkey, oidsz) != 0)
711 : 0 : return (EPKG_FATAL);
712 : :
713 : : /* Curve */
714 : 0 : oid = libder_obj_child(params, 1);
715 [ # # # # ]: 0 : if (oid == NULL || libder_obj_type_simple(oid) != BT_OID)
716 : 0 : goto out;
717 : :
718 : 0 : oidp = libder_obj_data(oid, &oidsz);
719 [ # # ]: 0 : if (ecc_extract_key_params(oidp, oidsz, rawparams) != EPKG_OK)
720 : 0 : goto out;
721 : :
722 : : /* Finally, peel off the key material */
723 : 0 : key = libder_obj_data(keydata, &keylen);
724 [ # # ]: 0 : if (ecc_extract_pubkey_string(key, keylen, rawkey, rawlen) != EPKG_OK)
725 : 0 : goto out;
726 : :
727 : 0 : rc = EPKG_OK;
728 : : out:
729 : 0 : libder_obj_free(root);
730 : 0 : libder_close(ctx);
731 : 0 : return (rc);
732 : 0 : }
733 : :
734 : : static int
735 : 3 : ecc_extract_privkey(const uint8_t *key, size_t keylen, uint8_t *rawkey,
736 : : size_t *rawlen, ec_params *rawparams)
737 : : {
738 : : const uint8_t *data;
739 : : struct libder_ctx *ctx;
740 : : struct libder_object *obj, *root;
741 : : size_t datasz;
742 : : int rc;
743 : :
744 : 3 : ctx = libder_open();
745 [ + - ]: 3 : if (ctx == NULL)
746 : 0 : return (EPKG_FATAL);
747 : :
748 : 3 : rc = EPKG_FATAL;
749 : 3 : root = libder_read(ctx, key, &keylen);
750 [ + - - + ]: 3 : if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
751 : 0 : goto out;
752 : :
753 : : /* Sanity check the version, we're expecting version 1. */
754 : 3 : obj = libder_obj_child(root, 0);
755 [ + - ]: 3 : if (obj == NULL)
756 : 0 : goto out;
757 [ + + ]: 3 : if (libder_obj_type_simple(obj) != BT_INTEGER) {
758 : 2 : rc = ecc_read_pkgkey(root, rawparams, 0, rawkey, rawlen);
759 : 2 : goto out;
760 : : }
761 : :
762 : 1 : data = libder_obj_data(obj, &datasz);
763 [ + - - + ]: 1 : if (datasz != 1 || *data != 1)
764 : 0 : goto out;
765 : :
766 : : /* Grab the key data itself. */
767 : 1 : obj = libder_obj_child(root, 1);
768 [ + - - + ]: 1 : if (obj == NULL || libder_obj_type_simple(obj) != BT_OCTETSTRING)
769 : 0 : goto out;
770 : :
771 : 1 : data = libder_obj_data(obj, &datasz);
772 [ + - - + ]: 1 : if (datasz == 0 || datasz > *rawlen)
773 : 0 : goto out;
774 : :
775 : 1 : memcpy(rawkey, data, datasz);
776 : 1 : *rawlen = datasz;
777 : :
778 : : /* Next, extract the OID describing the key type. */
779 : 1 : obj = libder_obj_child(root, 2);
780 [ + - - + ]: 1 : if (obj == NULL || libder_obj_type_simple(obj) !=
781 : : ((BC_CONTEXT << 6) | BER_TYPE_CONSTRUCTED_MASK))
782 : 0 : goto out;
783 : :
784 : 1 : obj = libder_obj_child(obj, 0);
785 [ + - - + ]: 1 : if (obj == NULL || libder_obj_type_simple(obj) != BT_OID)
786 : 0 : goto out;
787 : :
788 : 1 : data = libder_obj_data(obj, &datasz);
789 [ - + ]: 1 : if (ecc_extract_key_params(data, datasz, rawparams) != EPKG_OK)
790 : 0 : goto out;
791 : :
792 : 1 : rc = EPKG_OK;
793 : : out:
794 : 3 : libder_obj_free(root);
795 : 3 : libder_close(ctx);
796 : 3 : return (rc);
797 : 3 : }
798 : :
799 : : static int
800 : 5 : _generate_private_key(struct ecc_sign_ctx *keyinfo)
801 : : {
802 : : int ret;
803 : :
804 : 10 : ret = ec_key_pair_gen(&keyinfo->keypair, &keyinfo->params,
805 : 5 : keyinfo->sig_alg);
806 : :
807 [ - + ]: 5 : if (ret != 0) {
808 : 0 : pkg_emit_error("failed to generate ecc keypair");
809 : 0 : return (EPKG_FATAL);
810 : : }
811 : :
812 : 5 : keyinfo->loaded = true;
813 : 5 : return (EPKG_OK);
814 : 5 : }
815 : :
816 : : static inline void
817 : 11 : _specific_explicit_bzero(void *buf, size_t bufsz)
818 : : {
819 : :
820 : : #ifdef __APPLE__
821 : : memset_s(buf, bufsz, 0, bufsz);
822 : : #else
823 : 11 : explicit_bzero(buf, bufsz);
824 : : #endif
825 : 11 : }
826 : :
827 : :
828 : : static int
829 : 3 : _load_private_key(struct ecc_sign_ctx *keyinfo)
830 : : {
831 : : struct stat st;
832 : : uint8_t keybuf[EC_PRIV_KEY_MAX_SIZE];
833 : : uint8_t *filedata;
834 : : ssize_t readsz;
835 : : size_t keysz;
836 : : int fd, rc, ret;
837 : : size_t offset, resid;
838 : :
839 : 3 : filedata = NULL;
840 : 3 : fd = -1;
841 : 3 : rc = EPKG_FATAL;
842 : :
843 : 3 : keyinfo->loaded = false;
844 [ + - ]: 3 : if ((fd = open(keyinfo->sctx.path, O_RDONLY)) == -1)
845 : 0 : return (EPKG_FATAL);
846 : :
847 [ + - ]: 3 : if (fstat(fd, &st) == -1)
848 : 0 : goto out;
849 : :
850 : 3 : filedata = xmalloc(st.st_size);
851 : 3 : resid = st.st_size;
852 : 3 : offset = 0;
853 [ + + ]: 6 : while (resid != 0) {
854 : 3 : readsz = read(fd, &filedata[offset], resid);
855 [ - + ]: 3 : if (readsz <= 0)
856 : 0 : break;
857 : 3 : resid -= readsz;
858 : 3 : offset += readsz;
859 : : }
860 : :
861 [ + - ]: 3 : if (readsz < 0) {
862 : 0 : pkg_emit_errno("read", keyinfo->sctx.path);
863 : 0 : goto out;
864 [ - + ]: 3 : } else if (resid != 0) {
865 : 0 : pkg_emit_error("%s: failed to read key",
866 : 0 : keyinfo->sctx.path);
867 : 0 : goto out;
868 : : }
869 : :
870 : : /*
871 : : * Try DER-decoding it. Unlike with loading a pubkey, anything
872 : : * requiring the privkey requires a new context for each operation, so
873 : : * we can just clobber keyinfo->params at will.
874 : : */
875 : 3 : keysz = sizeof(keybuf);
876 [ - + - + : 9 : if (ecc_extract_privkey(filedata, offset, keybuf, &keysz,
- + ]
877 : 6 : &keyinfo->params) != EPKG_OK) {
878 : 0 : pkg_emit_error("failed to decode private key");
879 : 0 : goto out;
880 : : }
881 : :
882 : 6 : ret = ec_priv_key_import_from_buf(&keyinfo->keypair.priv_key,
883 : 3 : &keyinfo->params, keybuf, keysz, keyinfo->sig_alg);
884 [ - + ]: 6 : if (ret == 0) {
885 : 6 : ret = init_pubkey_from_privkey(&keyinfo->keypair.pub_key,
886 : 3 : &keyinfo->keypair.priv_key);
887 [ - + ]: 3 : if (ret == 0) {
888 : 3 : keyinfo->loaded = true;
889 : 3 : rc = EPKG_OK;
890 : 3 : } else {
891 : 0 : pkg_emit_error("%s: failed to derive public key",
892 : 0 : keyinfo->sctx.path);
893 : 0 : rc = EPKG_FATAL;
894 : : }
895 : 3 : } else {
896 : 0 : pkg_emit_error("%s: failed to import private key",
897 : 0 : keyinfo->sctx.path);
898 : 0 : rc = EPKG_FATAL;
899 : : }
900 : :
901 : : out:
902 : 3 : _specific_explicit_bzero(keybuf, sizeof(keybuf));
903 : 3 : free(filedata);
904 [ + - ]: 3 : if (fd != -1)
905 : 3 : close(fd);
906 : 3 : return (rc);
907 : 3 : }
908 : :
909 : : struct ecc_verify_cbdata {
910 : : const struct pkgsign_ctx *sctx;
911 : : unsigned char *key;
912 : : size_t keylen;
913 : : unsigned char *sig;
914 : : size_t siglen;
915 : : };
916 : :
917 : : static int
918 : 0 : ecc_verify_internal(struct ecc_verify_cbdata *cbdata, const uint8_t *hash,
919 : : size_t hashsz)
920 : : {
921 : : ec_pub_key pubkey;
922 : : ec_params derparams;
923 : 0 : struct ecc_sign_ctx *keyinfo = ECC_CTX(cbdata->sctx);
924 : : uint8_t keybuf[EC_PUB_KEY_MAX_SIZE];
925 : : uint8_t rawsig[EC_MAX_SIGLEN];
926 : : size_t keysz;
927 : : int ret;
928 : : uint8_t ecsiglen;
929 : :
930 [ # # ]: 0 : keysz = MIN(sizeof(keybuf), cbdata->keylen / 2);
931 : :
932 : 0 : keysz = sizeof(keybuf);
933 [ # # # # ]: 0 : if (ecc_extract_pubkey(cbdata->key, cbdata->keylen, keybuf,
934 : 0 : &keysz, &derparams) != EPKG_OK) {
935 : 0 : pkg_emit_error("failed to parse key");
936 : 0 : return (EPKG_FATAL);
937 : : }
938 : :
939 : 0 : ret = ec_get_sig_len(&derparams, keyinfo->sig_alg, keyinfo->sig_hash,
940 : : &ecsiglen);
941 [ # # ]: 0 : if (ret != 0)
942 : 0 : return (EPKG_FATAL);
943 : :
944 : : /*
945 : : * Signatures are DER-encoded, whether by OpenSSL or pkg.
946 : : */
947 [ # # # # : 0 : if (ecc_extract_signature(cbdata->sig, cbdata->siglen,
# # ]
948 : 0 : rawsig, ecsiglen) != EPKG_OK) {
949 : 0 : pkg_emit_error("failed to decode signature");
950 : 0 : return (EPKG_FATAL);
951 : : }
952 : :
953 : 0 : ret = ec_pub_key_import_from_aff_buf(&pubkey, &derparams,
954 : 0 : keybuf, keysz, keyinfo->sig_alg);
955 [ # # ]: 0 : if (ret != 0) {
956 : 0 : pkg_emit_error("failed to import key");
957 : 0 : return (EPKG_FATAL);
958 : : }
959 : :
960 : 0 : ret = ec_verify(rawsig, ecsiglen, &pubkey, hash, hashsz, keyinfo->sig_alg,
961 : 0 : keyinfo->sig_hash, NULL, 0);
962 [ # # ]: 0 : if (ret != 0) {
963 : 0 : pkg_emit_error("failed to verify signature");
964 : 0 : return (EPKG_FATAL);
965 : : }
966 : :
967 : 0 : return (EPKG_OK);
968 : 0 : }
969 : :
970 : :
971 : : static int
972 : 0 : ecc_verify_cert_cb(int fd, void *ud)
973 : : {
974 : 0 : struct ecc_verify_cbdata *cbdata = ud;
975 : : char *sha256;
976 : : int ret;
977 : :
978 : 0 : sha256 = pkg_checksum_fd(fd, PKG_HASH_TYPE_SHA256_HEX);
979 [ # # ]: 0 : if (sha256 == NULL)
980 : 0 : return (EPKG_FATAL);
981 : :
982 : 0 : ret = ecc_verify_internal(cbdata, sha256, strlen(sha256));
983 [ # # ]: 0 : if (ret != 0) {
984 : 0 : pkg_emit_error("ecc signature verification failure");
985 : 0 : return (EPKG_FATAL);
986 : : }
987 : :
988 : 0 : return (EPKG_OK);
989 : 0 : }
990 : :
991 : : static int
992 : 1 : ecc_verify_cert(const struct pkgsign_ctx *sctx, unsigned char *key,
993 : : size_t keylen, unsigned char *sig, size_t siglen, int fd)
994 : : {
995 : : int ret;
996 : : struct ecc_verify_cbdata cbdata;
997 : :
998 : 1 : (void)lseek(fd, 0, SEEK_SET);
999 : :
1000 : 1 : cbdata.sctx = sctx;
1001 : 1 : cbdata.key = key;
1002 : 1 : cbdata.keylen = keylen;
1003 : 1 : cbdata.sig = sig;
1004 : 1 : cbdata.siglen = siglen;
1005 : :
1006 : 1 : ret = pkg_emit_sandbox_call(ecc_verify_cert_cb, fd, &cbdata);
1007 : :
1008 : 1 : return (ret);
1009 : : }
1010 : :
1011 : : static int
1012 : 0 : ecc_verify_cb(int fd, void *ud)
1013 : : {
1014 : 0 : struct ecc_verify_cbdata *cbdata = ud;
1015 : : uint8_t *blake2;
1016 : : int ret;
1017 : :
1018 : 0 : blake2 = pkg_checksum_fd(fd, PKG_HASH_TYPE_BLAKE2_RAW);
1019 [ # # ]: 0 : if (blake2 == NULL)
1020 : 0 : return (EPKG_FATAL);
1021 : :
1022 : 0 : ret = ecc_verify_internal(cbdata, blake2,
1023 : 0 : pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_RAW));
1024 : :
1025 : 0 : free(blake2);
1026 [ # # ]: 0 : if (ret != 0) {
1027 : 0 : pkg_emit_error("ecc signature verification failure");
1028 : 0 : return (EPKG_FATAL);
1029 : : }
1030 : :
1031 : 0 : return (EPKG_OK);
1032 : 0 : }
1033 : :
1034 : : static int
1035 : 2 : ecc_verify(const struct pkgsign_ctx *sctx, const char *keypath,
1036 : : unsigned char *sig, size_t sig_len, int fd)
1037 : : {
1038 : : int ret;
1039 : : struct ecc_verify_cbdata cbdata;
1040 : : char *key_buf;
1041 : : off_t key_len;
1042 : :
1043 [ - + ]: 2 : if (file_to_buffer(keypath, (char**)&key_buf, &key_len) != EPKG_OK) {
1044 : 0 : pkg_emit_errno("ecc_verify", "cannot read key");
1045 : 0 : return (EPKG_FATAL);
1046 : : }
1047 : :
1048 : 2 : (void)lseek(fd, 0, SEEK_SET);
1049 : :
1050 : 2 : cbdata.sctx = sctx;
1051 : 2 : cbdata.key = key_buf;
1052 : 2 : cbdata.keylen = key_len;
1053 : 2 : cbdata.sig = sig;
1054 : 2 : cbdata.siglen = sig_len;
1055 : :
1056 : 2 : ret = pkg_emit_sandbox_call(ecc_verify_cb, fd, &cbdata);
1057 : :
1058 : 2 : free(key_buf);
1059 : :
1060 : 2 : return (ret);
1061 : 2 : }
1062 : :
1063 : : static int
1064 : 5 : ecc_sign_data(struct pkgsign_ctx *sctx, const unsigned char *msg, size_t msgsz,
1065 : : unsigned char **sigret, size_t *siglen)
1066 : : {
1067 : : uint8_t rawsig[EC_MAX_SIGLEN];
1068 : 5 : struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1069 : : int ret;
1070 : : uint8_t rawlen;
1071 : :
1072 [ + + + - ]: 5 : if (!keyinfo->loaded && _load_private_key(keyinfo) != EPKG_OK) {
1073 : 0 : pkg_emit_error("%s: failed to load key", keyinfo->sctx.path);
1074 : 0 : return (EPKG_FATAL);
1075 : : }
1076 : :
1077 : 5 : ret = ec_get_sig_len(&keyinfo->params, keyinfo->sig_alg, keyinfo->sig_hash,
1078 : : &rawlen);
1079 [ - + ]: 5 : if (ret != 0)
1080 : 0 : return (EPKG_FATAL);
1081 : :
1082 [ + - ]: 5 : assert(rawlen <= sizeof(rawsig));
1083 : :
1084 [ + - ]: 5 : assert(priv_key_check_initialized_and_type(&keyinfo->keypair.priv_key,
1085 : : keyinfo->sig_alg) == 0);
1086 [ + - ]: 5 : assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
1087 : : keyinfo->sig_alg) == 0);
1088 : :
1089 : 10 : ret = ec_sign(rawsig, rawlen, &keyinfo->keypair, msg, msgsz,
1090 : 5 : keyinfo->sig_alg, keyinfo->sig_hash, NULL, 0);
1091 : :
1092 [ - + ]: 5 : if (ret != 0) {
1093 : 0 : pkg_emit_error("%s: ecc signing failure", keyinfo->sctx.path);
1094 : 0 : return (EPKG_FATAL);
1095 : : }
1096 : :
1097 [ - + ]: 5 : if (ecc_write_signature(rawsig, rawlen, sigret, siglen) != EPKG_OK) {
1098 : 0 : pkg_emit_error("failed to encode signature");
1099 : 0 : return (EPKG_FATAL);
1100 : : }
1101 : :
1102 : 5 : return (EPKG_OK);
1103 : 5 : }
1104 : :
1105 : : static int
1106 : 4 : ecc_sign(struct pkgsign_ctx *sctx, const char *path, unsigned char **sigret,
1107 : : size_t *siglen)
1108 : : {
1109 : : uint8_t *blake2;
1110 : 4 : struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1111 : : int ret;
1112 : :
1113 [ + - ]: 4 : if (access(keyinfo->sctx.path, R_OK) == -1) {
1114 : 0 : pkg_emit_errno("access", keyinfo->sctx.path);
1115 : 0 : return (EPKG_FATAL);
1116 : : }
1117 : :
1118 : 4 : blake2 = pkg_checksum_file(path, PKG_HASH_TYPE_BLAKE2_RAW);
1119 [ + - ]: 4 : if (blake2 == NULL)
1120 : 0 : return (EPKG_FATAL);
1121 : :
1122 : 8 : ret = ecc_sign_data(sctx, blake2,
1123 : 4 : pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_RAW), sigret, siglen);
1124 : 4 : free(blake2);
1125 : :
1126 : 4 : return (ret);
1127 : 4 : }
1128 : :
1129 : : static int
1130 : 5 : ecc_generate(struct pkgsign_ctx *sctx, const struct iovec *iov __unused,
1131 : : int niov __unused)
1132 : : {
1133 : : uint8_t keybuf[EC_PRIV_KEY_MAX_SIZE], *outbuf;
1134 : 5 : struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1135 : 5 : const char *path = sctx->path;
1136 : : FILE *fp;
1137 : : size_t keysz, outsz;
1138 : :
1139 [ - + ]: 5 : if (niov != 0)
1140 : 0 : return (EPKG_FATAL);
1141 : :
1142 [ - + ]: 5 : if (_generate_private_key(keyinfo) != 0)
1143 : 0 : return (EPKG_FATAL);
1144 : :
1145 [ + - ]: 5 : assert(priv_key_check_initialized_and_type(&keyinfo->keypair.priv_key,
1146 : : keyinfo->sig_alg) == 0);
1147 [ + - ]: 5 : assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
1148 : : keyinfo->sig_alg) == 0);
1149 : :
1150 [ - + + - : 5 : keysz = EC_PRIV_KEY_EXPORT_SIZE(&keyinfo->keypair.priv_key);
# # ]
1151 [ - + - + : 15 : if (ec_priv_key_export_to_buf(&keyinfo->keypair.priv_key,
- + ]
1152 : 10 : keybuf, keysz) != 0) {
1153 : 0 : pkg_emit_error("failed to export ecc key");
1154 : 0 : return (EPKG_FATAL);
1155 : : }
1156 : :
1157 : 5 : outbuf = NULL;
1158 : 5 : outsz = 0;
1159 [ - + - + ]: 10 : if (ecc_write_pkgkey(&keyinfo->params, 0, keybuf, keysz, &outbuf,
1160 : 5 : &outsz) != EPKG_OK) {
1161 : 0 : pkg_emit_error("%s: failed to write DER-encoded key",
1162 : 0 : sctx->path);
1163 : 0 : return (EPKG_FATAL);
1164 : : }
1165 : :
1166 : 5 : fp = fopen(path, "wb");
1167 [ + - ]: 5 : if (fp == NULL) {
1168 : 0 : pkg_emit_errno("fopen write", path);
1169 : 0 : free(outbuf);
1170 : 0 : return (EPKG_FATAL);
1171 : : }
1172 : :
1173 [ - + ]: 5 : if (fchmod(fileno(fp), 0400) != 0) {
1174 : 0 : pkg_emit_errno("fchmod", path);
1175 : 0 : free(outbuf);
1176 : 0 : fclose(fp);
1177 : 0 : return (EPKG_FATAL);
1178 : : }
1179 : :
1180 : 5 : fwrite(outbuf, outsz, 1, fp);
1181 : 5 : free(outbuf);
1182 : 5 : outbuf = NULL;
1183 [ - + + - : 5 : if (ferror(fp) != 0 || fflush(fp) != 0) {
- + ]
1184 : 0 : pkg_emit_errno("fwrite", path);
1185 : 0 : fclose(fp);
1186 : 0 : return (EPKG_FATAL);
1187 : : }
1188 : :
1189 : 5 : fclose(fp);
1190 : 5 : return (EPKG_OK);
1191 : 5 : }
1192 : :
1193 : : static int
1194 : 5 : ecc_pubkey(struct pkgsign_ctx *sctx, char **pubkey, size_t *pubkeylen)
1195 : : {
1196 : 5 : struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1197 : : uint8_t keybuf[EC_PUB_KEY_MAX_SIZE];
1198 : : size_t keylen;
1199 : : int ret;
1200 : :
1201 [ - + # # ]: 5 : if (!keyinfo->loaded && _load_private_key(keyinfo) != EPKG_OK) {
1202 : 0 : pkg_emit_error("%s: failed to load key", sctx->path);
1203 : 0 : return (EPKG_FATAL);
1204 : : }
1205 : :
1206 [ + - ]: 5 : assert(keyinfo->loaded);
1207 [ + - ]: 5 : assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
1208 : : keyinfo->sig_alg) == 0);
1209 : :
1210 : 5 : keylen = 2 * BYTECEIL(keyinfo->params.ec_fp.p_bitlen);
1211 : 5 : ret = ec_pub_key_export_to_aff_buf(&keyinfo->keypair.pub_key, keybuf, keylen);
1212 [ - + ]: 5 : if (ret != 0) {
1213 : 0 : pkg_emit_error("%s: failed to export key", sctx->path);
1214 : 0 : return (EPKG_FATAL);
1215 : : }
1216 : :
1217 : : /*
1218 : : * We'll write a custom format for anything but ECDSA that includes our
1219 : : * params wholesale so that we can just import them directly.
1220 : : *
1221 : : * ECDSA keys get exported as PKCS#8 for interoperability with OpenSSL.
1222 : : */
1223 [ + + ]: 5 : if (keyinfo->sig_alg != ECDSA) {
1224 [ - + - + : 9 : if (ecc_write_pkgkey(&keyinfo->params, 1, keybuf, keylen,
- + ]
1225 : 6 : (uint8_t **)pubkey, pubkeylen) != EPKG_OK) {
1226 : 0 : pkg_emit_error("%s: failed to write DER-encoded key",
1227 : :
1228 : 0 : sctx->path);
1229 : 0 : return (EPKG_FATAL);
1230 : : }
1231 [ - + - + : 9 : } else if (ecc_pubkey_write_pkcs8(keybuf, keylen,
- + ]
1232 : 4 : (uint8_t **)pubkey, pubkeylen) != EPKG_OK) {
1233 : 0 : pkg_emit_error("%s: failed to write DER-encoded key", sctx->path);
1234 : 0 : return (EPKG_FATAL);
1235 : : }
1236 : :
1237 : 5 : return (EPKG_OK);
1238 : 5 : }
1239 : :
1240 : : static int
1241 : 11 : ecc_new(const char *name __unused, struct pkgsign_ctx *sctx)
1242 : : {
1243 : 11 : struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1244 : : int ret;
1245 : :
1246 : 11 : ret = EPKG_FATAL;
1247 [ + + + + ]: 11 : if (STREQ(name, "ecc") || STREQ(name, "eddsa")) {
1248 : 5 : keyinfo->sig_alg = EDDSA25519;
1249 : 5 : keyinfo->sig_hash = SHA512;
1250 : 5 : ret = import_params(&keyinfo->params, &wei25519_str_params);
1251 [ - + ]: 11 : } else if (STREQ(name, "ecdsa")) {
1252 : 6 : keyinfo->sig_alg = ECDSA;
1253 : 6 : keyinfo->sig_hash = SHA256;
1254 : 6 : ret = import_params(&keyinfo->params, &secp256k1_str_params);
1255 : 6 : }
1256 : :
1257 [ - + ]: 11 : if (ret != 0)
1258 : 0 : return (EPKG_FATAL);
1259 : :
1260 : 11 : return (0);
1261 : 11 : }
1262 : :
1263 : : static void
1264 : 8 : ecc_free(struct pkgsign_ctx *sctx)
1265 : : {
1266 : 8 : struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1267 : :
1268 : 8 : _specific_explicit_bzero(&keyinfo->keypair, sizeof(keyinfo->keypair));
1269 : 8 : }
1270 : :
1271 : : const struct pkgsign_ops pkgsign_ecc = {
1272 : : .pkgsign_ctx_size = sizeof(struct ecc_sign_ctx),
1273 : : .pkgsign_new = ecc_new,
1274 : : .pkgsign_free = ecc_free,
1275 : :
1276 : : .pkgsign_sign = ecc_sign,
1277 : : .pkgsign_verify = ecc_verify,
1278 : : .pkgsign_verify_cert = ecc_verify_cert,
1279 : :
1280 : : .pkgsign_generate = ecc_generate,
1281 : : .pkgsign_pubkey = ecc_pubkey,
1282 : : .pkgsign_sign_data = ecc_sign_data,
1283 : : };
|