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