xref: /freebsd/lib/libsecureboot/vets.c (revision 67ca7330cf34a789afbbff9ae7e4cdc4a4917ae3)
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 SECONDS_PER_DAY		86400
47 #define X509_DAYS_TO_UTC0	719528
48 
49 int DebugVe = 0;
50 
51 typedef VECTOR(br_x509_certificate) cert_list;
52 typedef VECTOR(hash_data) digest_list;
53 
54 static anchor_list trust_anchors = VEC_INIT;
55 static anchor_list forbidden_anchors = VEC_INIT;
56 static digest_list forbidden_digests = VEC_INIT;
57 
58 void
59 ve_debug_set(int n)
60 {
61 	DebugVe = n;
62 }
63 
64 static char ebuf[512];
65 
66 char *
67 ve_error_get(void)
68 {
69 	return (ebuf);
70 }
71 
72 int
73 ve_error_set(const char *fmt, ...)
74 {
75 	int rc;
76 	va_list ap;
77 
78 	va_start(ap, fmt);
79 	ebuf[0] = '\0';
80 	rc = 0;
81 	if (fmt) {
82 #ifdef STAND_H
83 		vsprintf(ebuf, fmt, ap); /* no vsnprintf in libstand */
84 		ebuf[sizeof(ebuf) - 1] = '\0';
85 		rc = strlen(ebuf);
86 #else
87 		rc = vsnprintf(ebuf, sizeof(ebuf), fmt, ap);
88 #endif
89 	}
90 	va_end(ap);
91 	return (rc);
92 }
93 
94 /* this is the time we use for verifying certs */
95 static time_t ve_utc = 0;
96 
97 /**
98  * @brief
99  * set ve_utc used for certificate verification
100  *
101  * @param[in] utc
102  *	time - ignored unless greater than current value.
103  */
104 void
105 ve_utc_set(time_t utc)
106 {
107 	if (utc > ve_utc) {
108 		DEBUG_PRINTF(2, ("Set ve_utc=%jd\n", (intmax_t)utc));
109 		ve_utc = utc;
110 	}
111 }
112 
113 static void
114 free_cert_contents(br_x509_certificate *xc)
115 {
116 	xfree(xc->data);
117 }
118 
119 /* ASN parsing related defines */
120 #define ASN1_PRIMITIVE_TAG 0x1F
121 #define ASN1_INF_LENGTH    0x80
122 #define ASN1_LENGTH_MASK   0x7F
123 
124 /*
125  * Get TBS part of certificate.
126  * Since BearSSL doesn't provide any API to do this,
127  * it has to be implemented here.
128  */
129 static void*
130 X509_to_tbs(unsigned char* cert, size_t* output_size)
131 {
132 	unsigned char *result;
133 	size_t tbs_size;
134 	int size, i;
135 
136 	if (cert == NULL)
137 		return (NULL);
138 
139 	/* Strip two sequences to get to the TBS section */
140 	for (i = 0; i < 2; i++) {
141 		/*
142 		 * XXX: We don't need to support extended tags since
143 		 * they should not be present in certificates.
144 		 */
145 		if ((*cert & ASN1_PRIMITIVE_TAG) == ASN1_PRIMITIVE_TAG)
146 			return (NULL);
147 
148 		cert++;
149 
150 		if (*cert == ASN1_INF_LENGTH)
151 			return (NULL);
152 
153 		size = *cert & ASN1_LENGTH_MASK;
154 		tbs_size = 0;
155 
156 		/* Size can either be stored on a single or multiple bytes */
157 		if (*cert & (ASN1_LENGTH_MASK + 1)) {
158 			cert++;
159 			while (*cert == 0 && size > 0) {
160 				cert++;
161 				size--;
162 			}
163 			while (size-- > 0) {
164 				tbs_size <<= 8;
165 				tbs_size |= *(cert++);
166 			}
167 		}
168 		if (i == 0)
169 			result = cert;
170 	}
171 	tbs_size += (cert - result);
172 
173 	if (output_size != NULL)
174 		*output_size = tbs_size;
175 
176 	return (result);
177 }
178 
179 void
180 ve_forbidden_digest_add(hash_data *digest, size_t num)
181 {
182 	while (num--)
183 		VEC_ADD(forbidden_digests, digest[num]);
184 }
185 
186 static size_t
187 ve_anchors_add(br_x509_certificate *xcs, size_t num, anchor_list *anchors)
188 {
189 	br_x509_trust_anchor ta;
190 	size_t u;
191 
192 	for (u = 0; u < num; u++) {
193 		if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) {
194 			break;
195 		}
196 		VEC_ADD(*anchors, ta);
197 	}
198 	return (u);
199 }
200 
201 /**
202  * @brief
203  * add certs to our trust store
204  */
205 size_t
206 ve_trust_anchors_add(br_x509_certificate *xcs, size_t num)
207 {
208 	return (ve_anchors_add(xcs, num, &trust_anchors));
209 }
210 
211 size_t
212 ve_forbidden_anchors_add(br_x509_certificate *xcs, size_t num)
213 {
214 	return (ve_anchors_add(xcs, num, &forbidden_anchors));
215 }
216 
217 /**
218  * @brief
219  * initialize our trust_anchors from ta_PEM
220  */
221 int
222 ve_trust_init(void)
223 {
224 #ifdef TRUST_ANCHOR_STR
225 	br_x509_certificate *xcs;
226 #endif
227 	static int once = -1;
228 	size_t num;
229 
230 	if (once >= 0)
231 		return (once);
232 
233 	ve_utc_set(time(NULL));
234 #ifdef BUILD_UTC
235 	ve_utc_set(BUILD_UTC);		/* just in case */
236 #endif
237 	ve_error_set(NULL);		/* make sure it is empty */
238 #ifdef VE_PCR_SUPPORT
239 	ve_pcr_init();
240 #endif
241 
242 #ifdef TRUST_ANCHOR_STR
243 	xcs = parse_certificates(__DECONST(unsigned char *, TRUST_ANCHOR_STR),
244 	    sizeof(TRUST_ANCHOR_STR), &num);
245 	if (xcs != NULL)
246 		num = ve_trust_anchors_add(xcs, num);
247 #endif
248 	once = (int) VEC_LEN(trust_anchors);
249 #ifdef VE_OPENPGP_SUPPORT
250 	once += openpgp_trust_init();
251 #endif
252 	return (once);
253 }
254 
255 /**
256  * if we can verify the certificate chain in "certs",
257  * return the public key and if "xcp" is !NULL the associated
258  * certificate
259  */
260 static br_x509_pkey *
261 verify_signer_xcs(br_x509_certificate *xcs,
262     size_t num,
263     br_name_element *elts, size_t num_elts,
264     anchor_list *anchors)
265 {
266 	br_x509_minimal_context mc;
267 	br_x509_certificate *xc;
268 	size_t u;
269 	cert_list chain = VEC_INIT;
270 	const br_x509_pkey *tpk;
271 	br_x509_pkey *pk;
272 	unsigned int usages;
273 	int err;
274 
275 	DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num));
276 	VEC_ADDMANY(chain, xcs, num);
277 	if (VEC_LEN(chain) == 0) {
278 		ve_error_set("ERROR: no/invalid certificate chain\n");
279 		return (NULL);
280 	}
281 
282 	DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n",
283 		VEC_LEN(*anchors)));
284 
285 	br_x509_minimal_init(&mc, &br_sha256_vtable,
286 	    &VEC_ELT(*anchors, 0),
287 	    VEC_LEN(*anchors));
288 #ifdef VE_ECDSA_SUPPORT
289 	br_x509_minimal_set_ecdsa(&mc,
290 	    &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
291 #endif
292 #ifdef VE_RSA_SUPPORT
293 	br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy);
294 #endif
295 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
296 	/* This is deprecated! do not enable unless you absoultely have to */
297 	br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable);
298 #endif
299 	br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable);
300 #ifdef VE_SHA384_SUPPORT
301 	br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable);
302 #endif
303 #ifdef VE_SHA512_SUPPORT
304 	br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable);
305 #endif
306 	br_x509_minimal_set_name_elements(&mc, elts, num_elts);
307 
308 #ifdef _STANDALONE
309 	/*
310 	 * Clock is probably bogus so we use ve_utc.
311 	 */
312 	mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0;
313 	mc.seconds = (ve_utc % SECONDS_PER_DAY);
314 #endif
315 
316 	mc.vtable->start_chain(&mc.vtable, NULL);
317 	for (u = 0; u < VEC_LEN(chain); u ++) {
318 		xc = &VEC_ELT(chain, u);
319 		mc.vtable->start_cert(&mc.vtable, xc->data_len);
320 		mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
321 		mc.vtable->end_cert(&mc.vtable);
322 		switch (mc.err) {
323 		case 0:
324 		case BR_ERR_X509_OK:
325 		case BR_ERR_X509_EXPIRED:
326 			break;
327 		default:
328 			printf("u=%zu mc.err=%d\n", u, mc.err);
329 			break;
330 		}
331 	}
332 	err = mc.vtable->end_chain(&mc.vtable);
333 	pk = NULL;
334 	if (err) {
335 		ve_error_set("Validation failed, err = %d", err);
336 	} else {
337 		tpk = mc.vtable->get_pkey(&mc.vtable, &usages);
338 		if (tpk != NULL) {
339 			pk = xpkeydup(tpk);
340 		}
341 	}
342 	VEC_CLEAR(chain);
343 	return (pk);
344 }
345 
346 /*
347  * Check if digest of one of the certificates from verified chain
348  * is present in the forbidden database.
349  * Since UEFI allows to store three types of digests
350  * all of them have to be checked separately.
351  */
352 static int
353 check_forbidden_digests(br_x509_certificate *xcs, size_t num)
354 {
355 	unsigned char sha256_digest[br_sha256_SIZE];
356 	unsigned char sha384_digest[br_sha384_SIZE];
357 	unsigned char sha512_digest[br_sha512_SIZE];
358 	void *tbs;
359 	hash_data *digest;
360 	br_hash_compat_context ctx;
361 	const br_hash_class *md;
362 	size_t tbs_len, i;
363 	int have_sha256, have_sha384, have_sha512;
364 
365 	if (VEC_LEN(forbidden_digests) == 0)
366 		return (0);
367 
368 	/*
369 	 * Iterate through certificates, extract their To-Be-Signed section,
370 	 * and compare its digest against the ones in the forbidden database.
371 	 */
372 	while (num--) {
373 		tbs = X509_to_tbs(xcs[num].data, &tbs_len);
374 		if (tbs == NULL) {
375 			printf("Failed to obtain TBS part of certificate\n");
376 			return (1);
377 		}
378 		have_sha256 = have_sha384 = have_sha512 = 0;
379 
380 		for (i = 0; i < VEC_LEN(forbidden_digests); i++) {
381 			digest = &VEC_ELT(forbidden_digests, i);
382 			switch (digest->hash_size) {
383 			case br_sha256_SIZE:
384 				if (!have_sha256) {
385 					have_sha256 = 1;
386 					md = &br_sha256_vtable;
387 					md->init(&ctx.vtable);
388 					md->update(&ctx.vtable, tbs, tbs_len);
389 					md->out(&ctx.vtable, sha256_digest);
390 				}
391 				if (!memcmp(sha256_digest,
392 					digest->data,
393 					br_sha256_SIZE))
394 					return (1);
395 
396 				break;
397 			case br_sha384_SIZE:
398 				if (!have_sha384) {
399 					have_sha384 = 1;
400 					md = &br_sha384_vtable;
401 					md->init(&ctx.vtable);
402 					md->update(&ctx.vtable, tbs, tbs_len);
403 					md->out(&ctx.vtable, sha384_digest);
404 				}
405 				if (!memcmp(sha384_digest,
406 					digest->data,
407 					br_sha384_SIZE))
408 					return (1);
409 
410 				break;
411 			case br_sha512_SIZE:
412 				if (!have_sha512) {
413 					have_sha512 = 1;
414 					md = &br_sha512_vtable;
415 					md->init(&ctx.vtable);
416 					md->update(&ctx.vtable, tbs, tbs_len);
417 					md->out(&ctx.vtable, sha512_digest);
418 				}
419 				if (!memcmp(sha512_digest,
420 					digest->data,
421 					br_sha512_SIZE))
422 					return (1);
423 
424 				break;
425 			}
426 		}
427 	}
428 
429 	return (0);
430 }
431 
432 static br_x509_pkey *
433 verify_signer(const char *certs,
434     br_name_element *elts, size_t num_elts)
435 {
436 	br_x509_certificate *xcs;
437 	br_x509_pkey *pk;
438 	size_t num;
439 
440 	pk = NULL;
441 
442 	ve_trust_init();
443 	xcs = read_certificates(certs, &num);
444 	if (xcs == NULL) {
445 		ve_error_set("cannot read certificates\n");
446 		return (NULL);
447 	}
448 
449 	/*
450 	 * Check if either
451 	 * 1. There is a direct match between cert from forbidden_anchors
452 	 * and a cert from chain.
453 	 * 2. CA that signed the chain is found in forbidden_anchors.
454 	 */
455 	if (VEC_LEN(forbidden_anchors) > 0)
456 		pk = verify_signer_xcs(xcs, num, elts, num_elts, &forbidden_anchors);
457 	if (pk != NULL) {
458 		ve_error_set("Certificate is on forbidden list\n");
459 		xfreepkey(pk);
460 		pk = NULL;
461 		goto out;
462 	}
463 
464 	pk = verify_signer_xcs(xcs, num, elts, num_elts, &trust_anchors);
465 	if (pk == NULL)
466 		goto out;
467 
468 	/*
469 	 * Check if hash of tbs part of any certificate in chain
470 	 * is on the forbidden list.
471 	 */
472 	if (check_forbidden_digests(xcs, num)) {
473 		ve_error_set("Certificate hash is on forbidden list\n");
474 		xfreepkey(pk);
475 		pk = NULL;
476 	}
477 out:
478 	free_certificates(xcs, num);
479 	return (pk);
480 }
481 
482 /**
483  * we need a hex digest including trailing newline below
484  */
485 char *
486 hexdigest(char *buf, size_t bufsz, unsigned char *foo, size_t foo_len)
487 {
488 	char const hex2ascii[] = "0123456789abcdef";
489 	size_t i;
490 
491 	/* every binary byte is 2 chars in hex + newline + null  */
492 	if (bufsz < (2 * foo_len) + 2)
493 		return (NULL);
494 
495 	for (i = 0; i < foo_len; i++) {
496 		buf[i * 2] = hex2ascii[foo[i] >> 4];
497 		buf[i * 2 + 1] = hex2ascii[foo[i] & 0x0f];
498 	}
499 
500 	buf[i * 2] = 0x0A; /* we also want a newline */
501 	buf[i * 2 + 1] = '\0';
502 
503 	return (buf);
504 }
505 
506 /**
507  * @brief
508  * verify file against sigfile using pk
509  *
510  * When we generated the signature in sigfile,
511  * we hashed (sha256) file, and sent that to signing server
512  * which hashed (sha256) that hash.
513  *
514  * To verify we need to replicate that result.
515  *
516  * @param[in] pk
517  *	br_x509_pkey
518  *
519  * @paramp[in] file
520  *	file to be verified
521  *
522  * @param[in] sigfile
523  * 	signature (PEM encoded)
524  *
525  * @return NULL on error, otherwise content of file.
526  */
527 #ifdef VE_ECDSA_SUPPORT
528 static unsigned char *
529 verify_ec(br_x509_pkey *pk, const char *file, const char *sigfile)
530 {
531 	char hexbuf[br_sha512_SIZE * 2 + 2];
532 	unsigned char rhbuf[br_sha512_SIZE];
533 	char *hex;
534 	br_sha256_context ctx;
535 	unsigned char *fcp, *scp;
536 	size_t flen, slen, plen;
537 	pem_object *po;
538 	const br_ec_impl *ec;
539 	br_ecdsa_vrfy vrfy;
540 
541 	if ((fcp = read_file(file, &flen)) == NULL)
542 		return (NULL);
543 	if ((scp = read_file(sigfile, &slen)) == NULL) {
544 		free(fcp);
545 		return (NULL);
546 	}
547 	if ((po = decode_pem(scp, slen, &plen)) == NULL) {
548 		free(fcp);
549 		free(scp);
550 		return (NULL);
551 	}
552 	br_sha256_init(&ctx);
553 	br_sha256_update(&ctx, fcp, flen);
554 	br_sha256_out(&ctx, rhbuf);
555 	hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE);
556 	/* now hash that */
557 	if (hex) {
558 		br_sha256_init(&ctx);
559 		br_sha256_update(&ctx, hex, strlen(hex));
560 		br_sha256_out(&ctx, rhbuf);
561 	}
562 	ec = br_ec_get_default();
563 	vrfy = br_ecdsa_vrfy_asn1_get_default();
564 	if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data,
565 		po->data_len)) {
566 		free(fcp);
567 		fcp = NULL;
568 	}
569 	free(scp);
570 	return (fcp);
571 }
572 #endif
573 
574 #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT)
575 /**
576  * @brief verify an rsa digest
577  *
578  * @return 0 on failure
579  */
580 int
581 verify_rsa_digest (br_rsa_public_key *pkey,
582     const unsigned char *hash_oid,
583     unsigned char *mdata, size_t mlen,
584     unsigned char *sdata, size_t slen)
585 {
586 	br_rsa_pkcs1_vrfy vrfy;
587 	unsigned char vhbuf[br_sha512_SIZE];
588 
589 	vrfy = br_rsa_pkcs1_vrfy_get_default();
590 
591 	if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) ||
592 	    memcmp(vhbuf, mdata, mlen) != 0) {
593 		return (0);		/* fail */
594 	}
595 	return (1);			/* ok */
596 }
597 #endif
598 
599 /**
600  * @brief
601  * verify file against sigfile using pk
602  *
603  * When we generated the signature in sigfile,
604  * we hashed (sha256) file, and sent that to signing server
605  * which hashed (sha256) that hash.
606  *
607  * Or (deprecated) we simply used sha1 hash directly.
608  *
609  * To verify we need to replicate that result.
610  *
611  * @param[in] pk
612  *	br_x509_pkey
613  *
614  * @paramp[in] file
615  *	file to be verified
616  *
617  * @param[in] sigfile
618  * 	signature (PEM encoded)
619  *
620  * @return NULL on error, otherwise content of file.
621  */
622 #ifdef VE_RSA_SUPPORT
623 static unsigned char *
624 verify_rsa(br_x509_pkey *pk,  const char *file, const char *sigfile)
625 {
626 	unsigned char rhbuf[br_sha512_SIZE];
627 	const unsigned char *hash_oid;
628 	const br_hash_class *md;
629 	br_hash_compat_context mctx;
630 	unsigned char *fcp, *scp;
631 	size_t flen, slen, plen, hlen;
632 	pem_object *po;
633 
634 	if ((fcp = read_file(file, &flen)) == NULL)
635 		return (NULL);
636 	if ((scp = read_file(sigfile, &slen)) == NULL) {
637 		free(fcp);
638 		return (NULL);
639 	}
640 	if ((po = decode_pem(scp, slen, &plen)) == NULL) {
641 		free(fcp);
642 		free(scp);
643 		return (NULL);
644 	}
645 
646 	switch (po->data_len) {
647 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
648 	case 256:
649 		// this is our old deprecated sig method
650 		md = &br_sha1_vtable;
651 		hlen = br_sha1_SIZE;
652 		hash_oid = BR_HASH_OID_SHA1;
653 		break;
654 #endif
655 	default:
656 		md = &br_sha256_vtable;
657 		hlen = br_sha256_SIZE;
658 		hash_oid = BR_HASH_OID_SHA256;
659 		break;
660 	}
661 	md->init(&mctx.vtable);
662 	md->update(&mctx.vtable, fcp, flen);
663 	md->out(&mctx.vtable, rhbuf);
664 	if (!verify_rsa_digest(&pk->key.rsa, hash_oid,
665 		rhbuf, hlen, po->data, po->data_len)) {
666 		free(fcp);
667 		fcp = NULL;
668 	}
669 	free(scp);
670 	return (fcp);
671 }
672 #endif
673 
674 /**
675  * @brief
676  * verify a signature and return content of signed file
677  *
678  * @param[in] sigfile
679  * 	file containing signature
680  * 	we derrive path of signed file and certificate change from
681  * 	this.
682  *
683  * @param[in] flags
684  * 	only bit 1 significant so far
685  *
686  * @return NULL on error otherwise content of signed file
687  */
688 unsigned char *
689 verify_sig(const char *sigfile, int flags)
690 {
691 	br_x509_pkey *pk;
692 	br_name_element cn;
693 	char cn_buf[80];
694 	unsigned char cn_oid[4];
695 	char pbuf[MAXPATHLEN];
696 	char *cp;
697 	unsigned char *ucp;
698 	size_t n;
699 
700 	DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile));
701 	n = strlcpy(pbuf, sigfile, sizeof(pbuf));
702 	if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0)
703 		return (NULL);
704 	cp = strcpy(&pbuf[n - 3], "certs");
705 	/*
706 	 * We want the commonName field
707 	 * the OID we want is 2,5,4,3 - but DER encoded
708 	 */
709 	cn_oid[0] = 3;
710 	cn_oid[1] = 0x55;
711 	cn_oid[2] = 4;
712 	cn_oid[3] = 3;
713 	cn.oid = cn_oid;
714 	cn.buf = cn_buf;
715 	cn.len = sizeof(cn_buf);
716 
717 	pk = verify_signer(pbuf, &cn, 1);
718 	if (!pk) {
719 		printf("cannot verify: %s: %s\n", pbuf, ve_error_get());
720 		return (NULL);
721 	}
722 	for (; cp > pbuf; cp--) {
723 		if (*cp == '.') {
724 			*cp = '\0';
725 			break;
726 		}
727 	}
728 	switch (pk->key_type) {
729 #ifdef VE_ECDSA_SUPPORT
730 	case BR_KEYTYPE_EC:
731 		ucp = verify_ec(pk, pbuf, sigfile);
732 		break;
733 #endif
734 #ifdef VE_RSA_SUPPORT
735 	case BR_KEYTYPE_RSA:
736 		ucp = verify_rsa(pk, pbuf, sigfile);
737 		break;
738 #endif
739 	default:
740 		ucp = NULL;		/* not supported */
741 	}
742 	xfreepkey(pk);
743 	if (!ucp) {
744 		printf("Unverified %s (%s)\n", pbuf,
745 		    cn.status ? cn_buf : "unknown");
746 	} else if ((flags & 1) != 0) {
747 		printf("Verified %s signed by %s\n", pbuf,
748 		    cn.status ? cn_buf : "someone we trust");
749 	}
750 	return (ucp);
751 }
752 
753 
754 /**
755  * @brief verify hash matches
756  *
757  * We have finished hashing a file,
758  * see if we got the desired result.
759  *
760  * @param[in] ctx
761  *	pointer to hash context
762  *
763  * @param[in] md
764  *	pointer to hash class
765  *
766  * @param[in] path
767  *	name of the file we are checking
768  *
769  * @param[in] want
770  *	the expected result
771  *
772  * @param[in] hlen
773  *	size of hash output
774  *
775  * @return 0 on success
776  */
777 int
778 ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md,
779     const char *path, const char *want, size_t hlen)
780 {
781 	char hexbuf[br_sha512_SIZE * 2 + 2];
782 	unsigned char hbuf[br_sha512_SIZE];
783 	char *hex;
784 	int rc;
785 	int n;
786 
787 	md->out(&ctx->vtable, hbuf);
788 #ifdef VE_PCR_SUPPORT
789 	ve_pcr_update(hbuf, hlen);
790 #endif
791 	hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen);
792 	if (!hex)
793 		return (VE_FINGERPRINT_WRONG);
794 	n = 2*hlen;
795 	if ((rc = strncmp(hex, want, n))) {
796 		ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want);
797 		rc = VE_FINGERPRINT_WRONG;
798 	}
799 	return (rc ? rc : VE_FINGERPRINT_OK);
800 }
801 
802 #ifdef VE_HASH_KAT_STR
803 static int
804 test_hash(const br_hash_class *md, size_t hlen,
805     const char *hname, const char *s, size_t slen, const char *want)
806 {
807 	br_hash_compat_context mctx;
808 
809 	md->init(&mctx.vtable);
810 	md->update(&mctx.vtable, s, slen);
811 	return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK);
812 }
813 
814 #endif
815 
816 #define ve_test_hash(n, N) \
817 	printf("Testing hash: " #n "\t\t\t\t%s\n", \
818 	    test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \
819 	    VE_HASH_KAT_STR, VE_HASH_KAT_STRLEN(VE_HASH_KAT_STR), \
820 	    vh_ ## N) ? "Failed" : "Passed")
821 
822 /**
823  * @brief
824  * run self tests on hash and signature verification
825  *
826  * Test that the hash methods (SHA1 and SHA256) work.
827  * Test that we can verify a certificate for each supported
828  * Root CA.
829  *
830  * @return cached result.
831  */
832 int
833 ve_self_tests(void)
834 {
835 	static int once = -1;
836 #ifdef VERIFY_CERTS_STR
837 	br_x509_certificate *xcs;
838 	br_x509_pkey *pk;
839 	br_name_element cn;
840 	char cn_buf[80];
841 	unsigned char cn_oid[4];
842 	size_t num;
843 	size_t u;
844 #endif
845 
846 	if (once >= 0)
847 		return (once);
848 	once = 0;
849 
850 	DEBUG_PRINTF(5, ("Self tests...\n"));
851 #ifdef VE_HASH_KAT_STR
852 #ifdef VE_SHA1_SUPPORT
853 	ve_test_hash(sha1, SHA1);
854 #endif
855 #ifdef VE_SHA256_SUPPORT
856 	ve_test_hash(sha256, SHA256);
857 #endif
858 #ifdef VE_SHA384_SUPPORT
859 	ve_test_hash(sha384, SHA384);
860 #endif
861 #ifdef VE_SHA512_SUPPORT
862 	ve_test_hash(sha512, SHA512);
863 #endif
864 #endif
865 #ifdef VERIFY_CERTS_STR
866 	xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR),
867 	    sizeof(VERIFY_CERTS_STR), &num);
868 	if (xcs != NULL) {
869 		/*
870 		 * We want the commonName field
871 		 * the OID we want is 2,5,4,3 - but DER encoded
872 		 */
873 		cn_oid[0] = 3;
874 		cn_oid[1] = 0x55;
875 		cn_oid[2] = 4;
876 		cn_oid[3] = 3;
877 		cn.oid = cn_oid;
878 		cn.buf = cn_buf;
879 
880 		for (u = 0; u < num; u ++) {
881 			cn.len = sizeof(cn_buf);
882 			if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) {
883 				free_cert_contents(&xcs[u]);
884 				once++;
885 				printf("Testing verify certificate: %s\tPassed\n",
886 				    cn.status ? cn_buf : "");
887 				xfreepkey(pk);
888 			}
889 		}
890 		if (!once)
891 			printf("Testing verify certificate:\t\t\tFailed\n");
892 		xfree(xcs);
893 	}
894 #endif	/* VERIFY_CERTS_STR */
895 #ifdef VE_OPENPGP_SUPPORT
896 	if (!openpgp_self_tests())
897 		once++;
898 #endif
899 	return (once);
900 }
901