xref: /freebsd/lib/libsecureboot/vets.c (revision 5fff9558a43aaac53da41dc23c250c4e84f6fb02)
1*5fff9558SSimon J. Gerraty /*-
2*5fff9558SSimon J. Gerraty  * Copyright (c) 2017-2018, Juniper Networks, Inc.
3*5fff9558SSimon J. Gerraty  *
4*5fff9558SSimon J. Gerraty  * Redistribution and use in source and binary forms, with or without
5*5fff9558SSimon J. Gerraty  * modification, are permitted provided that the following conditions
6*5fff9558SSimon J. Gerraty  * are met:
7*5fff9558SSimon J. Gerraty  * 1. Redistributions of source code must retain the above copyright
8*5fff9558SSimon J. Gerraty  *    notice, this list of conditions and the following disclaimer.
9*5fff9558SSimon J. Gerraty  * 2. Redistributions in binary form must reproduce the above copyright
10*5fff9558SSimon J. Gerraty  *    notice, this list of conditions and the following disclaimer in the
11*5fff9558SSimon J. Gerraty  *    documentation and/or other materials provided with the distribution.
12*5fff9558SSimon J. Gerraty  *
13*5fff9558SSimon J. Gerraty  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14*5fff9558SSimon J. Gerraty  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15*5fff9558SSimon J. Gerraty  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16*5fff9558SSimon J. Gerraty  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17*5fff9558SSimon J. Gerraty  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18*5fff9558SSimon J. Gerraty  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19*5fff9558SSimon J. Gerraty  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*5fff9558SSimon J. Gerraty  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*5fff9558SSimon J. Gerraty  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*5fff9558SSimon J. Gerraty  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23*5fff9558SSimon J. Gerraty  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*5fff9558SSimon J. Gerraty  */
25*5fff9558SSimon J. Gerraty #include <sys/cdefs.h>
26*5fff9558SSimon J. Gerraty __FBSDID("$FreeBSD$");
27*5fff9558SSimon J. Gerraty 
28*5fff9558SSimon J. Gerraty /**
29*5fff9558SSimon J. Gerraty  * @file vets.c - trust store
30*5fff9558SSimon J. Gerraty  * @brief verify signatures
31*5fff9558SSimon J. Gerraty  *
32*5fff9558SSimon J. Gerraty  * We leverage code from BearSSL www.bearssl.org
33*5fff9558SSimon J. Gerraty  */
34*5fff9558SSimon J. Gerraty 
35*5fff9558SSimon J. Gerraty #include <sys/time.h>
36*5fff9558SSimon J. Gerraty #include <stdarg.h>
37*5fff9558SSimon J. Gerraty #define NEED_BRSSL_H
38*5fff9558SSimon J. Gerraty #include "libsecureboot-priv.h"
39*5fff9558SSimon J. Gerraty #include <brssl.h>
40*5fff9558SSimon J. Gerraty #include <ta.h>
41*5fff9558SSimon J. Gerraty 
42*5fff9558SSimon J. Gerraty #ifndef TRUST_ANCHOR_STR
43*5fff9558SSimon J. Gerraty # define TRUST_ANCHOR_STR ta_PEM
44*5fff9558SSimon J. Gerraty #endif
45*5fff9558SSimon J. Gerraty 
46*5fff9558SSimon J. Gerraty #define SECONDS_PER_DAY		86400
47*5fff9558SSimon J. Gerraty #define X509_DAYS_TO_UTC0	719528
48*5fff9558SSimon J. Gerraty 
49*5fff9558SSimon J. Gerraty int DebugVe = 0;
50*5fff9558SSimon J. Gerraty 
51*5fff9558SSimon J. Gerraty typedef VECTOR(br_x509_certificate) cert_list;
52*5fff9558SSimon J. Gerraty 
53*5fff9558SSimon J. Gerraty static anchor_list trust_anchors = VEC_INIT;
54*5fff9558SSimon J. Gerraty 
55*5fff9558SSimon J. Gerraty void
56*5fff9558SSimon J. Gerraty ve_debug_set(int n)
57*5fff9558SSimon J. Gerraty {
58*5fff9558SSimon J. Gerraty 	DebugVe = n;
59*5fff9558SSimon J. Gerraty }
60*5fff9558SSimon J. Gerraty 
61*5fff9558SSimon J. Gerraty static char ebuf[512];
62*5fff9558SSimon J. Gerraty 
63*5fff9558SSimon J. Gerraty char *
64*5fff9558SSimon J. Gerraty ve_error_get(void)
65*5fff9558SSimon J. Gerraty {
66*5fff9558SSimon J. Gerraty 	return (ebuf);
67*5fff9558SSimon J. Gerraty }
68*5fff9558SSimon J. Gerraty 
69*5fff9558SSimon J. Gerraty int
70*5fff9558SSimon J. Gerraty ve_error_set(const char *fmt, ...)
71*5fff9558SSimon J. Gerraty {
72*5fff9558SSimon J. Gerraty 	int rc;
73*5fff9558SSimon J. Gerraty 	va_list ap;
74*5fff9558SSimon J. Gerraty 
75*5fff9558SSimon J. Gerraty 	va_start(ap, fmt);
76*5fff9558SSimon J. Gerraty 	ebuf[0] = '\0';
77*5fff9558SSimon J. Gerraty 	rc = 0;
78*5fff9558SSimon J. Gerraty 	if (fmt) {
79*5fff9558SSimon J. Gerraty #ifdef STAND_H
80*5fff9558SSimon J. Gerraty 		vsprintf(ebuf, fmt, ap); /* no vsnprintf in libstand */
81*5fff9558SSimon J. Gerraty 		ebuf[sizeof(ebuf) - 1] = '\0';
82*5fff9558SSimon J. Gerraty 		rc = strlen(ebuf);
83*5fff9558SSimon J. Gerraty #else
84*5fff9558SSimon J. Gerraty 		rc = vsnprintf(ebuf, sizeof(ebuf), fmt, ap);
85*5fff9558SSimon J. Gerraty #endif
86*5fff9558SSimon J. Gerraty 	}
87*5fff9558SSimon J. Gerraty 	va_end(ap);
88*5fff9558SSimon J. Gerraty 	return (rc);
89*5fff9558SSimon J. Gerraty }
90*5fff9558SSimon J. Gerraty 
91*5fff9558SSimon J. Gerraty /* this is the time we use for verifying certs */
92*5fff9558SSimon J. Gerraty static time_t ve_utc = 0;
93*5fff9558SSimon J. Gerraty 
94*5fff9558SSimon J. Gerraty /**
95*5fff9558SSimon J. Gerraty  * @brief
96*5fff9558SSimon J. Gerraty  * set ve_utc used for certificate verification
97*5fff9558SSimon J. Gerraty  *
98*5fff9558SSimon J. Gerraty  * @param[in] utc
99*5fff9558SSimon J. Gerraty  *	time - ignored unless greater than current value.
100*5fff9558SSimon J. Gerraty  */
101*5fff9558SSimon J. Gerraty void
102*5fff9558SSimon J. Gerraty ve_utc_set(time_t utc)
103*5fff9558SSimon J. Gerraty {
104*5fff9558SSimon J. Gerraty 	if (utc > ve_utc) {
105*5fff9558SSimon J. Gerraty 		DEBUG_PRINTF(2, ("Set ve_utc=%jd\n", (intmax_t)utc));
106*5fff9558SSimon J. Gerraty 		ve_utc = utc;
107*5fff9558SSimon J. Gerraty 	}
108*5fff9558SSimon J. Gerraty }
109*5fff9558SSimon J. Gerraty 
110*5fff9558SSimon J. Gerraty static void
111*5fff9558SSimon J. Gerraty free_cert_contents(br_x509_certificate *xc)
112*5fff9558SSimon J. Gerraty {
113*5fff9558SSimon J. Gerraty 	xfree(xc->data);
114*5fff9558SSimon J. Gerraty }
115*5fff9558SSimon J. Gerraty 
116*5fff9558SSimon J. Gerraty /**
117*5fff9558SSimon J. Gerraty  * @brief
118*5fff9558SSimon J. Gerraty  * add certs to our trust store
119*5fff9558SSimon J. Gerraty  */
120*5fff9558SSimon J. Gerraty size_t
121*5fff9558SSimon J. Gerraty ve_trust_anchors_add(br_x509_certificate *xcs, size_t num)
122*5fff9558SSimon J. Gerraty {
123*5fff9558SSimon J. Gerraty 	br_x509_trust_anchor ta;
124*5fff9558SSimon J. Gerraty 	size_t u;
125*5fff9558SSimon J. Gerraty 
126*5fff9558SSimon J. Gerraty 	for (u = 0; u < num; u++) {
127*5fff9558SSimon J. Gerraty 		if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) {
128*5fff9558SSimon J. Gerraty 			break;
129*5fff9558SSimon J. Gerraty 		}
130*5fff9558SSimon J. Gerraty 		VEC_ADD(trust_anchors, ta);
131*5fff9558SSimon J. Gerraty 	}
132*5fff9558SSimon J. Gerraty 	return (u);
133*5fff9558SSimon J. Gerraty }
134*5fff9558SSimon J. Gerraty 
135*5fff9558SSimon J. Gerraty /**
136*5fff9558SSimon J. Gerraty  * @brief
137*5fff9558SSimon J. Gerraty  * initialize our trust_anchors from ta_PEM
138*5fff9558SSimon J. Gerraty  */
139*5fff9558SSimon J. Gerraty int
140*5fff9558SSimon J. Gerraty ve_trust_init(void)
141*5fff9558SSimon J. Gerraty {
142*5fff9558SSimon J. Gerraty 	br_x509_certificate *xcs;
143*5fff9558SSimon J. Gerraty 	static int once = -1;
144*5fff9558SSimon J. Gerraty 	size_t num;
145*5fff9558SSimon J. Gerraty 
146*5fff9558SSimon J. Gerraty 	if (once >= 0)
147*5fff9558SSimon J. Gerraty 		return (once);
148*5fff9558SSimon J. Gerraty 	once = 0;
149*5fff9558SSimon J. Gerraty 
150*5fff9558SSimon J. Gerraty 	ve_utc_set(time(NULL));
151*5fff9558SSimon J. Gerraty #ifdef BUILD_UTC
152*5fff9558SSimon J. Gerraty 	ve_utc_set(BUILD_UTC);		/* just in case */
153*5fff9558SSimon J. Gerraty #endif
154*5fff9558SSimon J. Gerraty 	ve_error_set(NULL);		/* make sure it is empty */
155*5fff9558SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
156*5fff9558SSimon J. Gerraty 	ve_pcr_init();
157*5fff9558SSimon J. Gerraty #endif
158*5fff9558SSimon J. Gerraty 
159*5fff9558SSimon J. Gerraty #ifdef TRUST_ANCHOR_STR
160*5fff9558SSimon J. Gerraty 	xcs = parse_certificates(__DECONST(unsigned char *, TRUST_ANCHOR_STR),
161*5fff9558SSimon J. Gerraty 	    sizeof(TRUST_ANCHOR_STR), &num);
162*5fff9558SSimon J. Gerraty 	if (xcs == NULL)
163*5fff9558SSimon J. Gerraty 		return (0);
164*5fff9558SSimon J. Gerraty 	num = ve_trust_anchors_add(xcs, num);
165*5fff9558SSimon J. Gerraty 	once = (int) num;
166*5fff9558SSimon J. Gerraty #else
167*5fff9558SSimon J. Gerraty 	num = 0;
168*5fff9558SSimon J. Gerraty #endif
169*5fff9558SSimon J. Gerraty 	return (num);
170*5fff9558SSimon J. Gerraty }
171*5fff9558SSimon J. Gerraty 
172*5fff9558SSimon J. Gerraty /**
173*5fff9558SSimon J. Gerraty  * if we can verify the certificate chain in "certs",
174*5fff9558SSimon J. Gerraty  * return the public key and if "xcp" is !NULL the associated
175*5fff9558SSimon J. Gerraty  * certificate
176*5fff9558SSimon J. Gerraty  */
177*5fff9558SSimon J. Gerraty static br_x509_pkey *
178*5fff9558SSimon J. Gerraty verify_signer_xcs(br_x509_certificate *xcs,
179*5fff9558SSimon J. Gerraty     size_t num,
180*5fff9558SSimon J. Gerraty     br_name_element *elts, size_t num_elts)
181*5fff9558SSimon J. Gerraty {
182*5fff9558SSimon J. Gerraty 	br_x509_minimal_context mc;
183*5fff9558SSimon J. Gerraty 	br_x509_certificate *xc;
184*5fff9558SSimon J. Gerraty 	size_t u;
185*5fff9558SSimon J. Gerraty 	cert_list chain = VEC_INIT;
186*5fff9558SSimon J. Gerraty 	const br_x509_pkey *tpk;
187*5fff9558SSimon J. Gerraty 	br_x509_pkey *pk;
188*5fff9558SSimon J. Gerraty 	unsigned int usages;
189*5fff9558SSimon J. Gerraty 	int err;
190*5fff9558SSimon J. Gerraty 
191*5fff9558SSimon J. Gerraty 	DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num));
192*5fff9558SSimon J. Gerraty 	VEC_ADDMANY(chain, xcs, num);
193*5fff9558SSimon J. Gerraty 	if (VEC_LEN(chain) == 0) {
194*5fff9558SSimon J. Gerraty 		ve_error_set("ERROR: no/invalid certificate chain\n");
195*5fff9558SSimon J. Gerraty 		return (NULL);
196*5fff9558SSimon J. Gerraty 	}
197*5fff9558SSimon J. Gerraty 
198*5fff9558SSimon J. Gerraty 	DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n",
199*5fff9558SSimon J. Gerraty 		VEC_LEN(trust_anchors)));
200*5fff9558SSimon J. Gerraty 
201*5fff9558SSimon J. Gerraty 	br_x509_minimal_init(&mc, &br_sha256_vtable,
202*5fff9558SSimon J. Gerraty 	    &VEC_ELT(trust_anchors, 0),
203*5fff9558SSimon J. Gerraty 	    VEC_LEN(trust_anchors));
204*5fff9558SSimon J. Gerraty #ifdef VE_ECDSA_SUPPORT
205*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_ecdsa(&mc,
206*5fff9558SSimon J. Gerraty 	    &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
207*5fff9558SSimon J. Gerraty #endif
208*5fff9558SSimon J. Gerraty #ifdef VE_RSA_SUPPORT
209*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy);
210*5fff9558SSimon J. Gerraty #endif
211*5fff9558SSimon J. Gerraty #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
212*5fff9558SSimon J. Gerraty 	/* This is deprecated! do not enable unless you absoultely have to */
213*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable);
214*5fff9558SSimon J. Gerraty #endif
215*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable);
216*5fff9558SSimon J. Gerraty #ifdef VE_SHA384_SUPPORT
217*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable);
218*5fff9558SSimon J. Gerraty #endif
219*5fff9558SSimon J. Gerraty #ifdef VE_SHA512_SUPPORT
220*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable);
221*5fff9558SSimon J. Gerraty #endif
222*5fff9558SSimon J. Gerraty 	br_x509_minimal_set_name_elements(&mc, elts, num_elts);
223*5fff9558SSimon J. Gerraty 
224*5fff9558SSimon J. Gerraty #ifdef _STANDALONE
225*5fff9558SSimon J. Gerraty 	/*
226*5fff9558SSimon J. Gerraty 	 * Clock is probably bogus so we use ve_utc.
227*5fff9558SSimon J. Gerraty 	 */
228*5fff9558SSimon J. Gerraty 	mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0;
229*5fff9558SSimon J. Gerraty 	mc.seconds = (ve_utc % SECONDS_PER_DAY);
230*5fff9558SSimon J. Gerraty #endif
231*5fff9558SSimon J. Gerraty 
232*5fff9558SSimon J. Gerraty 	mc.vtable->start_chain(&mc.vtable, NULL);
233*5fff9558SSimon J. Gerraty 	for (u = 0; u < VEC_LEN(chain); u ++) {
234*5fff9558SSimon J. Gerraty 		xc = &VEC_ELT(chain, u);
235*5fff9558SSimon J. Gerraty 		mc.vtable->start_cert(&mc.vtable, xc->data_len);
236*5fff9558SSimon J. Gerraty 		mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
237*5fff9558SSimon J. Gerraty 		mc.vtable->end_cert(&mc.vtable);
238*5fff9558SSimon J. Gerraty 		switch (mc.err) {
239*5fff9558SSimon J. Gerraty 		case 0:
240*5fff9558SSimon J. Gerraty 		case BR_ERR_X509_OK:
241*5fff9558SSimon J. Gerraty 		case BR_ERR_X509_EXPIRED:
242*5fff9558SSimon J. Gerraty 			break;
243*5fff9558SSimon J. Gerraty 		default:
244*5fff9558SSimon J. Gerraty 			printf("u=%zu mc.err=%d\n", u, mc.err);
245*5fff9558SSimon J. Gerraty 			break;
246*5fff9558SSimon J. Gerraty 		}
247*5fff9558SSimon J. Gerraty 	}
248*5fff9558SSimon J. Gerraty 	err = mc.vtable->end_chain(&mc.vtable);
249*5fff9558SSimon J. Gerraty 	pk = NULL;
250*5fff9558SSimon J. Gerraty 	if (err) {
251*5fff9558SSimon J. Gerraty 		ve_error_set("Validation failed, err = %d", err);
252*5fff9558SSimon J. Gerraty 	} else {
253*5fff9558SSimon J. Gerraty 		tpk = mc.vtable->get_pkey(&mc.vtable, &usages);
254*5fff9558SSimon J. Gerraty 		if (tpk != NULL) {
255*5fff9558SSimon J. Gerraty 			pk = xpkeydup(tpk);
256*5fff9558SSimon J. Gerraty 		}
257*5fff9558SSimon J. Gerraty 	}
258*5fff9558SSimon J. Gerraty 	VEC_CLEAREXT(chain, &free_cert_contents);
259*5fff9558SSimon J. Gerraty 	return (pk);
260*5fff9558SSimon J. Gerraty }
261*5fff9558SSimon J. Gerraty 
262*5fff9558SSimon J. Gerraty static br_x509_pkey *
263*5fff9558SSimon J. Gerraty verify_signer(const char *certs,
264*5fff9558SSimon J. Gerraty     br_name_element *elts, size_t num_elts)
265*5fff9558SSimon J. Gerraty {
266*5fff9558SSimon J. Gerraty 	br_x509_certificate *xcs;
267*5fff9558SSimon J. Gerraty 	br_x509_pkey *pk;
268*5fff9558SSimon J. Gerraty 	size_t num;
269*5fff9558SSimon J. Gerraty 
270*5fff9558SSimon J. Gerraty 	ve_trust_init();
271*5fff9558SSimon J. Gerraty 	xcs = read_certificates(certs, &num);
272*5fff9558SSimon J. Gerraty 	if (xcs == NULL) {
273*5fff9558SSimon J. Gerraty 		ve_error_set("cannot read certificates\n");
274*5fff9558SSimon J. Gerraty 		return (NULL);
275*5fff9558SSimon J. Gerraty 	}
276*5fff9558SSimon J. Gerraty 	pk = verify_signer_xcs(xcs, num, elts, num_elts);
277*5fff9558SSimon J. Gerraty 	xfree(xcs);
278*5fff9558SSimon J. Gerraty 	return (pk);
279*5fff9558SSimon J. Gerraty }
280*5fff9558SSimon J. Gerraty 
281*5fff9558SSimon J. Gerraty /**
282*5fff9558SSimon J. Gerraty  * we need a hex digest including trailing newline below
283*5fff9558SSimon J. Gerraty  */
284*5fff9558SSimon J. Gerraty char *
285*5fff9558SSimon J. Gerraty hexdigest(char *buf, size_t bufsz, unsigned char *foo, size_t foo_len)
286*5fff9558SSimon J. Gerraty {
287*5fff9558SSimon J. Gerraty 	char const hex2ascii[] = "0123456789abcdef";
288*5fff9558SSimon J. Gerraty 	size_t i;
289*5fff9558SSimon J. Gerraty 
290*5fff9558SSimon J. Gerraty 	/* every binary byte is 2 chars in hex + newline + null  */
291*5fff9558SSimon J. Gerraty 	if (bufsz < (2 * foo_len) + 2)
292*5fff9558SSimon J. Gerraty 		return (NULL);
293*5fff9558SSimon J. Gerraty 
294*5fff9558SSimon J. Gerraty 	for (i = 0; i < foo_len; i++) {
295*5fff9558SSimon J. Gerraty 		buf[i * 2] = hex2ascii[foo[i] >> 4];
296*5fff9558SSimon J. Gerraty 		buf[i * 2 + 1] = hex2ascii[foo[i] & 0x0f];
297*5fff9558SSimon J. Gerraty 	}
298*5fff9558SSimon J. Gerraty 
299*5fff9558SSimon J. Gerraty 	buf[i * 2] = 0x0A; /* we also want a newline */
300*5fff9558SSimon J. Gerraty 	buf[i * 2 + 1] = '\0';
301*5fff9558SSimon J. Gerraty 
302*5fff9558SSimon J. Gerraty 	return (buf);
303*5fff9558SSimon J. Gerraty }
304*5fff9558SSimon J. Gerraty 
305*5fff9558SSimon J. Gerraty /**
306*5fff9558SSimon J. Gerraty  * @brief
307*5fff9558SSimon J. Gerraty  * verify file against sigfile using pk
308*5fff9558SSimon J. Gerraty  *
309*5fff9558SSimon J. Gerraty  * When we generated the signature in sigfile,
310*5fff9558SSimon J. Gerraty  * we hashed (sha256) file, and sent that to signing server
311*5fff9558SSimon J. Gerraty  * which hashed (sha256) that hash.
312*5fff9558SSimon J. Gerraty  *
313*5fff9558SSimon J. Gerraty  * To verify we need to replicate that result.
314*5fff9558SSimon J. Gerraty  *
315*5fff9558SSimon J. Gerraty  * @param[in] pk
316*5fff9558SSimon J. Gerraty  *	br_x509_pkey
317*5fff9558SSimon J. Gerraty  *
318*5fff9558SSimon J. Gerraty  * @paramp[in] file
319*5fff9558SSimon J. Gerraty  *	file to be verified
320*5fff9558SSimon J. Gerraty  *
321*5fff9558SSimon J. Gerraty  * @param[in] sigfile
322*5fff9558SSimon J. Gerraty  * 	signature (PEM encoded)
323*5fff9558SSimon J. Gerraty  *
324*5fff9558SSimon J. Gerraty  * @return NULL on error, otherwise content of file.
325*5fff9558SSimon J. Gerraty  */
326*5fff9558SSimon J. Gerraty #ifdef VE_ECDSA_SUPPORT
327*5fff9558SSimon J. Gerraty static unsigned char *
328*5fff9558SSimon J. Gerraty verify_ec(br_x509_pkey *pk, const char *file, const char *sigfile)
329*5fff9558SSimon J. Gerraty {
330*5fff9558SSimon J. Gerraty 	char hexbuf[br_sha512_SIZE * 2 + 2];
331*5fff9558SSimon J. Gerraty 	unsigned char rhbuf[br_sha512_SIZE];
332*5fff9558SSimon J. Gerraty 	char *hex;
333*5fff9558SSimon J. Gerraty 	br_sha256_context ctx;
334*5fff9558SSimon J. Gerraty 	unsigned char *fcp, *scp;
335*5fff9558SSimon J. Gerraty 	size_t flen, slen, plen;
336*5fff9558SSimon J. Gerraty 	pem_object *po;
337*5fff9558SSimon J. Gerraty 	const br_ec_impl *ec;
338*5fff9558SSimon J. Gerraty 	br_ecdsa_vrfy vrfy;
339*5fff9558SSimon J. Gerraty 
340*5fff9558SSimon J. Gerraty 	if ((fcp = read_file(file, &flen)) == NULL)
341*5fff9558SSimon J. Gerraty 		return (NULL);
342*5fff9558SSimon J. Gerraty 	if ((scp = read_file(sigfile, &slen)) == NULL) {
343*5fff9558SSimon J. Gerraty 		free(fcp);
344*5fff9558SSimon J. Gerraty 		return (NULL);
345*5fff9558SSimon J. Gerraty 	}
346*5fff9558SSimon J. Gerraty 	if ((po = decode_pem(scp, slen, &plen)) == NULL) {
347*5fff9558SSimon J. Gerraty 		free(fcp);
348*5fff9558SSimon J. Gerraty 		free(scp);
349*5fff9558SSimon J. Gerraty 		return (NULL);
350*5fff9558SSimon J. Gerraty 	}
351*5fff9558SSimon J. Gerraty 	br_sha256_init(&ctx);
352*5fff9558SSimon J. Gerraty 	br_sha256_update(&ctx, fcp, flen);
353*5fff9558SSimon J. Gerraty 	br_sha256_out(&ctx, rhbuf);
354*5fff9558SSimon J. Gerraty 	hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE);
355*5fff9558SSimon J. Gerraty 	/* now hash that */
356*5fff9558SSimon J. Gerraty 	if (hex) {
357*5fff9558SSimon J. Gerraty 		br_sha256_init(&ctx);
358*5fff9558SSimon J. Gerraty 		br_sha256_update(&ctx, hex, strlen(hex));
359*5fff9558SSimon J. Gerraty 		br_sha256_out(&ctx, rhbuf);
360*5fff9558SSimon J. Gerraty 	}
361*5fff9558SSimon J. Gerraty 	ec = br_ec_get_default();
362*5fff9558SSimon J. Gerraty 	vrfy = br_ecdsa_vrfy_asn1_get_default();
363*5fff9558SSimon J. Gerraty 	if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data,
364*5fff9558SSimon J. Gerraty 		po->data_len)) {
365*5fff9558SSimon J. Gerraty 		free(fcp);
366*5fff9558SSimon J. Gerraty 		fcp = NULL;
367*5fff9558SSimon J. Gerraty 	}
368*5fff9558SSimon J. Gerraty 	free(scp);
369*5fff9558SSimon J. Gerraty 	return (fcp);
370*5fff9558SSimon J. Gerraty }
371*5fff9558SSimon J. Gerraty #endif
372*5fff9558SSimon J. Gerraty 
373*5fff9558SSimon J. Gerraty #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT)
374*5fff9558SSimon J. Gerraty /**
375*5fff9558SSimon J. Gerraty  * @brief verify an rsa digest
376*5fff9558SSimon J. Gerraty  *
377*5fff9558SSimon J. Gerraty  * @return 0 on failure
378*5fff9558SSimon J. Gerraty  */
379*5fff9558SSimon J. Gerraty int
380*5fff9558SSimon J. Gerraty verify_rsa_digest (br_rsa_public_key *pkey,
381*5fff9558SSimon J. Gerraty     const unsigned char *hash_oid,
382*5fff9558SSimon J. Gerraty     unsigned char *mdata, size_t mlen,
383*5fff9558SSimon J. Gerraty     unsigned char *sdata, size_t slen)
384*5fff9558SSimon J. Gerraty {
385*5fff9558SSimon J. Gerraty 	br_rsa_pkcs1_vrfy vrfy;
386*5fff9558SSimon J. Gerraty 	unsigned char vhbuf[br_sha512_SIZE];
387*5fff9558SSimon J. Gerraty 
388*5fff9558SSimon J. Gerraty 	vrfy = br_rsa_pkcs1_vrfy_get_default();
389*5fff9558SSimon J. Gerraty 
390*5fff9558SSimon J. Gerraty 	if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) ||
391*5fff9558SSimon J. Gerraty 	    memcmp(vhbuf, mdata, mlen) != 0) {
392*5fff9558SSimon J. Gerraty 		return (0);		/* fail */
393*5fff9558SSimon J. Gerraty 	}
394*5fff9558SSimon J. Gerraty 	return (1);			/* ok */
395*5fff9558SSimon J. Gerraty }
396*5fff9558SSimon J. Gerraty #endif
397*5fff9558SSimon J. Gerraty 
398*5fff9558SSimon J. Gerraty /**
399*5fff9558SSimon J. Gerraty  * @brief
400*5fff9558SSimon J. Gerraty  * verify file against sigfile using pk
401*5fff9558SSimon J. Gerraty  *
402*5fff9558SSimon J. Gerraty  * When we generated the signature in sigfile,
403*5fff9558SSimon J. Gerraty  * we hashed (sha256) file, and sent that to signing server
404*5fff9558SSimon J. Gerraty  * which hashed (sha256) that hash.
405*5fff9558SSimon J. Gerraty  *
406*5fff9558SSimon J. Gerraty  * Or (deprecated) we simply used sha1 hash directly.
407*5fff9558SSimon J. Gerraty  *
408*5fff9558SSimon J. Gerraty  * To verify we need to replicate that result.
409*5fff9558SSimon J. Gerraty  *
410*5fff9558SSimon J. Gerraty  * @param[in] pk
411*5fff9558SSimon J. Gerraty  *	br_x509_pkey
412*5fff9558SSimon J. Gerraty  *
413*5fff9558SSimon J. Gerraty  * @paramp[in] file
414*5fff9558SSimon J. Gerraty  *	file to be verified
415*5fff9558SSimon J. Gerraty  *
416*5fff9558SSimon J. Gerraty  * @param[in] sigfile
417*5fff9558SSimon J. Gerraty  * 	signature (PEM encoded)
418*5fff9558SSimon J. Gerraty  *
419*5fff9558SSimon J. Gerraty  * @return NULL on error, otherwise content of file.
420*5fff9558SSimon J. Gerraty  */
421*5fff9558SSimon J. Gerraty #ifdef VE_RSA_SUPPORT
422*5fff9558SSimon J. Gerraty static unsigned char *
423*5fff9558SSimon J. Gerraty verify_rsa(br_x509_pkey *pk,  const char *file, const char *sigfile)
424*5fff9558SSimon J. Gerraty {
425*5fff9558SSimon J. Gerraty 	unsigned char rhbuf[br_sha512_SIZE];
426*5fff9558SSimon J. Gerraty 	const unsigned char *hash_oid;
427*5fff9558SSimon J. Gerraty 	const br_hash_class *md;
428*5fff9558SSimon J. Gerraty 	br_hash_compat_context mctx;
429*5fff9558SSimon J. Gerraty 	unsigned char *fcp, *scp;
430*5fff9558SSimon J. Gerraty 	size_t flen, slen, plen, hlen;
431*5fff9558SSimon J. Gerraty 	pem_object *po;
432*5fff9558SSimon J. Gerraty 
433*5fff9558SSimon J. Gerraty 	if ((fcp = read_file(file, &flen)) == NULL)
434*5fff9558SSimon J. Gerraty 		return (NULL);
435*5fff9558SSimon J. Gerraty 	if ((scp = read_file(sigfile, &slen)) == NULL) {
436*5fff9558SSimon J. Gerraty 		free(fcp);
437*5fff9558SSimon J. Gerraty 		return (NULL);
438*5fff9558SSimon J. Gerraty 	}
439*5fff9558SSimon J. Gerraty 	if ((po = decode_pem(scp, slen, &plen)) == NULL) {
440*5fff9558SSimon J. Gerraty 		free(fcp);
441*5fff9558SSimon J. Gerraty 		free(scp);
442*5fff9558SSimon J. Gerraty 		return (NULL);
443*5fff9558SSimon J. Gerraty 	}
444*5fff9558SSimon J. Gerraty 
445*5fff9558SSimon J. Gerraty 	switch (po->data_len) {
446*5fff9558SSimon J. Gerraty #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
447*5fff9558SSimon J. Gerraty 	case 256:
448*5fff9558SSimon J. Gerraty 		// this is our old deprecated sig method
449*5fff9558SSimon J. Gerraty 		md = &br_sha1_vtable;
450*5fff9558SSimon J. Gerraty 		hlen = br_sha1_SIZE;
451*5fff9558SSimon J. Gerraty 		hash_oid = BR_HASH_OID_SHA1;
452*5fff9558SSimon J. Gerraty 		break;
453*5fff9558SSimon J. Gerraty #endif
454*5fff9558SSimon J. Gerraty 	default:
455*5fff9558SSimon J. Gerraty 		md = &br_sha256_vtable;
456*5fff9558SSimon J. Gerraty 		hlen = br_sha256_SIZE;
457*5fff9558SSimon J. Gerraty 		hash_oid = BR_HASH_OID_SHA256;
458*5fff9558SSimon J. Gerraty 		break;
459*5fff9558SSimon J. Gerraty 	}
460*5fff9558SSimon J. Gerraty 	md->init(&mctx.vtable);
461*5fff9558SSimon J. Gerraty 	md->update(&mctx.vtable, fcp, flen);
462*5fff9558SSimon J. Gerraty 	md->out(&mctx.vtable, rhbuf);
463*5fff9558SSimon J. Gerraty 	if (!verify_rsa_digest(&pk->key.rsa, hash_oid,
464*5fff9558SSimon J. Gerraty 		rhbuf, hlen, po->data, po->data_len)) {
465*5fff9558SSimon J. Gerraty 		free(fcp);
466*5fff9558SSimon J. Gerraty 		fcp = NULL;
467*5fff9558SSimon J. Gerraty 	}
468*5fff9558SSimon J. Gerraty 	free(scp);
469*5fff9558SSimon J. Gerraty 	return (fcp);
470*5fff9558SSimon J. Gerraty }
471*5fff9558SSimon J. Gerraty #endif
472*5fff9558SSimon J. Gerraty 
473*5fff9558SSimon J. Gerraty /**
474*5fff9558SSimon J. Gerraty  * @brief
475*5fff9558SSimon J. Gerraty  * verify a signature and return content of signed file
476*5fff9558SSimon J. Gerraty  *
477*5fff9558SSimon J. Gerraty  * @param[in] sigfile
478*5fff9558SSimon J. Gerraty  * 	file containing signature
479*5fff9558SSimon J. Gerraty  * 	we derrive path of signed file and certificate change from
480*5fff9558SSimon J. Gerraty  * 	this.
481*5fff9558SSimon J. Gerraty  *
482*5fff9558SSimon J. Gerraty  * @param[in] flags
483*5fff9558SSimon J. Gerraty  * 	only bit 1 significant so far
484*5fff9558SSimon J. Gerraty  *
485*5fff9558SSimon J. Gerraty  * @return NULL on error otherwise content of signed file
486*5fff9558SSimon J. Gerraty  */
487*5fff9558SSimon J. Gerraty unsigned char *
488*5fff9558SSimon J. Gerraty verify_sig(const char *sigfile, int flags)
489*5fff9558SSimon J. Gerraty {
490*5fff9558SSimon J. Gerraty 	br_x509_pkey *pk;
491*5fff9558SSimon J. Gerraty 	br_name_element cn;
492*5fff9558SSimon J. Gerraty 	char cn_buf[80];
493*5fff9558SSimon J. Gerraty 	unsigned char cn_oid[4];
494*5fff9558SSimon J. Gerraty 	char pbuf[MAXPATHLEN];
495*5fff9558SSimon J. Gerraty 	char *cp;
496*5fff9558SSimon J. Gerraty 	unsigned char *ucp;
497*5fff9558SSimon J. Gerraty 	size_t n;
498*5fff9558SSimon J. Gerraty 
499*5fff9558SSimon J. Gerraty 	DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile));
500*5fff9558SSimon J. Gerraty 	n = strlcpy(pbuf, sigfile, sizeof(pbuf));
501*5fff9558SSimon J. Gerraty 	if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0)
502*5fff9558SSimon J. Gerraty 		return (NULL);
503*5fff9558SSimon J. Gerraty 	cp = strcpy(&pbuf[n - 3], "certs");
504*5fff9558SSimon J. Gerraty 	/*
505*5fff9558SSimon J. Gerraty 	 * We want the commonName field
506*5fff9558SSimon J. Gerraty 	 * the OID we want is 2,5,4,3 - but DER encoded
507*5fff9558SSimon J. Gerraty 	 */
508*5fff9558SSimon J. Gerraty 	cn_oid[0] = 3;
509*5fff9558SSimon J. Gerraty 	cn_oid[1] = 0x55;
510*5fff9558SSimon J. Gerraty 	cn_oid[2] = 4;
511*5fff9558SSimon J. Gerraty 	cn_oid[3] = 3;
512*5fff9558SSimon J. Gerraty 	cn.oid = cn_oid;
513*5fff9558SSimon J. Gerraty 	cn.buf = cn_buf;
514*5fff9558SSimon J. Gerraty 	cn.len = sizeof(cn_buf);
515*5fff9558SSimon J. Gerraty 
516*5fff9558SSimon J. Gerraty 	pk = verify_signer(pbuf, &cn, 1);
517*5fff9558SSimon J. Gerraty 	if (!pk) {
518*5fff9558SSimon J. Gerraty 		printf("cannot verify: %s: %s\n", pbuf, ve_error_get());
519*5fff9558SSimon J. Gerraty 		return (NULL);
520*5fff9558SSimon J. Gerraty 	}
521*5fff9558SSimon J. Gerraty 	for (; cp > pbuf; cp--) {
522*5fff9558SSimon J. Gerraty 		if (*cp == '.') {
523*5fff9558SSimon J. Gerraty 			*cp = '\0';
524*5fff9558SSimon J. Gerraty 			break;
525*5fff9558SSimon J. Gerraty 		}
526*5fff9558SSimon J. Gerraty 	}
527*5fff9558SSimon J. Gerraty 	switch (pk->key_type) {
528*5fff9558SSimon J. Gerraty #ifdef VE_ECDSA_SUPPORT
529*5fff9558SSimon J. Gerraty 	case BR_KEYTYPE_EC:
530*5fff9558SSimon J. Gerraty 		ucp = verify_ec(pk, pbuf, sigfile);
531*5fff9558SSimon J. Gerraty 		break;
532*5fff9558SSimon J. Gerraty #endif
533*5fff9558SSimon J. Gerraty #ifdef VE_RSA_SUPPORT
534*5fff9558SSimon J. Gerraty 	case BR_KEYTYPE_RSA:
535*5fff9558SSimon J. Gerraty 		ucp = verify_rsa(pk, pbuf, sigfile);
536*5fff9558SSimon J. Gerraty 		break;
537*5fff9558SSimon J. Gerraty #endif
538*5fff9558SSimon J. Gerraty 	default:
539*5fff9558SSimon J. Gerraty 		ucp = NULL;		/* not supported */
540*5fff9558SSimon J. Gerraty 	}
541*5fff9558SSimon J. Gerraty 	xfreepkey(pk);
542*5fff9558SSimon J. Gerraty 	if (!ucp) {
543*5fff9558SSimon J. Gerraty 		printf("Unverified %s (%s)\n", pbuf,
544*5fff9558SSimon J. Gerraty 		    cn.status ? cn_buf : "unknown");
545*5fff9558SSimon J. Gerraty 	} else if ((flags & 1) != 0) {
546*5fff9558SSimon J. Gerraty 		printf("Verified %s signed by %s\n", pbuf,
547*5fff9558SSimon J. Gerraty 		    cn.status ? cn_buf : "someone we trust");
548*5fff9558SSimon J. Gerraty 	}
549*5fff9558SSimon J. Gerraty 	return (ucp);
550*5fff9558SSimon J. Gerraty }
551*5fff9558SSimon J. Gerraty 
552*5fff9558SSimon J. Gerraty 
553*5fff9558SSimon J. Gerraty /**
554*5fff9558SSimon J. Gerraty  * @brief verify hash matches
555*5fff9558SSimon J. Gerraty  *
556*5fff9558SSimon J. Gerraty  * We have finished hashing a file,
557*5fff9558SSimon J. Gerraty  * see if we got the desired result.
558*5fff9558SSimon J. Gerraty  *
559*5fff9558SSimon J. Gerraty  * @param[in] ctx
560*5fff9558SSimon J. Gerraty  *	pointer to hash context
561*5fff9558SSimon J. Gerraty  *
562*5fff9558SSimon J. Gerraty  * @param[in] md
563*5fff9558SSimon J. Gerraty  *	pointer to hash class
564*5fff9558SSimon J. Gerraty  *
565*5fff9558SSimon J. Gerraty  * @param[in] path
566*5fff9558SSimon J. Gerraty  *	name of the file we are checking
567*5fff9558SSimon J. Gerraty  *
568*5fff9558SSimon J. Gerraty  * @param[in] want
569*5fff9558SSimon J. Gerraty  *	the expected result
570*5fff9558SSimon J. Gerraty  *
571*5fff9558SSimon J. Gerraty  * @param[in] hlen
572*5fff9558SSimon J. Gerraty  *	size of hash output
573*5fff9558SSimon J. Gerraty  *
574*5fff9558SSimon J. Gerraty  * @return 0 on success
575*5fff9558SSimon J. Gerraty  */
576*5fff9558SSimon J. Gerraty int
577*5fff9558SSimon J. Gerraty ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md,
578*5fff9558SSimon J. Gerraty     const char *path, const char *want, size_t hlen)
579*5fff9558SSimon J. Gerraty {
580*5fff9558SSimon J. Gerraty 	char hexbuf[br_sha512_SIZE * 2 + 2];
581*5fff9558SSimon J. Gerraty 	unsigned char hbuf[br_sha512_SIZE];
582*5fff9558SSimon J. Gerraty 	char *hex;
583*5fff9558SSimon J. Gerraty 	int rc;
584*5fff9558SSimon J. Gerraty 	int n;
585*5fff9558SSimon J. Gerraty 
586*5fff9558SSimon J. Gerraty 	md->out(&ctx->vtable, hbuf);
587*5fff9558SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
588*5fff9558SSimon J. Gerraty 	ve_pcr_update(hbuf, hlen);
589*5fff9558SSimon J. Gerraty #endif
590*5fff9558SSimon J. Gerraty 	hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen);
591*5fff9558SSimon J. Gerraty 	if (!hex)
592*5fff9558SSimon J. Gerraty 		return (VE_FINGERPRINT_WRONG);
593*5fff9558SSimon J. Gerraty 	n = 2*hlen;
594*5fff9558SSimon J. Gerraty 	if ((rc = strncmp(hex, want, n))) {
595*5fff9558SSimon J. Gerraty 		ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want);
596*5fff9558SSimon J. Gerraty 		rc = VE_FINGERPRINT_WRONG;
597*5fff9558SSimon J. Gerraty 	}
598*5fff9558SSimon J. Gerraty 	return (rc ? rc : VE_FINGERPRINT_OK);
599*5fff9558SSimon J. Gerraty }
600*5fff9558SSimon J. Gerraty 
601*5fff9558SSimon J. Gerraty #ifdef VE_HASH_KAT_STR
602*5fff9558SSimon J. Gerraty static int
603*5fff9558SSimon J. Gerraty test_hash(const br_hash_class *md, size_t hlen,
604*5fff9558SSimon J. Gerraty     const char *hname, const char *s, size_t slen, const char *want)
605*5fff9558SSimon J. Gerraty {
606*5fff9558SSimon J. Gerraty 	br_hash_compat_context mctx;
607*5fff9558SSimon J. Gerraty 
608*5fff9558SSimon J. Gerraty 	md->init(&mctx.vtable);
609*5fff9558SSimon J. Gerraty 	md->update(&mctx.vtable, s, slen);
610*5fff9558SSimon J. Gerraty 	return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK);
611*5fff9558SSimon J. Gerraty }
612*5fff9558SSimon J. Gerraty 
613*5fff9558SSimon J. Gerraty #endif
614*5fff9558SSimon J. Gerraty 
615*5fff9558SSimon J. Gerraty #define ve_test_hash(n, N) \
616*5fff9558SSimon J. Gerraty 	printf("Testing hash: " #n "\t\t\t\t%s\n", \
617*5fff9558SSimon J. Gerraty 	    test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \
618*5fff9558SSimon J. Gerraty 	    VE_HASH_KAT_STR, sizeof(VE_HASH_KAT_STR), \
619*5fff9558SSimon J. Gerraty 	    vh_ ## N) ? "Failed" : "Passed")
620*5fff9558SSimon J. Gerraty 
621*5fff9558SSimon J. Gerraty /**
622*5fff9558SSimon J. Gerraty  * @brief
623*5fff9558SSimon J. Gerraty  * run self tests on hash and signature verification
624*5fff9558SSimon J. Gerraty  *
625*5fff9558SSimon J. Gerraty  * Test that the hash methods (SHA1 and SHA256) work.
626*5fff9558SSimon J. Gerraty  * Test that we can verify a certificate for each supported
627*5fff9558SSimon J. Gerraty  * Root CA.
628*5fff9558SSimon J. Gerraty  *
629*5fff9558SSimon J. Gerraty  * @return cached result.
630*5fff9558SSimon J. Gerraty  */
631*5fff9558SSimon J. Gerraty int
632*5fff9558SSimon J. Gerraty ve_self_tests(void)
633*5fff9558SSimon J. Gerraty {
634*5fff9558SSimon J. Gerraty 	static int once = -1;
635*5fff9558SSimon J. Gerraty #ifdef VERIFY_CERTS_STR
636*5fff9558SSimon J. Gerraty 	br_x509_certificate *xcs;
637*5fff9558SSimon J. Gerraty 	br_x509_pkey *pk;
638*5fff9558SSimon J. Gerraty 	br_name_element cn;
639*5fff9558SSimon J. Gerraty 	char cn_buf[80];
640*5fff9558SSimon J. Gerraty 	unsigned char cn_oid[4];
641*5fff9558SSimon J. Gerraty 	size_t num;
642*5fff9558SSimon J. Gerraty 	size_t u;
643*5fff9558SSimon J. Gerraty #endif
644*5fff9558SSimon J. Gerraty 
645*5fff9558SSimon J. Gerraty 	if (once >= 0)
646*5fff9558SSimon J. Gerraty 		return (once);
647*5fff9558SSimon J. Gerraty 	once = 0;
648*5fff9558SSimon J. Gerraty 
649*5fff9558SSimon J. Gerraty 	DEBUG_PRINTF(5, ("Self tests...\n"));
650*5fff9558SSimon J. Gerraty #ifdef VE_HASH_KAT_STR
651*5fff9558SSimon J. Gerraty #ifdef VE_SHA1_SUPPORT
652*5fff9558SSimon J. Gerraty 	ve_test_hash(sha1, SHA1);
653*5fff9558SSimon J. Gerraty #endif
654*5fff9558SSimon J. Gerraty #ifdef VE_SHA256_SUPPORT
655*5fff9558SSimon J. Gerraty 	ve_test_hash(sha256, SHA256);
656*5fff9558SSimon J. Gerraty #endif
657*5fff9558SSimon J. Gerraty #ifdef VE_SHA384_SUPPORT
658*5fff9558SSimon J. Gerraty 	ve_test_hash(sha384, SHA384);
659*5fff9558SSimon J. Gerraty #endif
660*5fff9558SSimon J. Gerraty #ifdef VE_SHA512_SUPPORT
661*5fff9558SSimon J. Gerraty 	ve_test_hash(sha512, SHA512);
662*5fff9558SSimon J. Gerraty #endif
663*5fff9558SSimon J. Gerraty #endif
664*5fff9558SSimon J. Gerraty #ifdef VERIFY_CERTS_STR
665*5fff9558SSimon J. Gerraty 	xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR),
666*5fff9558SSimon J. Gerraty 	    sizeof(VERIFY_CERTS_STR), &num);
667*5fff9558SSimon J. Gerraty 	if (xcs == NULL)
668*5fff9558SSimon J. Gerraty 		return (0);
669*5fff9558SSimon J. Gerraty 	/*
670*5fff9558SSimon J. Gerraty 	 * We want the commonName field
671*5fff9558SSimon J. Gerraty 	 * the OID we want is 2,5,4,3 - but DER encoded
672*5fff9558SSimon J. Gerraty 	 */
673*5fff9558SSimon J. Gerraty 	cn_oid[0] = 3;
674*5fff9558SSimon J. Gerraty 	cn_oid[1] = 0x55;
675*5fff9558SSimon J. Gerraty 	cn_oid[2] = 4;
676*5fff9558SSimon J. Gerraty 	cn_oid[3] = 3;
677*5fff9558SSimon J. Gerraty 	cn.oid = cn_oid;
678*5fff9558SSimon J. Gerraty 	cn.buf = cn_buf;
679*5fff9558SSimon J. Gerraty 
680*5fff9558SSimon J. Gerraty 	for (u = 0; u < num; u ++) {
681*5fff9558SSimon J. Gerraty 		cn.len = sizeof(cn_buf);
682*5fff9558SSimon J. Gerraty 		if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1)) != NULL) {
683*5fff9558SSimon J. Gerraty 			once++;
684*5fff9558SSimon J. Gerraty 			printf("Testing verify certificate: %s\tPassed\n",
685*5fff9558SSimon J. Gerraty 			    cn.status ? cn_buf : "");
686*5fff9558SSimon J. Gerraty 			xfreepkey(pk);
687*5fff9558SSimon J. Gerraty 		}
688*5fff9558SSimon J. Gerraty 	}
689*5fff9558SSimon J. Gerraty 	if (!once)
690*5fff9558SSimon J. Gerraty 		printf("Testing verify certificate:\t\t\tFailed\n");
691*5fff9558SSimon J. Gerraty 	xfree(xcs);
692*5fff9558SSimon J. Gerraty #else
693*5fff9558SSimon J. Gerraty 	printf("No X.509 self tests\n");
694*5fff9558SSimon J. Gerraty #endif	/* VERIFY_CERTS_STR */
695*5fff9558SSimon J. Gerraty #ifdef VE_OPENPGP_SUPPORT
696*5fff9558SSimon J. Gerraty 	if (!openpgp_self_tests())
697*5fff9558SSimon J. Gerraty 		once++;
698*5fff9558SSimon J. Gerraty #endif
699*5fff9558SSimon J. Gerraty 	return (once);
700*5fff9558SSimon J. Gerraty }
701