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