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 static void 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 * 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* 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 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 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 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 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 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 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 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 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 * 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 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 * 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 * 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 * 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 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 * 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 * 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 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 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 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