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