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