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