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