1 /*-
2 * Copyright (c) 2018, Juniper Networks, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 /*
26 * RCSid:
27 * from: signer.c,v 1.10 2018/03/23 01:14:30 sjg
28 *
29 * This file is provided in the hope that it will
30 * be of use. There is absolutely NO WARRANTY.
31 * Permission to copy, redistribute or otherwise
32 * use this file is hereby granted provided that
33 * the above copyright notice and this notice are
34 * left intact.
35 *
36 * Please send copies of changes and bug-fixes to:
37 * sjg@crufty.net
38 */
39
40 #include <sys/cdefs.h>
41 #include "../libsecureboot-priv.h"
42 #ifdef _STANDALONE
43 #define warnx printf
44 #else
45
46 #include <sys/param.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <stdio.h>
50 #include <fcntl.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <err.h>
54 #endif
55
56 #include "decode.h"
57 #include "packet.h"
58
59 #ifdef USE_BEARSSL
60
61 #define get_error_string ve_error_get
62
63 void
initialize(void)64 initialize (void)
65 {
66 openpgp_trust_init();
67 }
68
69 #else
70
71 #include <openssl/err.h>
72
73 /**
74 * @brief initialize OpenSSL
75 */
76 void
initialize(void)77 initialize(void)
78 {
79 static int once;
80
81 if (once)
82 return);
83 once = 1;
84 //CRYPTO_malloc_init();
85 ERR_load_crypto_strings();
86 OpenSSL_add_all_algorithms();
87 }
88
89 /**
90 * @brief
91 * last error from OpenSSL as a string
92 */
93 char *
94 get_error_string(void)
95 {
96 initialize();
97 return (ERR_error_string(ERR_get_error(), NULL));
98 }
99 #endif
100
101 /**
102 * @brief decode a signature packet
103 *
104 * We only support RSA
105 *
106 * @sa rfc4880:5.2
107 */
108 ssize_t
109 decode_sig(int tag, unsigned char **pptr, size_t len, OpenPGP_sig *sig)
110 {
111 unsigned char *ptr;
112 unsigned char *pgpbytes;
113 unsigned char *sp;
114 int version;
115 int hcount = 0;
116 int ucount = 0;
117 int stag = 0;
118 int n;
119
120 n = tag; /* avoid unused */
121
122 /*
123 * We need to keep a reference to the packet bytes
124 * as these form part of the signature data.
125 *
126 * @sa rfc4880:5.2.4
127 */
128 pgpbytes = ptr = *pptr;
129 version = *ptr++;
130 if (version == 3) {
131 ptr++;
132 sig->pgpbytes = malloc(5);
133 if (!sig->pgpbytes)
134 return (-1);
135 memcpy(sig->pgpbytes, ptr, 5);
136 sig->pgpbytes_len = 5;
137 sig->sig_type = *ptr++;
138 ptr += 4;
139 sig->key_id = octets2hex(ptr, 8);
140 ptr += 8;
141 sig->sig_alg = *ptr++;
142 sig->hash_alg = *ptr++;
143 } else if (version == 4) {
144 sig->sig_type = *ptr++;
145 sig->sig_alg = *ptr++;
146 sig->hash_alg = *ptr++;
147 hcount = octets2i(ptr, 2);
148 ptr += 2;
149 sig->pgpbytes_len = (size_t)hcount + 6;
150 sig->pgpbytes = malloc(sig->pgpbytes_len + 6);
151 if (!sig->pgpbytes)
152 return (-1);
153 memcpy(sig->pgpbytes, pgpbytes, sig->pgpbytes_len);
154 sp = &sig->pgpbytes[sig->pgpbytes_len];
155 *sp++ = 4;
156 *sp++ = 255;
157 memcpy(sp, i2octets(4, (int)sig->pgpbytes_len), 4);
158 sig->pgpbytes_len += 6;
159
160 while (hcount > 0) {
161 sp = decode_subpacket(&ptr, &stag, &n);
162 hcount -= n;
163 /* can check stag to see if we care */
164 }
165 ucount = octets2i(ptr, 2);
166 ptr += 2;
167 while (ucount > 0) {
168 sp = decode_subpacket(&ptr, &stag, &n);
169 ucount -= n;
170 /* can check stag to see if we care */
171 if (stag == 16) {
172 free(sig->key_id);
173 sig->key_id = octets2hex(sp, 8);
174 }
175 }
176 } else
177 return (-1);
178 ptr += 2; /* skip hash16 */
179 if (sig->sig_alg == 1) { /* RSA */
180 sig->sig = decode_mpi(&ptr, &sig->sig_len);
181 }
182 /* we are done */
183 return ((ssize_t)len);
184 }
185
186 /**
187 * @brief map OpenPGP hash algorithm id's to name
188 *
189 * @sa rfc4880:9.4
190 */
191 static struct hash_alg_map {
192 int halg;
193 const char *hname;
194 } hash_algs[] = {
195 {1, "md5"},
196 {2, "sha1"},
197 {8, "sha256"},
198 {9, "sha384"},
199 {10, "sha512"},
200 {11, "sha224"},
201 {0, NULL},
202 };
203
204 static const char *
205 get_hname(int hash_alg)
206 {
207 struct hash_alg_map *hmp;
208
209 for (hmp = hash_algs; hmp->halg > 0; hmp++) {
210 if (hmp->halg == hash_alg)
211 return (hmp->hname);
212 }
213 return (NULL);
214 }
215
216 /* lifted from signer.c */
217 /**
218 * @brief verify a digest
219 *
220 * The public key, digest name, file and signature data.
221 *
222 * @return 1 on success 0 on failure, -1 on error
223 */
224 #ifndef USE_BEARSSL
225 static int
226 verify_digest (EVP_PKEY *pkey,
227 const char *digest,
228 unsigned char *mdata, size_t mlen,
229 unsigned char *sdata, size_t slen)
230 {
231 EVP_MD_CTX ctx;
232 const EVP_MD *md = NULL;
233 EVP_PKEY_CTX *pctx = NULL;
234 int rc = 0;
235 int i = -1;
236
237 initialize();
238 md = EVP_get_digestbyname(digest);
239 EVP_DigestInit(&ctx, md);
240
241 pctx = EVP_PKEY_CTX_new(pkey, NULL);
242 if (!pctx)
243 goto fail;
244 if (EVP_PKEY_verify_init(pctx) <= 0)
245 goto fail;
246 if (EVP_PKEY_CTX_set_signature_md(pctx, ctx.digest) <= 0)
247 goto fail;
248 i = EVP_PKEY_verify(pctx, sdata, slen, mdata, mlen);
249 if (i >= 0)
250 rc = i;
251 fail:
252 EVP_PKEY_CTX_free(pctx);
253 return (rc);
254 }
255 #endif
256
257
258 /**
259 * @brief verify OpenPGP signed file
260 *
261 *
262 * @param[in] filename
263 * used to determine the signature name
264 *
265 * @param[in] fdata
266 * content of filename
267 *
268 * @param[in] fbytes
269 * of fdata
270 *
271 * @param[in] sdata
272 * content of signature
273 *
274 * @param[in] sbytes
275 * of sdata
276 *
277 * @param[in] flags
278 *
279 * @return 0 on success
280 */
281 int
282 openpgp_verify(const char *filename,
283 unsigned char *fdata, size_t fbytes,
284 unsigned char *sdata, size_t sbytes,
285 int flags)
286 {
287 OpenPGP_key *key;
288 OpenPGP_sig *sig;
289 #ifdef USE_BEARSSL
290 const br_hash_class *md;
291 br_hash_compat_context mctx;
292 const unsigned char *hash_oid;
293 #else
294 const EVP_MD *md = NULL;
295 EVP_MD_CTX mctx;
296 #endif
297 unsigned char mdata[64];
298 unsigned char *ptr;
299 unsigned char *ddata = NULL;
300 const char *hname;
301 size_t mlen;
302 int rc = -1;
303
304 initialize();
305
306 sig = NEW(OpenPGP_sig);
307 if (!sdata || !sig) {
308 warnx("cannot verify %s", filename);
309 goto oops;
310 }
311 if (!(sdata[0] & OPENPGP_TAG_ISTAG))
312 sdata = ddata = dearmor((char *)sdata, sbytes, &sbytes);
313 ptr = sdata;
314 rc = decode_packet(2, &ptr, sbytes, (decoder_t)decode_sig, sig);
315 DEBUG_PRINTF(2, ("rc=%d keyID=%s\n", rc, sig->key_id ? sig->key_id : "?"));
316 if (rc == 0 && sig->key_id) {
317 key = load_key_id(sig->key_id);
318 if (!key) {
319 warnx("cannot find key-id: %s", sig->key_id);
320 rc = -1;
321 } else if (!(hname = get_hname(sig->hash_alg))) {
322 warnx("unsupported hash algorithm: %d", sig->hash_alg);
323 rc = -1;
324 } else {
325 /*
326 * Hash fdata according to the OpenPGP recipe
327 *
328 * @sa rfc4880:5.2.4
329 */
330 #ifdef USE_BEARSSL
331 switch (sig->hash_alg) { /* see hash_algs above */
332 case 2: /* sha1 */
333 md = &br_sha1_vtable;
334 mlen = br_sha1_SIZE;
335 hash_oid = BR_HASH_OID_SHA1;
336 break;
337 case 8: /* sha256 */
338 md = &br_sha256_vtable;
339 mlen = br_sha256_SIZE;
340 hash_oid = BR_HASH_OID_SHA256;
341 break;
342 case 9: /* sha384 */
343 md = &br_sha384_vtable;
344 mlen = br_sha384_SIZE;
345 hash_oid = BR_HASH_OID_SHA384;
346 break;
347 case 10: /* sha512 */
348 md = &br_sha512_vtable;
349 mlen = br_sha512_SIZE;
350 hash_oid = BR_HASH_OID_SHA512;
351 break;
352 default:
353 warnx("unsupported hash algorithm: %s", hname);
354 rc = -1;
355 goto oops;
356 }
357 md->init(&mctx.vtable);
358 md->update(&mctx.vtable, fdata, fbytes);
359 md->update(&mctx.vtable, sig->pgpbytes,
360 sig->pgpbytes_len);
361 md->out(&mctx.vtable, mdata);
362
363 rc = verify_rsa_digest(key->key, hash_oid,
364 mdata, mlen, sig->sig, sig->sig_len);
365 #else
366 md = EVP_get_digestbyname(hname);
367 EVP_DigestInit(&mctx, md);
368 EVP_DigestUpdate(&mctx, fdata, fbytes);
369 EVP_DigestUpdate(&mctx, sig->pgpbytes,
370 sig->pgpbytes_len);
371 mlen = sizeof(mdata);
372 EVP_DigestFinal(&mctx,mdata,(unsigned int *)&mlen);
373
374 rc = verify_digest(key->key, hname, mdata, mlen,
375 sig->sig, sig->sig_len);
376 #endif
377
378 if (rc > 0) {
379 if ((flags & VEF_VERBOSE))
380 printf("Verified %s signed by %s\n",
381 filename,
382 key->user ? key->user->name : "someone");
383 rc = 0; /* success */
384 } else if (rc == 0) {
385 printf("Unverified %s: %s\n",
386 filename, get_error_string());
387 rc = 1;
388 } else {
389 printf("Unverified %s\n", filename);
390 }
391 }
392 } else {
393 warnx("cannot decode signature for %s", filename);
394 rc = -1;
395 }
396 oops:
397 free(ddata);
398 free(sig);
399 return (rc);
400 }
401
402 #ifndef _STANDALONE
403 /**
404 * @brief list of extensions we handle
405 *
406 * ".asc" is preferred as it works seamlessly with openpgp
407 */
408 static const char *sig_exts[] = {
409 ".asc",
410 ".pgp",
411 ".psig",
412 NULL,
413 };
414
415 /**
416 * @brief verify OpenPGP signed file
417 *
418 *
419 * @param[in] filename
420 * used to determine the signature name
421 *
422 * @param[in] fdata
423 * content of filename
424 *
425 * @param[in] nbytes
426 * of fdata
427 *
428 * @return
429 */
430
431 int
432 openpgp_verify_file(const char *filename, unsigned char *fdata, size_t nbytes)
433 {
434 char pbuf[MAXPATHLEN];
435 unsigned char *sdata;
436 const char *sname = NULL;
437 const char **ep;
438 size_t sz;
439 int n;
440
441 for (ep = sig_exts; *ep; ep++) {
442 n = snprintf(pbuf, sizeof(pbuf), "%s%s", filename, *ep);
443 if (n >= (int)sizeof(pbuf)) {
444 warnx("cannot form signature name for %s", filename);
445 return (-1);
446 }
447 if (access(pbuf, R_OK) == 0) {
448 sname = pbuf;
449 break;
450 }
451 }
452 if (!sname) {
453 warnx("cannot find signature for %s", filename);
454 return (-1);
455 }
456 sdata = read_file(sname, &sz);
457 return (openpgp_verify(filename, fdata, nbytes, sdata, sz, VerifyFlags));
458 }
459 #endif
460
461 /**
462 * @brief verify OpenPGP signature
463 *
464 * @return content of signed file
465 */
466 unsigned char *
467 verify_asc(const char *sigfile, int flags)
468 {
469 char pbuf[MAXPATHLEN];
470 char *cp;
471 size_t n;
472 unsigned char *fdata, *sdata;
473 size_t fbytes, sbytes;
474
475 fdata = NULL;
476 if ((sdata = read_file(sigfile, &sbytes))) {
477 n = strlcpy(pbuf, sigfile, sizeof(pbuf));
478 if (n < sizeof(pbuf)) {
479 if ((cp = strrchr(pbuf, '.')))
480 *cp = '\0';
481 if ((fdata = read_file(pbuf, &fbytes))) {
482 if (openpgp_verify(pbuf, fdata, fbytes, sdata,
483 sbytes, flags)) {
484 free(fdata);
485 fdata = NULL;
486 }
487 }
488 }
489 }
490 free(sdata);
491 return (fdata);
492 }
493