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