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