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