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 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 char hexbuf[br_sha512_SIZE * 2 + 2]; 646 unsigned char rhbuf[br_sha512_SIZE]; 647 char *hex; 648 br_sha256_context ctx; 649 unsigned char *fcp, *scp; 650 size_t flen, slen, plen; 651 pem_object *po; 652 const br_ec_impl *ec; 653 br_ecdsa_vrfy vrfy; 654 655 if ((fcp = read_file(file, &flen)) == NULL) 656 return (NULL); 657 if ((scp = read_file(sigfile, &slen)) == NULL) { 658 free(fcp); 659 return (NULL); 660 } 661 if ((po = decode_pem(scp, slen, &plen)) == NULL) { 662 free(fcp); 663 free(scp); 664 return (NULL); 665 } 666 br_sha256_init(&ctx); 667 br_sha256_update(&ctx, fcp, flen); 668 br_sha256_out(&ctx, rhbuf); 669 #ifdef VE_ECDSA_HASH_AGAIN 670 hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE); 671 /* now hash that */ 672 if (hex) { 673 br_sha256_init(&ctx); 674 br_sha256_update(&ctx, hex, strlen(hex)); 675 br_sha256_out(&ctx, rhbuf); 676 } 677 #endif 678 ec = br_ec_get_default(); 679 vrfy = br_ecdsa_vrfy_asn1_get_default(); 680 if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data, 681 po->data_len)) { 682 free(fcp); 683 fcp = NULL; 684 } 685 free(scp); 686 return (fcp); 687 } 688 #endif 689 690 #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT) 691 /** 692 * @brief verify an rsa digest 693 * 694 * @return 0 on failure 695 */ 696 int 697 verify_rsa_digest (br_rsa_public_key *pkey, 698 const unsigned char *hash_oid, 699 unsigned char *mdata, size_t mlen, 700 unsigned char *sdata, size_t slen) 701 { 702 br_rsa_pkcs1_vrfy vrfy; 703 unsigned char vhbuf[br_sha512_SIZE]; 704 705 vrfy = br_rsa_pkcs1_vrfy_get_default(); 706 707 if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) || 708 memcmp(vhbuf, mdata, mlen) != 0) { 709 return (0); /* fail */ 710 } 711 return (1); /* ok */ 712 } 713 #endif 714 715 /** 716 * @brief 717 * verify file against sigfile using pk 718 * 719 * When we generated the signature in sigfile, 720 * we hashed (sha256) file, and sent that to signing server 721 * which hashed (sha256) that hash. 722 * 723 * Or (deprecated) we simply used sha1 hash directly. 724 * 725 * To verify we need to replicate that result. 726 * 727 * @param[in] pk 728 * br_x509_pkey 729 * 730 * @paramp[in] file 731 * file to be verified 732 * 733 * @param[in] sigfile 734 * signature (PEM encoded) 735 * 736 * @return NULL on error, otherwise content of file. 737 */ 738 #ifdef VE_RSA_SUPPORT 739 static unsigned char * 740 verify_rsa(br_x509_pkey *pk, const char *file, const char *sigfile) 741 { 742 unsigned char rhbuf[br_sha512_SIZE]; 743 const unsigned char *hash_oid; 744 const br_hash_class *md; 745 br_hash_compat_context mctx; 746 unsigned char *fcp, *scp; 747 size_t flen, slen, plen, hlen; 748 pem_object *po; 749 750 if ((fcp = read_file(file, &flen)) == NULL) 751 return (NULL); 752 if ((scp = read_file(sigfile, &slen)) == NULL) { 753 free(fcp); 754 return (NULL); 755 } 756 if ((po = decode_pem(scp, slen, &plen)) == NULL) { 757 free(fcp); 758 free(scp); 759 return (NULL); 760 } 761 762 switch (po->data_len) { 763 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT) 764 case 256: 765 // this is our old deprecated sig method 766 md = &br_sha1_vtable; 767 hlen = br_sha1_SIZE; 768 hash_oid = BR_HASH_OID_SHA1; 769 break; 770 #endif 771 default: 772 md = &br_sha256_vtable; 773 hlen = br_sha256_SIZE; 774 hash_oid = BR_HASH_OID_SHA256; 775 break; 776 } 777 md->init(&mctx.vtable); 778 md->update(&mctx.vtable, fcp, flen); 779 md->out(&mctx.vtable, rhbuf); 780 if (!verify_rsa_digest(&pk->key.rsa, hash_oid, 781 rhbuf, hlen, po->data, po->data_len)) { 782 free(fcp); 783 fcp = NULL; 784 } 785 free(scp); 786 return (fcp); 787 } 788 #endif 789 790 /** 791 * @brief 792 * verify a signature and return content of signed file 793 * 794 * @param[in] sigfile 795 * file containing signature 796 * we derrive path of signed file and certificate change from 797 * this. 798 * 799 * @param[in] flags 800 * only bit 1 significant so far 801 * 802 * @return NULL on error otherwise content of signed file 803 */ 804 unsigned char * 805 verify_sig(const char *sigfile, int flags) 806 { 807 br_x509_pkey *pk; 808 br_name_element cn; 809 char cn_buf[80]; 810 unsigned char cn_oid[4]; 811 char pbuf[MAXPATHLEN]; 812 char *cp; 813 unsigned char *ucp; 814 size_t n; 815 816 DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile)); 817 n = strlcpy(pbuf, sigfile, sizeof(pbuf)); 818 if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0) 819 return (NULL); 820 cp = strcpy(&pbuf[n - 3], "certs"); 821 /* 822 * We want the commonName field 823 * the OID we want is 2,5,4,3 - but DER encoded 824 */ 825 cn_oid[0] = 3; 826 cn_oid[1] = 0x55; 827 cn_oid[2] = 4; 828 cn_oid[3] = 3; 829 cn.oid = cn_oid; 830 cn.buf = cn_buf; 831 cn.len = sizeof(cn_buf); 832 833 pk = verify_signer(pbuf, &cn, 1); 834 if (!pk) { 835 printf("cannot verify: %s: %s\n", pbuf, ve_error_get()); 836 return (NULL); 837 } 838 for (; cp > pbuf; cp--) { 839 if (*cp == '.') { 840 *cp = '\0'; 841 break; 842 } 843 } 844 switch (pk->key_type) { 845 #ifdef VE_ECDSA_SUPPORT 846 case BR_KEYTYPE_EC: 847 ucp = verify_ec(pk, pbuf, sigfile); 848 break; 849 #endif 850 #ifdef VE_RSA_SUPPORT 851 case BR_KEYTYPE_RSA: 852 ucp = verify_rsa(pk, pbuf, sigfile); 853 break; 854 #endif 855 default: 856 ucp = NULL; /* not supported */ 857 } 858 xfreepkey(pk); 859 if (!ucp) { 860 printf("Unverified %s (%s)\n", pbuf, 861 cn.status ? cn_buf : "unknown"); 862 } else if ((flags & 1) != 0) { 863 printf("Verified %s signed by %s\n", pbuf, 864 cn.status ? cn_buf : "someone we trust"); 865 } 866 return (ucp); 867 } 868 869 870 /** 871 * @brief verify hash matches 872 * 873 * We have finished hashing a file, 874 * see if we got the desired result. 875 * 876 * @param[in] ctx 877 * pointer to hash context 878 * 879 * @param[in] md 880 * pointer to hash class 881 * 882 * @param[in] path 883 * name of the file we are checking 884 * 885 * @param[in] want 886 * the expected result 887 * 888 * @param[in] hlen 889 * size of hash output 890 * 891 * @return 0 on success 892 */ 893 int 894 ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md, 895 const char *path, const char *want, size_t hlen) 896 { 897 char hexbuf[br_sha512_SIZE * 2 + 2]; 898 unsigned char hbuf[br_sha512_SIZE]; 899 char *hex; 900 int rc; 901 int n; 902 903 md->out(&ctx->vtable, hbuf); 904 #ifdef VE_PCR_SUPPORT 905 ve_pcr_update(hbuf, hlen); 906 #endif 907 hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen); 908 if (!hex) 909 return (VE_FINGERPRINT_WRONG); 910 n = 2*hlen; 911 if ((rc = strncmp(hex, want, n))) { 912 ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want); 913 rc = VE_FINGERPRINT_WRONG; 914 } 915 return (rc ? rc : VE_FINGERPRINT_OK); 916 } 917 918 #ifdef VE_HASH_KAT_STR 919 static int 920 test_hash(const br_hash_class *md, size_t hlen, 921 const char *hname, const char *s, size_t slen, const char *want) 922 { 923 br_hash_compat_context mctx; 924 925 md->init(&mctx.vtable); 926 md->update(&mctx.vtable, s, slen); 927 return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK); 928 } 929 930 #endif 931 932 #define ve_test_hash(n, N) \ 933 printf("Testing hash: " #n "\t\t\t\t%s\n", \ 934 test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \ 935 VE_HASH_KAT_STR, VE_HASH_KAT_STRLEN(VE_HASH_KAT_STR), \ 936 vh_ ## N) ? "Failed" : "Passed") 937 938 /** 939 * @brief 940 * run self tests on hash and signature verification 941 * 942 * Test that the hash methods (SHA1 and SHA256) work. 943 * Test that we can verify a certificate for each supported 944 * Root CA. 945 * 946 * @return cached result. 947 */ 948 int 949 ve_self_tests(void) 950 { 951 static int once = -1; 952 #ifdef VERIFY_CERTS_STR 953 br_x509_certificate *xcs; 954 br_x509_pkey *pk; 955 br_name_element cn; 956 char cn_buf[80]; 957 unsigned char cn_oid[4]; 958 size_t num; 959 size_t u; 960 #endif 961 962 if (once >= 0) 963 return (once); 964 once = 0; 965 966 DEBUG_PRINTF(5, ("Self tests...\n")); 967 #ifdef VE_HASH_KAT_STR 968 #ifdef VE_SHA1_SUPPORT 969 ve_test_hash(sha1, SHA1); 970 #endif 971 #ifdef VE_SHA256_SUPPORT 972 ve_test_hash(sha256, SHA256); 973 #endif 974 #ifdef VE_SHA384_SUPPORT 975 ve_test_hash(sha384, SHA384); 976 #endif 977 #ifdef VE_SHA512_SUPPORT 978 ve_test_hash(sha512, SHA512); 979 #endif 980 #endif 981 #ifdef VERIFY_CERTS_STR 982 xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR), 983 sizeof(VERIFY_CERTS_STR), &num); 984 if (xcs != NULL) { 985 /* 986 * We want the commonName field 987 * the OID we want is 2,5,4,3 - but DER encoded 988 */ 989 cn_oid[0] = 3; 990 cn_oid[1] = 0x55; 991 cn_oid[2] = 4; 992 cn_oid[3] = 3; 993 cn.oid = cn_oid; 994 cn.buf = cn_buf; 995 996 for (u = 0; u < num; u ++) { 997 cn.len = sizeof(cn_buf); 998 if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) { 999 free_cert_contents(&xcs[u]); 1000 once++; 1001 printf("Testing verify certificate: %s\tPassed\n", 1002 cn.status ? cn_buf : ""); 1003 xfreepkey(pk); 1004 } 1005 } 1006 if (!once) 1007 printf("Testing verify certificate:\t\t\tFailed\n"); 1008 xfree(xcs); 1009 } 1010 #endif /* VERIFY_CERTS_STR */ 1011 #ifdef VE_OPENPGP_SUPPORT 1012 if (!openpgp_self_tests()) 1013 once++; 1014 #endif 1015 return (once); 1016 } 1017