xref: /freebsd-13-stable/lib/libsecureboot/vets.c (revision 3d497e17ebd33fe0f58d773e35ab994d750258d6)
1 /*-
2  * Copyright (c) 2017-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 #include <sys/cdefs.h>
26 /**
27  * @file vets.c - trust store
28  * @brief verify signatures
29  *
30  * We leverage code from BearSSL www.bearssl.org
31  */
32 
33 #include <sys/time.h>
34 #include <stdarg.h>
35 #define NEED_BRSSL_H
36 #include "libsecureboot-priv.h"
37 #include <brssl.h>
38 #include <ta.h>
39 
40 #ifndef TRUST_ANCHOR_STR
41 # define TRUST_ANCHOR_STR ta_PEM
42 #endif
43 
44 #define EPOCH_YEAR		1970
45 #define AVG_SECONDS_PER_YEAR	31556952L
46 #define SECONDS_PER_DAY		86400
47 #define SECONDS_PER_YEAR	365 * SECONDS_PER_DAY
48 #ifndef VE_UTC_MAX_JUMP
49 # define VE_UTC_MAX_JUMP	20 * SECONDS_PER_YEAR
50 #endif
51 #define X509_DAYS_TO_UTC0	719528
52 
53 int DebugVe = 0;
54 
55 #ifndef VE_VERIFY_FLAGS
56 # define VE_VERIFY_FLAGS VEF_VERBOSE
57 #endif
58 int VerifyFlags = VE_VERIFY_FLAGS;
59 
60 typedef VECTOR(br_x509_certificate) cert_list;
61 typedef VECTOR(hash_data) digest_list;
62 
63 static anchor_list trust_anchors = VEC_INIT;
64 static anchor_list forbidden_anchors = VEC_INIT;
65 static digest_list forbidden_digests = VEC_INIT;
66 
67 static int anchor_verbose = 0;
68 
69 void
ve_anchor_verbose_set(int n)70 ve_anchor_verbose_set(int n)
71 {
72 	anchor_verbose = n;
73 }
74 
75 int
ve_anchor_verbose_get(void)76 ve_anchor_verbose_get(void)
77 {
78 	return (anchor_verbose);
79 }
80 
81 void
ve_debug_set(int n)82 ve_debug_set(int n)
83 {
84 	DebugVe = n;
85 }
86 
87 /*
88  * For embedded systems (and boot loaders)
89  * we do not want to enforce certificate validity post install.
90  * It is generally unacceptible for infrastructure to stop working
91  * just because it has not been updated recently.
92  */
93 static int enforce_validity = 0;
94 
95 void
ve_enforce_validity_set(int i)96 ve_enforce_validity_set(int i)
97 {
98     enforce_validity = i;
99 }
100 
101 static char ebuf[512];
102 
103 char *
ve_error_get(void)104 ve_error_get(void)
105 {
106 	return (ebuf);
107 }
108 
109 int
ve_error_set(const char * fmt,...)110 ve_error_set(const char *fmt, ...)
111 {
112 	int rc;
113 	va_list ap;
114 
115 	va_start(ap, fmt);
116 	ebuf[0] = '\0';
117 	rc = 0;
118 	if (fmt) {
119 #ifdef STAND_H
120 		vsprintf(ebuf, fmt, ap); /* no vsnprintf in libstand */
121 		ebuf[sizeof(ebuf) - 1] = '\0';
122 		rc = strlen(ebuf);
123 #else
124 		rc = vsnprintf(ebuf, sizeof(ebuf), fmt, ap);
125 #endif
126 	}
127 	va_end(ap);
128 	return (rc);
129 }
130 
131 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
132 
133 /*
134  * The *approximate* date.
135  *
136  * When certificate verification fails for being
137  * expired or not yet valid, it helps to indicate
138  * our current date.
139  * Since libsa lacks strftime and gmtime,
140  * this simple implementation suffices.
141  */
142 static const char *
gdate(char * buf,size_t bufsz,time_t clock)143 gdate(char *buf, size_t bufsz, time_t clock)
144 {
145 	int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
146 	int year, y, m, d;
147 
148 	y = clock / AVG_SECONDS_PER_YEAR;
149 	year = EPOCH_YEAR + y;
150 	for (y = EPOCH_YEAR; y < year; y++) {
151 		clock -= SECONDS_PER_YEAR;
152 		if (isleap(y))
153 			clock -= SECONDS_PER_DAY;
154 	}
155 	d = clock / SECONDS_PER_DAY;
156 	for (m = 0; d > 1 && m < 12; m++) {
157 		if (d > days[m]) {
158 			d -= days[m];
159 			if (m == 1 && d > 0 && isleap(year))
160 				d--;
161 		} else
162 			break;
163 	}
164 	d++;
165 	if (d > days[m]) {
166 	    d = 1;
167 	    m++;
168 	    if (m >= 12) {
169 		year++;
170 		m = 0;
171 	    }
172 	}
173 	(void)snprintf(buf, bufsz, "%04d-%02d-%02d", year, m+1, d);
174 	return(buf);
175 }
176 
177 /* this is the time we use for verifying certs */
178 #ifdef UNIT_TEST
179 extern time_t ve_utc;
180 time_t ve_utc = 0;
181 #else
182 static time_t ve_utc = 0;
183 #endif
184 
185 /**
186  * @brief
187  * set ve_utc used for certificate verification
188  *
189  * @param[in] utc
190  *	time - ignored unless greater than current value
191  *	and not a leap of 20 years or more.
192  */
193 void
ve_utc_set(time_t utc)194 ve_utc_set(time_t utc)
195 {
196 	if (utc > ve_utc &&
197 	    (ve_utc == 0 || (utc - ve_utc) < VE_UTC_MAX_JUMP)) {
198 		DEBUG_PRINTF(2, ("Set ve_utc=%jd\n", (intmax_t)utc));
199 		ve_utc = utc;
200 	}
201 }
202 
203 static void
free_cert_contents(br_x509_certificate * xc)204 free_cert_contents(br_x509_certificate *xc)
205 {
206 	xfree(xc->data);
207 }
208 
209 /*
210  * a bit of a dance to get commonName from a certificate
211  */
212 static char *
x509_cn_get(br_x509_certificate * xc,char * buf,size_t len)213 x509_cn_get(br_x509_certificate *xc, char *buf, size_t len)
214 {
215 	br_x509_minimal_context mc;
216 	br_name_element cn;
217 	unsigned char cn_oid[4];
218 	int err;
219 
220 	if (buf == NULL)
221 		return (buf);
222 	/*
223 	 * We want the commonName field
224 	 * the OID we want is 2,5,4,3 - but DER encoded
225 	 */
226 	cn_oid[0] = 3;
227 	cn_oid[1] = 0x55;
228 	cn_oid[2] = 4;
229 	cn_oid[3] = 3;
230 	cn.oid = cn_oid;
231 	cn.buf = buf;
232 	cn.len = len;
233 	cn.buf[0] = '\0';
234 
235 	br_x509_minimal_init(&mc, &br_sha256_vtable, NULL, 0);
236 	br_x509_minimal_set_name_elements(&mc, &cn, 1);
237 	/* the below actually does the work - updates cn.status */
238 	mc.vtable->start_chain(&mc.vtable, NULL);
239 	mc.vtable->start_cert(&mc.vtable, xc->data_len);
240 	mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
241 	mc.vtable->end_cert(&mc.vtable);
242 	/* we don' actually care about cert status - just its name */
243 	err = mc.vtable->end_chain(&mc.vtable);
244 
245 	if (!cn.status)
246 		buf = NULL;
247 	return (buf);
248 }
249 
250 /* ASN parsing related defines */
251 #define ASN1_PRIMITIVE_TAG 0x1F
252 #define ASN1_INF_LENGTH    0x80
253 #define ASN1_LENGTH_MASK   0x7F
254 
255 /*
256  * Get TBS part of certificate.
257  * Since BearSSL doesn't provide any API to do this,
258  * it has to be implemented here.
259  */
260 static void*
X509_to_tbs(unsigned char * cert,size_t * output_size)261 X509_to_tbs(unsigned char* cert, size_t* output_size)
262 {
263 	unsigned char *result;
264 	size_t tbs_size;
265 	int size, i;
266 
267 	if (cert == NULL)
268 		return (NULL);
269 
270 	/* Strip two sequences to get to the TBS section */
271 	for (i = 0; i < 2; i++) {
272 		/*
273 		 * XXX: We don't need to support extended tags since
274 		 * they should not be present in certificates.
275 		 */
276 		if ((*cert & ASN1_PRIMITIVE_TAG) == ASN1_PRIMITIVE_TAG)
277 			return (NULL);
278 
279 		cert++;
280 
281 		if (*cert == ASN1_INF_LENGTH)
282 			return (NULL);
283 
284 		size = *cert & ASN1_LENGTH_MASK;
285 		tbs_size = 0;
286 
287 		/* Size can either be stored on a single or multiple bytes */
288 		if (*cert & (ASN1_LENGTH_MASK + 1)) {
289 			cert++;
290 			while (*cert == 0 && size > 0) {
291 				cert++;
292 				size--;
293 			}
294 			while (size-- > 0) {
295 				tbs_size <<= 8;
296 				tbs_size |= *(cert++);
297 			}
298 		}
299 		if (i == 0)
300 			result = cert;
301 	}
302 	tbs_size += (cert - result);
303 
304 	if (output_size != NULL)
305 		*output_size = tbs_size;
306 
307 	return (result);
308 }
309 
310 void
ve_forbidden_digest_add(hash_data * digest,size_t num)311 ve_forbidden_digest_add(hash_data *digest, size_t num)
312 {
313 	while (num--)
314 		VEC_ADD(forbidden_digests, digest[num]);
315 }
316 
317 static size_t
ve_anchors_add(br_x509_certificate * xcs,size_t num,anchor_list * anchors,const char * anchors_name)318 ve_anchors_add(br_x509_certificate *xcs, size_t num, anchor_list *anchors,
319     const char *anchors_name)
320 {
321 	br_x509_trust_anchor ta;
322 	size_t u;
323 
324 	for (u = 0; u < num; u++) {
325 		if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) {
326 			break;
327 		}
328 		VEC_ADD(*anchors, ta);
329 		if (anchor_verbose && anchors_name) {
330 			char buf[64];
331 			char *cp;
332 
333 			cp = x509_cn_get(&xcs[u], buf, sizeof(buf));
334 			if (cp) {
335 				printf("x509_anchor(%s) %s\n", cp, anchors_name);
336 			}
337 		}
338 	}
339 	return (u);
340 }
341 
342 /**
343  * @brief
344  * add certs to our trust store
345  */
346 size_t
ve_trust_anchors_add(br_x509_certificate * xcs,size_t num)347 ve_trust_anchors_add(br_x509_certificate *xcs, size_t num)
348 {
349 	return (ve_anchors_add(xcs, num, &trust_anchors, "trusted"));
350 }
351 
352 size_t
ve_forbidden_anchors_add(br_x509_certificate * xcs,size_t num)353 ve_forbidden_anchors_add(br_x509_certificate *xcs, size_t num)
354 {
355 	return (ve_anchors_add(xcs, num, &forbidden_anchors, "forbidden"));
356 }
357 
358 
359 /**
360  * @brief add trust anchors in buf
361  *
362  * Assume buf contains x509 certificates, but if not and
363  * we support OpenPGP try adding as that.
364  *
365  * @return number of anchors added
366  */
367 size_t
ve_trust_anchors_add_buf(unsigned char * buf,size_t len)368 ve_trust_anchors_add_buf(unsigned char *buf, size_t len)
369 {
370 	br_x509_certificate *xcs;
371 	size_t num;
372 
373 	num = 0;
374 	xcs = parse_certificates(buf, len, &num);
375 	if (xcs != NULL) {
376 		num = ve_trust_anchors_add(xcs, num);
377 #ifdef VE_OPENPGP_SUPPORT
378 	} else {
379 		num = openpgp_trust_add_buf(buf, len);
380 #endif
381 	}
382 	return (num);
383 }
384 
385 /**
386  * @brief revoke trust anchors in buf
387  *
388  * Assume buf contains x509 certificates, but if not and
389  * we support OpenPGP try revoking keyId
390  *
391  * @return number of anchors revoked
392  */
393 size_t
ve_trust_anchors_revoke(unsigned char * buf,size_t len)394 ve_trust_anchors_revoke(unsigned char *buf, size_t len)
395 {
396 	br_x509_certificate *xcs;
397 	size_t num;
398 
399 	num = 0;
400 	xcs = parse_certificates(buf, len, &num);
401 	if (xcs != NULL) {
402 		num = ve_forbidden_anchors_add(xcs, num);
403 #ifdef VE_OPENPGP_SUPPORT
404 	} else {
405 		if (buf[len - 1] == '\n')
406 			buf[len - 1] = '\0';
407 		num = openpgp_trust_revoke((char *)buf);
408 #endif
409 	}
410 	return (num);
411 }
412 
413 /**
414  * @brief
415  * initialize our trust_anchors from ta_PEM
416  */
417 int
ve_trust_init(void)418 ve_trust_init(void)
419 {
420 	static int once = -1;
421 
422 	if (once >= 0)
423 		return (once);
424 	once = 0;			/* to be sure */
425 #ifdef BUILD_UTC
426 	ve_utc_set(BUILD_UTC);		/* ensure sanity */
427 #endif
428 	ve_utc_set(time(NULL));
429 	ve_error_set(NULL);		/* make sure it is empty */
430 #ifdef VE_PCR_SUPPORT
431 	ve_pcr_init();
432 #endif
433 
434 #ifdef TRUST_ANCHOR_STR
435 	if (TRUST_ANCHOR_STR != NULL && strlen(TRUST_ANCHOR_STR) != 0ul)
436 		ve_trust_anchors_add_buf(__DECONST(unsigned char *,
437 		    TRUST_ANCHOR_STR), sizeof(TRUST_ANCHOR_STR));
438 #endif
439 	once = (int) VEC_LEN(trust_anchors);
440 #ifdef VE_OPENPGP_SUPPORT
441 	once += openpgp_trust_init();
442 #endif
443 	return (once);
444 }
445 
446 #ifdef HAVE_BR_X509_TIME_CHECK
447 static int
verify_time_cb(void * tctx __unused,uint32_t not_before_days,uint32_t not_before_seconds,uint32_t not_after_days,uint32_t not_after_seconds)448 verify_time_cb(void *tctx __unused,
449     uint32_t not_before_days, uint32_t not_before_seconds,
450     uint32_t not_after_days, uint32_t not_after_seconds)
451 {
452 	time_t not_before;
453 	time_t not_after;
454 	int rc;
455 #ifdef UNIT_TEST
456 	char date[12], nb_date[12], na_date[12];
457 #endif
458 
459 	if (enforce_validity) {
460 		not_before = ((not_before_days - X509_DAYS_TO_UTC0) * SECONDS_PER_DAY) + not_before_seconds;
461 		not_after =  ((not_after_days - X509_DAYS_TO_UTC0) * SECONDS_PER_DAY) + not_after_seconds;
462 		if (ve_utc < not_before)
463 			rc = -1;
464 		else if (ve_utc > not_after)
465 			rc = 1;
466 		else
467 			rc = 0;
468 #ifdef UNIT_TEST
469 		printf("notBefore %s notAfter %s date %s rc %d\n",
470 		    gdate(nb_date, sizeof(nb_date), not_before),
471 		    gdate(na_date, sizeof(na_date), not_after),
472 		    gdate(date, sizeof(date), ve_utc), rc);
473 #endif
474 	} else
475 		rc = 0;			/* don't fail */
476 	return rc;
477 }
478 #endif
479 
480 /**
481  * if we can verify the certificate chain in "certs",
482  * return the public key and if "xcp" is !NULL the associated
483  * certificate
484  */
485 static br_x509_pkey *
verify_signer_xcs(br_x509_certificate * xcs,size_t num,br_name_element * elts,size_t num_elts,anchor_list * anchors)486 verify_signer_xcs(br_x509_certificate *xcs,
487     size_t num,
488     br_name_element *elts, size_t num_elts,
489     anchor_list *anchors)
490 {
491 	br_x509_minimal_context mc;
492 	br_x509_certificate *xc;
493 	size_t u;
494 	cert_list chain = VEC_INIT;
495 	const br_x509_pkey *tpk;
496 	br_x509_pkey *pk;
497 	unsigned int usages;
498 	int err;
499 
500 	DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num));
501 	VEC_ADDMANY(chain, xcs, num);
502 	if (VEC_LEN(chain) == 0) {
503 		ve_error_set("ERROR: no/invalid certificate chain\n");
504 		return (NULL);
505 	}
506 
507 	DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n",
508 		VEC_LEN(*anchors)));
509 
510 	br_x509_minimal_init(&mc, &br_sha256_vtable,
511 	    &VEC_ELT(*anchors, 0),
512 	    VEC_LEN(*anchors));
513 #ifdef VE_ECDSA_SUPPORT
514 	br_x509_minimal_set_ecdsa(&mc,
515 	    &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
516 #endif
517 #ifdef VE_RSA_SUPPORT
518 	br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy);
519 #endif
520 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
521 	/* This is deprecated! do not enable unless you absolutely have to */
522 	br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable);
523 #endif
524 	br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable);
525 #ifdef VE_SHA384_SUPPORT
526 	br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable);
527 #endif
528 #ifdef VE_SHA512_SUPPORT
529 	br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable);
530 #endif
531 	br_x509_minimal_set_name_elements(&mc, elts, num_elts);
532 
533 #ifdef HAVE_BR_X509_TIME_CHECK
534 	br_x509_minimal_set_time_callback(&mc, NULL, verify_time_cb);
535 #else
536 #if defined(_STANDALONE) || defined(UNIT_TEST)
537 	/*
538 	 * Clock is probably bogus so we use ve_utc.
539 	 */
540 	mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0;
541 	mc.seconds = (ve_utc % SECONDS_PER_DAY);
542 #endif
543 #endif
544 	mc.vtable->start_chain(&mc.vtable, NULL);
545 	for (u = 0; u < VEC_LEN(chain); u ++) {
546 		xc = &VEC_ELT(chain, u);
547 		mc.vtable->start_cert(&mc.vtable, xc->data_len);
548 		mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
549 		mc.vtable->end_cert(&mc.vtable);
550 		switch (mc.err) {
551 		case 0:
552 		case BR_ERR_X509_OK:
553 		case BR_ERR_X509_EXPIRED:
554 			break;
555 		default:
556 			printf("u=%zu mc.err=%d\n", u, mc.err);
557 			break;
558 		}
559 	}
560 	err = mc.vtable->end_chain(&mc.vtable);
561 	pk = NULL;
562 	if (err) {
563 		char date[12];
564 
565 		switch (err) {
566 		case 54:
567 			ve_error_set("Validation failed, certificate not valid as of %s",
568 			    gdate(date, sizeof(date), ve_utc));
569 			break;
570 		default:
571 			ve_error_set("Validation failed, err = %d", err);
572 			break;
573 		}
574 	} else {
575 		tpk = mc.vtable->get_pkey(&mc.vtable, &usages);
576 		if (tpk != NULL) {
577 			pk = xpkeydup(tpk);
578 		}
579 	}
580 	VEC_CLEAR(chain);
581 	return (pk);
582 }
583 
584 /*
585  * Check if digest of one of the certificates from verified chain
586  * is present in the forbidden database.
587  * Since UEFI allows to store three types of digests
588  * all of them have to be checked separately.
589  */
590 static int
check_forbidden_digests(br_x509_certificate * xcs,size_t num)591 check_forbidden_digests(br_x509_certificate *xcs, size_t num)
592 {
593 	unsigned char sha256_digest[br_sha256_SIZE];
594 	unsigned char sha384_digest[br_sha384_SIZE];
595 	unsigned char sha512_digest[br_sha512_SIZE];
596 	void *tbs;
597 	hash_data *digest;
598 	br_hash_compat_context ctx;
599 	const br_hash_class *md;
600 	size_t tbs_len, i;
601 	int have_sha256, have_sha384, have_sha512;
602 
603 	if (VEC_LEN(forbidden_digests) == 0)
604 		return (0);
605 
606 	/*
607 	 * Iterate through certificates, extract their To-Be-Signed section,
608 	 * and compare its digest against the ones in the forbidden database.
609 	 */
610 	while (num--) {
611 		tbs = X509_to_tbs(xcs[num].data, &tbs_len);
612 		if (tbs == NULL) {
613 			printf("Failed to obtain TBS part of certificate\n");
614 			return (1);
615 		}
616 		have_sha256 = have_sha384 = have_sha512 = 0;
617 
618 		for (i = 0; i < VEC_LEN(forbidden_digests); i++) {
619 			digest = &VEC_ELT(forbidden_digests, i);
620 			switch (digest->hash_size) {
621 			case br_sha256_SIZE:
622 				if (!have_sha256) {
623 					have_sha256 = 1;
624 					md = &br_sha256_vtable;
625 					md->init(&ctx.vtable);
626 					md->update(&ctx.vtable, tbs, tbs_len);
627 					md->out(&ctx.vtable, sha256_digest);
628 				}
629 				if (!memcmp(sha256_digest,
630 					digest->data,
631 					br_sha256_SIZE))
632 					return (1);
633 
634 				break;
635 			case br_sha384_SIZE:
636 				if (!have_sha384) {
637 					have_sha384 = 1;
638 					md = &br_sha384_vtable;
639 					md->init(&ctx.vtable);
640 					md->update(&ctx.vtable, tbs, tbs_len);
641 					md->out(&ctx.vtable, sha384_digest);
642 				}
643 				if (!memcmp(sha384_digest,
644 					digest->data,
645 					br_sha384_SIZE))
646 					return (1);
647 
648 				break;
649 			case br_sha512_SIZE:
650 				if (!have_sha512) {
651 					have_sha512 = 1;
652 					md = &br_sha512_vtable;
653 					md->init(&ctx.vtable);
654 					md->update(&ctx.vtable, tbs, tbs_len);
655 					md->out(&ctx.vtable, sha512_digest);
656 				}
657 				if (!memcmp(sha512_digest,
658 					digest->data,
659 					br_sha512_SIZE))
660 					return (1);
661 
662 				break;
663 			}
664 		}
665 	}
666 
667 	return (0);
668 }
669 
670 static br_x509_pkey *
verify_signer(const char * certs,br_name_element * elts,size_t num_elts)671 verify_signer(const char *certs,
672     br_name_element *elts, size_t num_elts)
673 {
674 	br_x509_certificate *xcs;
675 	br_x509_pkey *pk;
676 	size_t num;
677 
678 	pk = NULL;
679 
680 	ve_trust_init();
681 	xcs = read_certificates(certs, &num);
682 	if (xcs == NULL) {
683 		ve_error_set("cannot read certificates\n");
684 		return (NULL);
685 	}
686 
687 	/*
688 	 * Check if either
689 	 * 1. There is a direct match between cert from forbidden_anchors
690 	 * and a cert from chain.
691 	 * 2. CA that signed the chain is found in forbidden_anchors.
692 	 */
693 	if (VEC_LEN(forbidden_anchors) > 0)
694 		pk = verify_signer_xcs(xcs, num, elts, num_elts, &forbidden_anchors);
695 	if (pk != NULL) {
696 		ve_error_set("Certificate is on forbidden list\n");
697 		xfreepkey(pk);
698 		pk = NULL;
699 		goto out;
700 	}
701 
702 	pk = verify_signer_xcs(xcs, num, elts, num_elts, &trust_anchors);
703 	if (pk == NULL)
704 		goto out;
705 
706 	/*
707 	 * Check if hash of tbs part of any certificate in chain
708 	 * is on the forbidden list.
709 	 */
710 	if (check_forbidden_digests(xcs, num)) {
711 		ve_error_set("Certificate hash is on forbidden list\n");
712 		xfreepkey(pk);
713 		pk = NULL;
714 	}
715 out:
716 	free_certificates(xcs, num);
717 	return (pk);
718 }
719 
720 /**
721  * we need a hex digest including trailing newline below
722  */
723 char *
hexdigest(char * buf,size_t bufsz,unsigned char * foo,size_t foo_len)724 hexdigest(char *buf, size_t bufsz, unsigned char *foo, size_t foo_len)
725 {
726 	char const hex2ascii[] = "0123456789abcdef";
727 	size_t i;
728 
729 	/* every binary byte is 2 chars in hex + newline + null  */
730 	if (bufsz < (2 * foo_len) + 2)
731 		return (NULL);
732 
733 	for (i = 0; i < foo_len; i++) {
734 		buf[i * 2] = hex2ascii[foo[i] >> 4];
735 		buf[i * 2 + 1] = hex2ascii[foo[i] & 0x0f];
736 	}
737 
738 	buf[i * 2] = 0x0A; /* we also want a newline */
739 	buf[i * 2 + 1] = '\0';
740 
741 	return (buf);
742 }
743 
744 /**
745  * @brief
746  * verify file against sigfile using pk
747  *
748  * When we generated the signature in sigfile,
749  * we hashed (sha256) file, and sent that to signing server
750  * which hashed (sha256) that hash.
751  *
752  * To verify we need to replicate that result.
753  *
754  * @param[in] pk
755  *	br_x509_pkey
756  *
757  * @paramp[in] file
758  *	file to be verified
759  *
760  * @param[in] sigfile
761  * 	signature (PEM encoded)
762  *
763  * @return NULL on error, otherwise content of file.
764  */
765 #ifdef VE_ECDSA_SUPPORT
766 static unsigned char *
verify_ec(br_x509_pkey * pk,const char * file,const char * sigfile)767 verify_ec(br_x509_pkey *pk, const char *file, const char *sigfile)
768 {
769 #ifdef VE_ECDSA_HASH_AGAIN
770 	char *hex, hexbuf[br_sha512_SIZE * 2 + 2];
771 #endif
772 	unsigned char rhbuf[br_sha512_SIZE];
773 	br_sha256_context ctx;
774 	unsigned char *fcp, *scp;
775 	size_t flen, slen, plen;
776 	pem_object *po;
777 	const br_ec_impl *ec;
778 	br_ecdsa_vrfy vrfy;
779 
780 	if ((fcp = read_file(file, &flen)) == NULL)
781 		return (NULL);
782 	if ((scp = read_file(sigfile, &slen)) == NULL) {
783 		free(fcp);
784 		return (NULL);
785 	}
786 	if ((po = decode_pem(scp, slen, &plen)) == NULL) {
787 		free(fcp);
788 		free(scp);
789 		return (NULL);
790 	}
791 	br_sha256_init(&ctx);
792 	br_sha256_update(&ctx, fcp, flen);
793 	br_sha256_out(&ctx, rhbuf);
794 #ifdef VE_ECDSA_HASH_AGAIN
795 	hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE);
796 	/* now hash that */
797 	if (hex) {
798 		br_sha256_init(&ctx);
799 		br_sha256_update(&ctx, hex, strlen(hex));
800 		br_sha256_out(&ctx, rhbuf);
801 	}
802 #endif
803 	ec = br_ec_get_default();
804 	vrfy = br_ecdsa_vrfy_asn1_get_default();
805 	if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data,
806 		po->data_len)) {
807 		free(fcp);
808 		fcp = NULL;
809 	}
810 	free(scp);
811 	return (fcp);
812 }
813 #endif
814 
815 #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT)
816 /**
817  * @brief verify an rsa digest
818  *
819  * @return 0 on failure
820  */
821 int
verify_rsa_digest(br_rsa_public_key * pkey,const unsigned char * hash_oid,unsigned char * mdata,size_t mlen,unsigned char * sdata,size_t slen)822 verify_rsa_digest (br_rsa_public_key *pkey,
823     const unsigned char *hash_oid,
824     unsigned char *mdata, size_t mlen,
825     unsigned char *sdata, size_t slen)
826 {
827 	br_rsa_pkcs1_vrfy vrfy;
828 	unsigned char vhbuf[br_sha512_SIZE];
829 
830 	vrfy = br_rsa_pkcs1_vrfy_get_default();
831 
832 	if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) ||
833 	    memcmp(vhbuf, mdata, mlen) != 0) {
834 		return (0);		/* fail */
835 	}
836 	return (1);			/* ok */
837 }
838 #endif
839 
840 /**
841  * @brief
842  * verify file against sigfile using pk
843  *
844  * When we generated the signature in sigfile,
845  * we hashed (sha256) file, and sent that to signing server
846  * which hashed (sha256) that hash.
847  *
848  * Or (deprecated) we simply used sha1 hash directly.
849  *
850  * To verify we need to replicate that result.
851  *
852  * @param[in] pk
853  *	br_x509_pkey
854  *
855  * @paramp[in] file
856  *	file to be verified
857  *
858  * @param[in] sigfile
859  * 	signature (PEM encoded)
860  *
861  * @return NULL on error, otherwise content of file.
862  */
863 #ifdef VE_RSA_SUPPORT
864 static unsigned char *
verify_rsa(br_x509_pkey * pk,const char * file,const char * sigfile)865 verify_rsa(br_x509_pkey *pk,  const char *file, const char *sigfile)
866 {
867 	unsigned char rhbuf[br_sha512_SIZE];
868 	const unsigned char *hash_oid;
869 	const br_hash_class *md;
870 	br_hash_compat_context mctx;
871 	unsigned char *fcp, *scp;
872 	size_t flen, slen, plen, hlen;
873 	pem_object *po;
874 
875 	if ((fcp = read_file(file, &flen)) == NULL)
876 		return (NULL);
877 	if ((scp = read_file(sigfile, &slen)) == NULL) {
878 		free(fcp);
879 		return (NULL);
880 	}
881 	if ((po = decode_pem(scp, slen, &plen)) == NULL) {
882 		free(fcp);
883 		free(scp);
884 		return (NULL);
885 	}
886 
887 	switch (po->data_len) {
888 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
889 	case 256:
890 		// this is our old deprecated sig method
891 		md = &br_sha1_vtable;
892 		hlen = br_sha1_SIZE;
893 		hash_oid = BR_HASH_OID_SHA1;
894 		break;
895 #endif
896 	default:
897 		md = &br_sha256_vtable;
898 		hlen = br_sha256_SIZE;
899 		hash_oid = BR_HASH_OID_SHA256;
900 		break;
901 	}
902 	md->init(&mctx.vtable);
903 	md->update(&mctx.vtable, fcp, flen);
904 	md->out(&mctx.vtable, rhbuf);
905 	if (!verify_rsa_digest(&pk->key.rsa, hash_oid,
906 		rhbuf, hlen, po->data, po->data_len)) {
907 		free(fcp);
908 		fcp = NULL;
909 	}
910 	free(scp);
911 	return (fcp);
912 }
913 #endif
914 
915 /**
916  * @brief
917  * verify a signature and return content of signed file
918  *
919  * @param[in] sigfile
920  * 	file containing signature
921  * 	we derrive path of signed file and certificate change from
922  * 	this.
923  *
924  * @param[in] flags
925  * 	only bit 1 significant so far
926  *
927  * @return NULL on error otherwise content of signed file
928  */
929 unsigned char *
verify_sig(const char * sigfile,int flags)930 verify_sig(const char *sigfile, int flags)
931 {
932 	br_x509_pkey *pk;
933 	br_name_element cn;
934 	char cn_buf[80];
935 	unsigned char cn_oid[4];
936 	char pbuf[MAXPATHLEN];
937 	char *cp;
938 	unsigned char *ucp;
939 	size_t n;
940 
941 	DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile));
942 	n = strlcpy(pbuf, sigfile, sizeof(pbuf));
943 	if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0)
944 		return (NULL);
945 	cp = strcpy(&pbuf[n - 3], "certs");
946 	/*
947 	 * We want the commonName field
948 	 * the OID we want is 2,5,4,3 - but DER encoded
949 	 */
950 	cn_oid[0] = 3;
951 	cn_oid[1] = 0x55;
952 	cn_oid[2] = 4;
953 	cn_oid[3] = 3;
954 	cn.oid = cn_oid;
955 	cn.buf = cn_buf;
956 	cn.len = sizeof(cn_buf);
957 
958 	pk = verify_signer(pbuf, &cn, 1);
959 	if (!pk) {
960 		printf("cannot verify: %s: %s\n", pbuf, ve_error_get());
961 		return (NULL);
962 	}
963 	for (; cp > pbuf; cp--) {
964 		if (*cp == '.') {
965 			*cp = '\0';
966 			break;
967 		}
968 	}
969 	switch (pk->key_type) {
970 #ifdef VE_ECDSA_SUPPORT
971 	case BR_KEYTYPE_EC:
972 		ucp = verify_ec(pk, pbuf, sigfile);
973 		break;
974 #endif
975 #ifdef VE_RSA_SUPPORT
976 	case BR_KEYTYPE_RSA:
977 		ucp = verify_rsa(pk, pbuf, sigfile);
978 		break;
979 #endif
980 	default:
981 		ucp = NULL;		/* not supported */
982 	}
983 	xfreepkey(pk);
984 	if (!ucp) {
985 		printf("Unverified %s (%s)\n", pbuf,
986 		    cn.status ? cn_buf : "unknown");
987 	} else if ((flags & VEF_VERBOSE) != 0) {
988 		printf("Verified %s signed by %s\n", pbuf,
989 		    cn.status ? cn_buf : "someone we trust");
990 	}
991 	return (ucp);
992 }
993 
994 
995 /**
996  * @brief verify hash matches
997  *
998  * We have finished hashing a file,
999  * see if we got the desired result.
1000  *
1001  * @param[in] ctx
1002  *	pointer to hash context
1003  *
1004  * @param[in] md
1005  *	pointer to hash class
1006  *
1007  * @param[in] path
1008  *	name of the file we are checking
1009  *
1010  * @param[in] want
1011  *	the expected result
1012  *
1013  * @param[in] hlen
1014  *	size of hash output
1015  *
1016  * @return 0 on success
1017  */
1018 int
ve_check_hash(br_hash_compat_context * ctx,const br_hash_class * md,const char * path,const char * want,size_t hlen)1019 ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md,
1020     const char *path, const char *want, size_t hlen)
1021 {
1022 	char hexbuf[br_sha512_SIZE * 2 + 2];
1023 	unsigned char hbuf[br_sha512_SIZE];
1024 	char *hex;
1025 	int rc;
1026 	int n;
1027 
1028 	md->out(&ctx->vtable, hbuf);
1029 #ifdef VE_PCR_SUPPORT
1030 	ve_pcr_update(path, hbuf, hlen);
1031 #endif
1032 	hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen);
1033 	if (!hex)
1034 		return (VE_FINGERPRINT_WRONG);
1035 	n = 2*hlen;
1036 	if ((rc = strncmp(hex, want, n))) {
1037 		ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want);
1038 		rc = VE_FINGERPRINT_WRONG;
1039 	}
1040 	return (rc ? rc : VE_FINGERPRINT_OK);
1041 }
1042 
1043 #ifdef VE_HASH_KAT_STR
1044 static int
test_hash(const br_hash_class * md,size_t hlen,const char * hname,const char * s,size_t slen,const char * want)1045 test_hash(const br_hash_class *md, size_t hlen,
1046     const char *hname, const char *s, size_t slen, const char *want)
1047 {
1048 	br_hash_compat_context mctx;
1049 
1050 	md->init(&mctx.vtable);
1051 	md->update(&mctx.vtable, s, slen);
1052 	return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK);
1053 }
1054 
1055 #endif
1056 
1057 #define ve_test_hash(n, N) \
1058 	printf("Testing hash: " #n "\t\t\t\t%s\n", \
1059 	    test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \
1060 	    VE_HASH_KAT_STR, VE_HASH_KAT_STRLEN(VE_HASH_KAT_STR), \
1061 	    vh_ ## N) ? "Failed" : "Passed")
1062 
1063 /**
1064  * @brief
1065  * run self tests on hash and signature verification
1066  *
1067  * Test that the hash methods (SHA1 and SHA256) work.
1068  * Test that we can verify a certificate for each supported
1069  * Root CA.
1070  *
1071  * @return cached result.
1072  */
1073 int
ve_self_tests(void)1074 ve_self_tests(void)
1075 {
1076 	static int once = -1;
1077 #ifdef VERIFY_CERTS_STR
1078 	br_x509_certificate *xcs;
1079 	br_x509_pkey *pk;
1080 	br_name_element cn;
1081 	char cn_buf[80];
1082 	unsigned char cn_oid[4];
1083 	size_t num;
1084 	size_t u;
1085 #endif
1086 
1087 	if (once >= 0)
1088 		return (once);
1089 	once = 0;
1090 
1091 	DEBUG_PRINTF(5, ("Self tests...\n"));
1092 #ifdef VE_HASH_KAT_STR
1093 #ifdef VE_SHA1_SUPPORT
1094 	ve_test_hash(sha1, SHA1);
1095 #endif
1096 #ifdef VE_SHA256_SUPPORT
1097 	ve_test_hash(sha256, SHA256);
1098 #endif
1099 #ifdef VE_SHA384_SUPPORT
1100 	ve_test_hash(sha384, SHA384);
1101 #endif
1102 #ifdef VE_SHA512_SUPPORT
1103 	ve_test_hash(sha512, SHA512);
1104 #endif
1105 #endif
1106 #ifdef VERIFY_CERTS_STR
1107 	xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR),
1108 	    sizeof(VERIFY_CERTS_STR), &num);
1109 	if (xcs != NULL) {
1110 		/*
1111 		 * We want the commonName field
1112 		 * the OID we want is 2,5,4,3 - but DER encoded
1113 		 */
1114 		cn_oid[0] = 3;
1115 		cn_oid[1] = 0x55;
1116 		cn_oid[2] = 4;
1117 		cn_oid[3] = 3;
1118 		cn.oid = cn_oid;
1119 		cn.buf = cn_buf;
1120 
1121 		for (u = 0; u < num; u ++) {
1122 			cn.len = sizeof(cn_buf);
1123 			if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) {
1124 				free_cert_contents(&xcs[u]);
1125 				once++;
1126 				printf("Testing verify certificate: %s\tPassed\n",
1127 				    cn.status ? cn_buf : "");
1128 				xfreepkey(pk);
1129 			}
1130 		}
1131 		if (!once)
1132 			printf("Testing verify certificate:\t\t\tFailed\n");
1133 		xfree(xcs);
1134 	}
1135 #endif	/* VERIFY_CERTS_STR */
1136 #ifdef VE_OPENPGP_SUPPORT
1137 	if (!openpgp_self_tests())
1138 		once++;
1139 #endif
1140 	return (once);
1141 }
1142