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