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