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