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 SECONDS_PER_DAY 86400 47 #define X509_DAYS_TO_UTC0 719528 48 49 int DebugVe = 0; 50 51 typedef VECTOR(br_x509_certificate) cert_list; 52 53 static anchor_list trust_anchors = VEC_INIT; 54 55 void 56 ve_debug_set(int n) 57 { 58 DebugVe = n; 59 } 60 61 static char ebuf[512]; 62 63 char * 64 ve_error_get(void) 65 { 66 return (ebuf); 67 } 68 69 int 70 ve_error_set(const char *fmt, ...) 71 { 72 int rc; 73 va_list ap; 74 75 va_start(ap, fmt); 76 ebuf[0] = '\0'; 77 rc = 0; 78 if (fmt) { 79 #ifdef STAND_H 80 vsprintf(ebuf, fmt, ap); /* no vsnprintf in libstand */ 81 ebuf[sizeof(ebuf) - 1] = '\0'; 82 rc = strlen(ebuf); 83 #else 84 rc = vsnprintf(ebuf, sizeof(ebuf), fmt, ap); 85 #endif 86 } 87 va_end(ap); 88 return (rc); 89 } 90 91 /* this is the time we use for verifying certs */ 92 static time_t ve_utc = 0; 93 94 /** 95 * @brief 96 * set ve_utc used for certificate verification 97 * 98 * @param[in] utc 99 * time - ignored unless greater than current value. 100 */ 101 void 102 ve_utc_set(time_t utc) 103 { 104 if (utc > ve_utc) { 105 DEBUG_PRINTF(2, ("Set ve_utc=%jd\n", (intmax_t)utc)); 106 ve_utc = utc; 107 } 108 } 109 110 static void 111 free_cert_contents(br_x509_certificate *xc) 112 { 113 xfree(xc->data); 114 } 115 116 /** 117 * @brief 118 * add certs to our trust store 119 */ 120 size_t 121 ve_trust_anchors_add(br_x509_certificate *xcs, size_t num) 122 { 123 br_x509_trust_anchor ta; 124 size_t u; 125 126 for (u = 0; u < num; u++) { 127 if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) { 128 break; 129 } 130 VEC_ADD(trust_anchors, ta); 131 } 132 return (u); 133 } 134 135 /** 136 * @brief 137 * initialize our trust_anchors from ta_PEM 138 */ 139 int 140 ve_trust_init(void) 141 { 142 br_x509_certificate *xcs; 143 static int once = -1; 144 size_t num; 145 146 if (once >= 0) 147 return (once); 148 once = 0; 149 150 ve_utc_set(time(NULL)); 151 #ifdef BUILD_UTC 152 ve_utc_set(BUILD_UTC); /* just in case */ 153 #endif 154 ve_error_set(NULL); /* make sure it is empty */ 155 #ifdef VE_PCR_SUPPORT 156 ve_pcr_init(); 157 #endif 158 159 #ifdef TRUST_ANCHOR_STR 160 xcs = parse_certificates(__DECONST(unsigned char *, TRUST_ANCHOR_STR), 161 sizeof(TRUST_ANCHOR_STR), &num); 162 if (xcs == NULL) 163 return (0); 164 num = ve_trust_anchors_add(xcs, num); 165 once = (int) num; 166 #else 167 num = 0; 168 #endif 169 return (num); 170 } 171 172 /** 173 * if we can verify the certificate chain in "certs", 174 * return the public key and if "xcp" is !NULL the associated 175 * certificate 176 */ 177 static br_x509_pkey * 178 verify_signer_xcs(br_x509_certificate *xcs, 179 size_t num, 180 br_name_element *elts, size_t num_elts) 181 { 182 br_x509_minimal_context mc; 183 br_x509_certificate *xc; 184 size_t u; 185 cert_list chain = VEC_INIT; 186 const br_x509_pkey *tpk; 187 br_x509_pkey *pk; 188 unsigned int usages; 189 int err; 190 191 DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num)); 192 VEC_ADDMANY(chain, xcs, num); 193 if (VEC_LEN(chain) == 0) { 194 ve_error_set("ERROR: no/invalid certificate chain\n"); 195 return (NULL); 196 } 197 198 DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n", 199 VEC_LEN(trust_anchors))); 200 201 br_x509_minimal_init(&mc, &br_sha256_vtable, 202 &VEC_ELT(trust_anchors, 0), 203 VEC_LEN(trust_anchors)); 204 #ifdef VE_ECDSA_SUPPORT 205 br_x509_minimal_set_ecdsa(&mc, 206 &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); 207 #endif 208 #ifdef VE_RSA_SUPPORT 209 br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy); 210 #endif 211 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT) 212 /* This is deprecated! do not enable unless you absoultely have to */ 213 br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable); 214 #endif 215 br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable); 216 #ifdef VE_SHA384_SUPPORT 217 br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable); 218 #endif 219 #ifdef VE_SHA512_SUPPORT 220 br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable); 221 #endif 222 br_x509_minimal_set_name_elements(&mc, elts, num_elts); 223 224 #ifdef _STANDALONE 225 /* 226 * Clock is probably bogus so we use ve_utc. 227 */ 228 mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0; 229 mc.seconds = (ve_utc % SECONDS_PER_DAY); 230 #endif 231 232 mc.vtable->start_chain(&mc.vtable, NULL); 233 for (u = 0; u < VEC_LEN(chain); u ++) { 234 xc = &VEC_ELT(chain, u); 235 mc.vtable->start_cert(&mc.vtable, xc->data_len); 236 mc.vtable->append(&mc.vtable, xc->data, xc->data_len); 237 mc.vtable->end_cert(&mc.vtable); 238 switch (mc.err) { 239 case 0: 240 case BR_ERR_X509_OK: 241 case BR_ERR_X509_EXPIRED: 242 break; 243 default: 244 printf("u=%zu mc.err=%d\n", u, mc.err); 245 break; 246 } 247 } 248 err = mc.vtable->end_chain(&mc.vtable); 249 pk = NULL; 250 if (err) { 251 ve_error_set("Validation failed, err = %d", err); 252 } else { 253 tpk = mc.vtable->get_pkey(&mc.vtable, &usages); 254 if (tpk != NULL) { 255 pk = xpkeydup(tpk); 256 } 257 } 258 VEC_CLEAREXT(chain, &free_cert_contents); 259 return (pk); 260 } 261 262 static br_x509_pkey * 263 verify_signer(const char *certs, 264 br_name_element *elts, size_t num_elts) 265 { 266 br_x509_certificate *xcs; 267 br_x509_pkey *pk; 268 size_t num; 269 270 ve_trust_init(); 271 xcs = read_certificates(certs, &num); 272 if (xcs == NULL) { 273 ve_error_set("cannot read certificates\n"); 274 return (NULL); 275 } 276 pk = verify_signer_xcs(xcs, num, elts, num_elts); 277 xfree(xcs); 278 return (pk); 279 } 280 281 /** 282 * we need a hex digest including trailing newline below 283 */ 284 char * 285 hexdigest(char *buf, size_t bufsz, unsigned char *foo, size_t foo_len) 286 { 287 char const hex2ascii[] = "0123456789abcdef"; 288 size_t i; 289 290 /* every binary byte is 2 chars in hex + newline + null */ 291 if (bufsz < (2 * foo_len) + 2) 292 return (NULL); 293 294 for (i = 0; i < foo_len; i++) { 295 buf[i * 2] = hex2ascii[foo[i] >> 4]; 296 buf[i * 2 + 1] = hex2ascii[foo[i] & 0x0f]; 297 } 298 299 buf[i * 2] = 0x0A; /* we also want a newline */ 300 buf[i * 2 + 1] = '\0'; 301 302 return (buf); 303 } 304 305 /** 306 * @brief 307 * verify file against sigfile using pk 308 * 309 * When we generated the signature in sigfile, 310 * we hashed (sha256) file, and sent that to signing server 311 * which hashed (sha256) that hash. 312 * 313 * To verify we need to replicate that result. 314 * 315 * @param[in] pk 316 * br_x509_pkey 317 * 318 * @paramp[in] file 319 * file to be verified 320 * 321 * @param[in] sigfile 322 * signature (PEM encoded) 323 * 324 * @return NULL on error, otherwise content of file. 325 */ 326 #ifdef VE_ECDSA_SUPPORT 327 static unsigned char * 328 verify_ec(br_x509_pkey *pk, const char *file, const char *sigfile) 329 { 330 char hexbuf[br_sha512_SIZE * 2 + 2]; 331 unsigned char rhbuf[br_sha512_SIZE]; 332 char *hex; 333 br_sha256_context ctx; 334 unsigned char *fcp, *scp; 335 size_t flen, slen, plen; 336 pem_object *po; 337 const br_ec_impl *ec; 338 br_ecdsa_vrfy vrfy; 339 340 if ((fcp = read_file(file, &flen)) == NULL) 341 return (NULL); 342 if ((scp = read_file(sigfile, &slen)) == NULL) { 343 free(fcp); 344 return (NULL); 345 } 346 if ((po = decode_pem(scp, slen, &plen)) == NULL) { 347 free(fcp); 348 free(scp); 349 return (NULL); 350 } 351 br_sha256_init(&ctx); 352 br_sha256_update(&ctx, fcp, flen); 353 br_sha256_out(&ctx, rhbuf); 354 hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE); 355 /* now hash that */ 356 if (hex) { 357 br_sha256_init(&ctx); 358 br_sha256_update(&ctx, hex, strlen(hex)); 359 br_sha256_out(&ctx, rhbuf); 360 } 361 ec = br_ec_get_default(); 362 vrfy = br_ecdsa_vrfy_asn1_get_default(); 363 if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data, 364 po->data_len)) { 365 free(fcp); 366 fcp = NULL; 367 } 368 free(scp); 369 return (fcp); 370 } 371 #endif 372 373 #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT) 374 /** 375 * @brief verify an rsa digest 376 * 377 * @return 0 on failure 378 */ 379 int 380 verify_rsa_digest (br_rsa_public_key *pkey, 381 const unsigned char *hash_oid, 382 unsigned char *mdata, size_t mlen, 383 unsigned char *sdata, size_t slen) 384 { 385 br_rsa_pkcs1_vrfy vrfy; 386 unsigned char vhbuf[br_sha512_SIZE]; 387 388 vrfy = br_rsa_pkcs1_vrfy_get_default(); 389 390 if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) || 391 memcmp(vhbuf, mdata, mlen) != 0) { 392 return (0); /* fail */ 393 } 394 return (1); /* ok */ 395 } 396 #endif 397 398 /** 399 * @brief 400 * verify file against sigfile using pk 401 * 402 * When we generated the signature in sigfile, 403 * we hashed (sha256) file, and sent that to signing server 404 * which hashed (sha256) that hash. 405 * 406 * Or (deprecated) we simply used sha1 hash directly. 407 * 408 * To verify we need to replicate that result. 409 * 410 * @param[in] pk 411 * br_x509_pkey 412 * 413 * @paramp[in] file 414 * file to be verified 415 * 416 * @param[in] sigfile 417 * signature (PEM encoded) 418 * 419 * @return NULL on error, otherwise content of file. 420 */ 421 #ifdef VE_RSA_SUPPORT 422 static unsigned char * 423 verify_rsa(br_x509_pkey *pk, const char *file, const char *sigfile) 424 { 425 unsigned char rhbuf[br_sha512_SIZE]; 426 const unsigned char *hash_oid; 427 const br_hash_class *md; 428 br_hash_compat_context mctx; 429 unsigned char *fcp, *scp; 430 size_t flen, slen, plen, hlen; 431 pem_object *po; 432 433 if ((fcp = read_file(file, &flen)) == NULL) 434 return (NULL); 435 if ((scp = read_file(sigfile, &slen)) == NULL) { 436 free(fcp); 437 return (NULL); 438 } 439 if ((po = decode_pem(scp, slen, &plen)) == NULL) { 440 free(fcp); 441 free(scp); 442 return (NULL); 443 } 444 445 switch (po->data_len) { 446 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT) 447 case 256: 448 // this is our old deprecated sig method 449 md = &br_sha1_vtable; 450 hlen = br_sha1_SIZE; 451 hash_oid = BR_HASH_OID_SHA1; 452 break; 453 #endif 454 default: 455 md = &br_sha256_vtable; 456 hlen = br_sha256_SIZE; 457 hash_oid = BR_HASH_OID_SHA256; 458 break; 459 } 460 md->init(&mctx.vtable); 461 md->update(&mctx.vtable, fcp, flen); 462 md->out(&mctx.vtable, rhbuf); 463 if (!verify_rsa_digest(&pk->key.rsa, hash_oid, 464 rhbuf, hlen, po->data, po->data_len)) { 465 free(fcp); 466 fcp = NULL; 467 } 468 free(scp); 469 return (fcp); 470 } 471 #endif 472 473 /** 474 * @brief 475 * verify a signature and return content of signed file 476 * 477 * @param[in] sigfile 478 * file containing signature 479 * we derrive path of signed file and certificate change from 480 * this. 481 * 482 * @param[in] flags 483 * only bit 1 significant so far 484 * 485 * @return NULL on error otherwise content of signed file 486 */ 487 unsigned char * 488 verify_sig(const char *sigfile, int flags) 489 { 490 br_x509_pkey *pk; 491 br_name_element cn; 492 char cn_buf[80]; 493 unsigned char cn_oid[4]; 494 char pbuf[MAXPATHLEN]; 495 char *cp; 496 unsigned char *ucp; 497 size_t n; 498 499 DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile)); 500 n = strlcpy(pbuf, sigfile, sizeof(pbuf)); 501 if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0) 502 return (NULL); 503 cp = strcpy(&pbuf[n - 3], "certs"); 504 /* 505 * We want the commonName field 506 * the OID we want is 2,5,4,3 - but DER encoded 507 */ 508 cn_oid[0] = 3; 509 cn_oid[1] = 0x55; 510 cn_oid[2] = 4; 511 cn_oid[3] = 3; 512 cn.oid = cn_oid; 513 cn.buf = cn_buf; 514 cn.len = sizeof(cn_buf); 515 516 pk = verify_signer(pbuf, &cn, 1); 517 if (!pk) { 518 printf("cannot verify: %s: %s\n", pbuf, ve_error_get()); 519 return (NULL); 520 } 521 for (; cp > pbuf; cp--) { 522 if (*cp == '.') { 523 *cp = '\0'; 524 break; 525 } 526 } 527 switch (pk->key_type) { 528 #ifdef VE_ECDSA_SUPPORT 529 case BR_KEYTYPE_EC: 530 ucp = verify_ec(pk, pbuf, sigfile); 531 break; 532 #endif 533 #ifdef VE_RSA_SUPPORT 534 case BR_KEYTYPE_RSA: 535 ucp = verify_rsa(pk, pbuf, sigfile); 536 break; 537 #endif 538 default: 539 ucp = NULL; /* not supported */ 540 } 541 xfreepkey(pk); 542 if (!ucp) { 543 printf("Unverified %s (%s)\n", pbuf, 544 cn.status ? cn_buf : "unknown"); 545 } else if ((flags & 1) != 0) { 546 printf("Verified %s signed by %s\n", pbuf, 547 cn.status ? cn_buf : "someone we trust"); 548 } 549 return (ucp); 550 } 551 552 553 /** 554 * @brief verify hash matches 555 * 556 * We have finished hashing a file, 557 * see if we got the desired result. 558 * 559 * @param[in] ctx 560 * pointer to hash context 561 * 562 * @param[in] md 563 * pointer to hash class 564 * 565 * @param[in] path 566 * name of the file we are checking 567 * 568 * @param[in] want 569 * the expected result 570 * 571 * @param[in] hlen 572 * size of hash output 573 * 574 * @return 0 on success 575 */ 576 int 577 ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md, 578 const char *path, const char *want, size_t hlen) 579 { 580 char hexbuf[br_sha512_SIZE * 2 + 2]; 581 unsigned char hbuf[br_sha512_SIZE]; 582 char *hex; 583 int rc; 584 int n; 585 586 md->out(&ctx->vtable, hbuf); 587 #ifdef VE_PCR_SUPPORT 588 ve_pcr_update(hbuf, hlen); 589 #endif 590 hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen); 591 if (!hex) 592 return (VE_FINGERPRINT_WRONG); 593 n = 2*hlen; 594 if ((rc = strncmp(hex, want, n))) { 595 ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want); 596 rc = VE_FINGERPRINT_WRONG; 597 } 598 return (rc ? rc : VE_FINGERPRINT_OK); 599 } 600 601 #ifdef VE_HASH_KAT_STR 602 static int 603 test_hash(const br_hash_class *md, size_t hlen, 604 const char *hname, const char *s, size_t slen, const char *want) 605 { 606 br_hash_compat_context mctx; 607 608 md->init(&mctx.vtable); 609 md->update(&mctx.vtable, s, slen); 610 return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK); 611 } 612 613 #endif 614 615 #define ve_test_hash(n, N) \ 616 printf("Testing hash: " #n "\t\t\t\t%s\n", \ 617 test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \ 618 VE_HASH_KAT_STR, sizeof(VE_HASH_KAT_STR), \ 619 vh_ ## N) ? "Failed" : "Passed") 620 621 /** 622 * @brief 623 * run self tests on hash and signature verification 624 * 625 * Test that the hash methods (SHA1 and SHA256) work. 626 * Test that we can verify a certificate for each supported 627 * Root CA. 628 * 629 * @return cached result. 630 */ 631 int 632 ve_self_tests(void) 633 { 634 static int once = -1; 635 #ifdef VERIFY_CERTS_STR 636 br_x509_certificate *xcs; 637 br_x509_pkey *pk; 638 br_name_element cn; 639 char cn_buf[80]; 640 unsigned char cn_oid[4]; 641 size_t num; 642 size_t u; 643 #endif 644 645 if (once >= 0) 646 return (once); 647 once = 0; 648 649 DEBUG_PRINTF(5, ("Self tests...\n")); 650 #ifdef VE_HASH_KAT_STR 651 #ifdef VE_SHA1_SUPPORT 652 ve_test_hash(sha1, SHA1); 653 #endif 654 #ifdef VE_SHA256_SUPPORT 655 ve_test_hash(sha256, SHA256); 656 #endif 657 #ifdef VE_SHA384_SUPPORT 658 ve_test_hash(sha384, SHA384); 659 #endif 660 #ifdef VE_SHA512_SUPPORT 661 ve_test_hash(sha512, SHA512); 662 #endif 663 #endif 664 #ifdef VERIFY_CERTS_STR 665 xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR), 666 sizeof(VERIFY_CERTS_STR), &num); 667 if (xcs == NULL) 668 return (0); 669 /* 670 * We want the commonName field 671 * the OID we want is 2,5,4,3 - but DER encoded 672 */ 673 cn_oid[0] = 3; 674 cn_oid[1] = 0x55; 675 cn_oid[2] = 4; 676 cn_oid[3] = 3; 677 cn.oid = cn_oid; 678 cn.buf = cn_buf; 679 680 for (u = 0; u < num; u ++) { 681 cn.len = sizeof(cn_buf); 682 if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1)) != NULL) { 683 once++; 684 printf("Testing verify certificate: %s\tPassed\n", 685 cn.status ? cn_buf : ""); 686 xfreepkey(pk); 687 } 688 } 689 if (!once) 690 printf("Testing verify certificate:\t\t\tFailed\n"); 691 xfree(xcs); 692 #else 693 printf("No X.509 self tests\n"); 694 #endif /* VERIFY_CERTS_STR */ 695 #ifdef VE_OPENPGP_SUPPORT 696 if (!openpgp_self_tests()) 697 once++; 698 #endif 699 return (once); 700 } 701