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