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