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
53 int DebugVe = 0;
54
55 #ifndef VE_VERIFY_FLAGS
56 # define VE_VERIFY_FLAGS VEF_VERBOSE
57 #endif
58 int VerifyFlags = VE_VERIFY_FLAGS;
59
60 typedef VECTOR(br_x509_certificate) cert_list;
61 typedef VECTOR(hash_data) digest_list;
62
63 static anchor_list trust_anchors = VEC_INIT;
64 static anchor_list forbidden_anchors = VEC_INIT;
65 static digest_list forbidden_digests = VEC_INIT;
66
67 static int anchor_verbose = 0;
68
69 void
ve_anchor_verbose_set(int n)70 ve_anchor_verbose_set(int n)
71 {
72 anchor_verbose = n;
73 }
74
75 int
ve_anchor_verbose_get(void)76 ve_anchor_verbose_get(void)
77 {
78 return (anchor_verbose);
79 }
80
81 void
ve_debug_set(int n)82 ve_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 */
93 static int enforce_validity = 0;
94
95 void
ve_enforce_validity_set(int i)96 ve_enforce_validity_set(int i)
97 {
98 enforce_validity = i;
99 }
100
101 static char ebuf[512];
102
103 char *
ve_error_get(void)104 ve_error_get(void)
105 {
106 return (ebuf);
107 }
108
109 int
ve_error_set(const char * fmt,...)110 ve_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 */
142 static const char *
gdate(char * buf,size_t bufsz,time_t clock)143 gdate(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
179 extern time_t ve_utc;
180 time_t ve_utc = 0;
181 #else
182 static 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 */
193 void
ve_utc_set(time_t utc)194 ve_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
203 static void
free_cert_contents(br_x509_certificate * xc)204 free_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 */
212 static char *
x509_cn_get(br_x509_certificate * xc,char * buf,size_t len)213 x509_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 */
261 static void*
X509_to_tbs(unsigned char * cert,size_t * output_size)262 X509_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
311 void
ve_forbidden_digest_add(hash_data * digest,size_t num)312 ve_forbidden_digest_add(hash_data *digest, size_t num)
313 {
314 while (num--)
315 VEC_ADD(forbidden_digests, digest[num]);
316 }
317
318 static size_t
ve_anchors_add(br_x509_certificate * xcs,size_t num,anchor_list * anchors,const char * anchors_name)319 ve_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 */
347 size_t
ve_trust_anchors_add(br_x509_certificate * xcs,size_t num)348 ve_trust_anchors_add(br_x509_certificate *xcs, size_t num)
349 {
350 return (ve_anchors_add(xcs, num, &trust_anchors, "trusted"));
351 }
352
353 size_t
ve_forbidden_anchors_add(br_x509_certificate * xcs,size_t num)354 ve_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 */
368 size_t
ve_trust_anchors_add_buf(unsigned char * buf,size_t len)369 ve_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 */
394 size_t
ve_trust_anchors_revoke(unsigned char * buf,size_t len)395 ve_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 */
418 int
ve_trust_init(void)419 ve_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
448 static int
verify_time_cb(void * tctx __unused,uint32_t not_before_days,uint32_t not_before_seconds,uint32_t not_after_days,uint32_t not_after_seconds)449 verify_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 */
486 static br_x509_pkey *
verify_signer_xcs(br_x509_certificate * xcs,size_t num,br_name_element * elts,size_t num_elts,anchor_list * anchors)487 verify_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 */
599 static int
check_forbidden_digests(br_x509_certificate * xcs,size_t num)600 check_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
679 static br_x509_pkey *
verify_signer(const char * certs,br_name_element * elts,size_t num_elts)680 verify_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 }
724 out:
725 free_certificates(xcs, num);
726 return (pk);
727 }
728
729 /**
730 * we need a hex digest including trailing newline below
731 */
732 char *
hexdigest(char * buf,size_t bufsz,unsigned char * foo,size_t foo_len)733 hexdigest(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
775 static unsigned char *
verify_ec(br_x509_pkey * pk,const char * file,const char * sigfile)776 verify_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 */
830 int
verify_rsa_digest(br_rsa_public_key * pkey,const unsigned char * hash_oid,unsigned char * mdata,size_t mlen,unsigned char * sdata,size_t slen)831 verify_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
873 static unsigned char *
verify_rsa(br_x509_pkey * pk,const char * file,const char * sigfile)874 verify_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 */
938 unsigned char *
verify_sig(const char * sigfile,int flags)939 verify_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 */
1027 int
ve_check_hash(br_hash_compat_context * ctx,const br_hash_class * md,const char * path,const char * want,size_t hlen)1028 ve_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
1053 static int
test_hash(const br_hash_class * md,size_t hlen,const char * hname,const char * s,size_t slen,const char * want)1054 test_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 */
1082 int
ve_self_tests(void)1083 ve_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