1 /* $OpenBSD: parser.c,v 1.148 2024/11/21 13:32:27 claudio Exp $ */ 2 /* 3 * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> 4 * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/queue.h> 20 #include <sys/tree.h> 21 #include <sys/types.h> 22 23 #include <err.h> 24 #include <fcntl.h> 25 #include <poll.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <limits.h> 30 #include <unistd.h> 31 #include <imsg.h> 32 33 #include <openssl/asn1.h> 34 #include <openssl/err.h> 35 #include <openssl/evp.h> 36 #include <openssl/x509.h> 37 #include <openssl/x509v3.h> 38 39 #include "extern.h" 40 41 extern int certid; 42 43 extern BN_CTX *bn_ctx; 44 45 static X509_STORE_CTX *ctx; 46 static struct auth_tree auths = RB_INITIALIZER(&auths); 47 static struct crl_tree crlt = RB_INITIALIZER(&crlt); 48 49 struct parse_repo { 50 RB_ENTRY(parse_repo) entry; 51 char *path; 52 char *validpath; 53 unsigned int id; 54 }; 55 56 static RB_HEAD(repo_tree, parse_repo) repos = RB_INITIALIZER(&repos); 57 58 static inline int 59 repocmp(struct parse_repo *a, struct parse_repo *b) 60 { 61 return a->id - b->id; 62 } 63 64 RB_GENERATE_STATIC(repo_tree, parse_repo, entry, repocmp); 65 66 static struct parse_repo * 67 repo_get(unsigned int id) 68 { 69 struct parse_repo needle = { .id = id }; 70 71 return RB_FIND(repo_tree, &repos, &needle); 72 } 73 74 static void 75 repo_add(unsigned int id, char *path, char *validpath) 76 { 77 struct parse_repo *rp; 78 79 if ((rp = calloc(1, sizeof(*rp))) == NULL) 80 err(1, NULL); 81 rp->id = id; 82 if (path != NULL) 83 if ((rp->path = strdup(path)) == NULL) 84 err(1, NULL); 85 if (validpath != NULL) 86 if ((rp->validpath = strdup(validpath)) == NULL) 87 err(1, NULL); 88 89 if (RB_INSERT(repo_tree, &repos, rp) != NULL) 90 errx(1, "repository already added: id %d, %s", id, path); 91 } 92 93 /* 94 * Return the issuer by its certificate id, or NULL on failure. 95 * Make sure the AKI is the same as the AKI listed on the Manifest, 96 * and that the SKI of the cert matches with the AKI. 97 */ 98 static struct auth * 99 find_issuer(const char *fn, int id, const char *aki, const char *mftaki) 100 { 101 struct auth *a; 102 103 a = auth_find(&auths, id); 104 if (a == NULL) { 105 if (certid <= CERTID_MAX) 106 warnx("%s: RFC 6487: unknown cert with SKI %s", fn, 107 aki); 108 return NULL; 109 } 110 111 if (mftaki != NULL) { 112 if (strcmp(aki, mftaki) != 0) { 113 warnx("%s: AKI %s doesn't match Manifest AKI %s", fn, 114 aki, mftaki); 115 return NULL; 116 } 117 } 118 119 if (strcmp(aki, a->cert->ski) != 0) { 120 warnx("%s: AKI %s doesn't match issuer SKI %s", fn, 121 aki, a->cert->ski); 122 return NULL; 123 } 124 125 return a; 126 } 127 128 /* 129 * Build access path to file based on repoid, path, location and file values. 130 */ 131 static char * 132 parse_filepath(unsigned int repoid, const char *path, const char *file, 133 enum location loc) 134 { 135 struct parse_repo *rp; 136 char *fn, *repopath; 137 138 /* build file path based on repoid, entity path and filename */ 139 rp = repo_get(repoid); 140 if (rp == NULL) 141 errx(1, "build file path: repository %u missing", repoid); 142 143 if (loc == DIR_VALID) 144 repopath = rp->validpath; 145 else 146 repopath = rp->path; 147 148 if (repopath == NULL) 149 return NULL; 150 151 if (path == NULL) { 152 if (asprintf(&fn, "%s/%s", repopath, file) == -1) 153 err(1, NULL); 154 } else { 155 if (asprintf(&fn, "%s/%s/%s", repopath, path, file) == -1) 156 err(1, NULL); 157 } 158 return fn; 159 } 160 161 /* 162 * Parse and validate a ROA. 163 * This is standard stuff. 164 * Returns the roa on success, NULL on failure. 165 */ 166 static struct roa * 167 proc_parser_roa(char *file, const unsigned char *der, size_t len, 168 const struct entity *entp) 169 { 170 struct roa *roa; 171 X509 *x509 = NULL; 172 struct auth *a; 173 struct crl *crl; 174 const char *errstr; 175 176 if ((roa = roa_parse(&x509, file, entp->talid, der, len)) == NULL) 177 goto out; 178 179 a = find_issuer(file, entp->certid, roa->aki, entp->mftaki); 180 if (a == NULL) 181 goto out; 182 crl = crl_get(&crlt, a); 183 184 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 185 warnx("%s: %s", file, errstr); 186 goto out; 187 } 188 X509_free(x509); 189 x509 = NULL; 190 191 roa->talid = a->cert->talid; 192 193 roa->expires = x509_find_expires(roa->notafter, a, &crlt); 194 195 return roa; 196 197 out: 198 roa_free(roa); 199 X509_free(x509); 200 201 return NULL; 202 } 203 204 /* 205 * Parse and validate a draft-ietf-sidrops-rpki-prefixlist SPL. 206 * Returns the spl on success, NULL on failure. 207 */ 208 static struct spl * 209 proc_parser_spl(char *file, const unsigned char *der, size_t len, 210 const struct entity *entp) 211 { 212 struct spl *spl; 213 X509 *x509 = NULL; 214 struct auth *a; 215 struct crl *crl; 216 const char *errstr; 217 218 if ((spl = spl_parse(&x509, file, entp->talid, der, len)) == NULL) 219 goto out; 220 221 a = find_issuer(file, entp->certid, spl->aki, entp->mftaki); 222 if (a == NULL) 223 goto out; 224 crl = crl_get(&crlt, a); 225 226 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 227 warnx("%s: %s", file, errstr); 228 goto out; 229 } 230 X509_free(x509); 231 x509 = NULL; 232 233 spl->talid = a->cert->talid; 234 235 spl->expires = x509_find_expires(spl->notafter, a, &crlt); 236 237 return spl; 238 239 out: 240 spl_free(spl); 241 X509_free(x509); 242 243 return NULL; 244 } 245 246 /* 247 * Check all files and their hashes in a MFT structure. 248 * Return zero on failure, non-zero on success. 249 */ 250 static int 251 proc_parser_mft_check(const char *fn, struct mft *p) 252 { 253 const enum location loc[2] = { DIR_TEMP, DIR_VALID }; 254 size_t i; 255 int rc = 1; 256 char *path; 257 258 if (p == NULL) 259 return 0; 260 261 for (i = 0; i < p->filesz; i++) { 262 struct mftfile *m = &p->files[i]; 263 int try, fd = -1, noent = 0, valid = 0; 264 for (try = 0; try < 2 && !valid; try++) { 265 if ((path = parse_filepath(p->repoid, p->path, m->file, 266 loc[try])) == NULL) 267 continue; 268 fd = open(path, O_RDONLY); 269 if (fd == -1 && errno == ENOENT) 270 noent++; 271 free(path); 272 273 /* remember which path was checked */ 274 m->location = loc[try]; 275 valid = valid_filehash(fd, m->hash, sizeof(m->hash)); 276 } 277 278 if (!valid) { 279 /* silently skip not-existing unknown files */ 280 if (m->type == RTYPE_INVALID && noent == 2) 281 continue; 282 warnx("%s#%s: bad message digest for %s", fn, 283 p->seqnum, m->file); 284 rc = 0; 285 continue; 286 } 287 } 288 289 return rc; 290 } 291 292 /* 293 * Load the CRL from loc using the info from the MFT. 294 */ 295 static struct crl * 296 parse_load_crl_from_mft(struct entity *entp, struct mft *mft, enum location loc, 297 char **crlfile) 298 { 299 struct crl *crl = NULL; 300 unsigned char *f = NULL; 301 char *fn = NULL; 302 size_t flen; 303 304 *crlfile = NULL; 305 306 fn = parse_filepath(entp->repoid, entp->path, mft->crl, loc); 307 if (fn == NULL) 308 goto out; 309 310 f = load_file(fn, &flen); 311 if (f == NULL) { 312 if (errno != ENOENT) 313 warn("parse file %s", fn); 314 goto out; 315 } 316 317 if (!valid_hash(f, flen, mft->crlhash, sizeof(mft->crlhash))) 318 goto out; 319 320 crl = crl_parse(fn, f, flen); 321 if (crl == NULL) 322 goto out; 323 324 if (strcmp(crl->aki, mft->aki) != 0) { 325 warnx("%s: AKI doesn't match Manifest AKI", fn); 326 goto out; 327 } 328 329 if ((crl->mftpath = strdup(mft->sia)) == NULL) 330 err(1, NULL); 331 332 *crlfile = fn; 333 free(f); 334 335 return crl; 336 337 out: 338 crl_free(crl); 339 free(f); 340 free(fn); 341 342 return NULL; 343 } 344 345 /* 346 * Parse and validate a manifest file. 347 * Don't check the fileandhash, this is done later on. 348 * Return the mft on success, or NULL on failure. 349 */ 350 static struct mft * 351 proc_parser_mft_pre(struct entity *entp, char *file, struct crl **crl, 352 char **crlfile, struct mft *cached_mft, const char **errstr) 353 { 354 struct mft *mft; 355 X509 *x509; 356 struct auth *a; 357 unsigned char *der; 358 size_t len; 359 time_t now; 360 int issued_cmp, seqnum_cmp; 361 362 *crl = NULL; 363 *crlfile = NULL; 364 *errstr = NULL; 365 366 if (file == NULL) 367 return NULL; 368 369 der = load_file(file, &len); 370 if (der == NULL && errno != ENOENT) 371 warn("parse file %s", file); 372 373 if ((mft = mft_parse(&x509, file, entp->talid, der, len)) == NULL) { 374 free(der); 375 return NULL; 376 } 377 378 if (entp->path != NULL) { 379 if ((mft->path = strdup(entp->path)) == NULL) 380 err(1, NULL); 381 } 382 383 if (!EVP_Digest(der, len, mft->mfthash, NULL, EVP_sha256(), NULL)) 384 errx(1, "EVP_Digest failed"); 385 386 free(der); 387 388 *crl = parse_load_crl_from_mft(entp, mft, DIR_TEMP, crlfile); 389 if (*crl == NULL) 390 *crl = parse_load_crl_from_mft(entp, mft, DIR_VALID, crlfile); 391 392 a = find_issuer(file, entp->certid, mft->aki, NULL); 393 if (a == NULL) 394 goto err; 395 if (!valid_x509(file, ctx, x509, a, *crl, errstr)) 396 goto err; 397 X509_free(x509); 398 x509 = NULL; 399 400 mft->repoid = entp->repoid; 401 mft->talid = a->cert->talid; 402 mft->certid = entp->certid; 403 404 now = get_current_time(); 405 /* check that now is not before from */ 406 if (now < mft->thisupdate) { 407 warnx("%s: manifest not yet valid %s", file, 408 time2str(mft->thisupdate)); 409 goto err; 410 } 411 /* check that now is not after until */ 412 if (now > mft->nextupdate) { 413 warnx("%s: manifest expired on %s", file, 414 time2str(mft->nextupdate)); 415 goto err; 416 } 417 418 /* if there is nothing to compare to, return now */ 419 if (cached_mft == NULL) 420 return mft; 421 422 /* 423 * Check that the cached manifest is older in the sense that it was 424 * issued earlier and that it has a smaller sequence number. 425 */ 426 427 if ((issued_cmp = mft_compare_issued(mft, cached_mft)) < 0) { 428 warnx("%s: unexpected manifest issuance date (want >= %lld, " 429 "got %lld)", file, (long long)cached_mft->thisupdate, 430 (long long)mft->thisupdate); 431 goto err; 432 } 433 if ((seqnum_cmp = mft_compare_seqnum(mft, cached_mft)) < 0) { 434 warnx("%s: unexpected manifest number (want >= #%s, got #%s)", 435 file, cached_mft->seqnum, mft->seqnum); 436 goto err; 437 } 438 if (issued_cmp > 0 && seqnum_cmp == 0) { 439 warnx("%s: manifest issued at %lld and %lld with same " 440 "manifest number #%s", file, (long long)mft->thisupdate, 441 (long long)cached_mft->thisupdate, cached_mft->seqnum); 442 goto err; 443 } 444 if (issued_cmp == 0 && seqnum_cmp > 0) { 445 warnx("%s: #%s and #%s were issued at same issuance date %lld", 446 file, mft->seqnum, cached_mft->seqnum, 447 (long long)mft->thisupdate); 448 goto err; 449 } 450 if (issued_cmp == 0 && seqnum_cmp == 0 && memcmp(mft->mfthash, 451 cached_mft->mfthash, SHA256_DIGEST_LENGTH) != 0) { 452 warnx("%s: misissuance, issuance date %lld and manifest number " 453 "#%s were recycled", file, (long long)mft->thisupdate, 454 mft->seqnum); 455 goto err; 456 } 457 458 if (seqnum_cmp > 0) { 459 if (mft_seqnum_gap_present(mft, cached_mft)) { 460 mft->seqnum_gap = 1; 461 warnx("%s: seqnum gap detected #%s -> #%s", file, 462 cached_mft->seqnum, mft->seqnum); 463 } 464 } 465 466 return mft; 467 468 err: 469 X509_free(x509); 470 mft_free(mft); 471 crl_free(*crl); 472 *crl = NULL; 473 free(*crlfile); 474 *crlfile = NULL; 475 return NULL; 476 } 477 478 /* 479 * Load the most recent MFT by opening both options and comparing the two. 480 */ 481 static char * 482 proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile, 483 time_t *crlmtime) 484 { 485 struct mft *mft1 = NULL, *mft2 = NULL; 486 struct crl *crl, *crl1 = NULL, *crl2 = NULL; 487 char *file, *file1 = NULL, *file2 = NULL; 488 char *crl1file = NULL, *crl2file = NULL; 489 const char *err1 = NULL, *err2 = NULL; 490 491 *mp = NULL; 492 *crlmtime = 0; 493 494 file2 = parse_filepath(entp->repoid, entp->path, entp->file, DIR_VALID); 495 mft2 = proc_parser_mft_pre(entp, file2, &crl2, &crl2file, NULL, &err2); 496 497 if (!noop) { 498 file1 = parse_filepath(entp->repoid, entp->path, entp->file, 499 DIR_TEMP); 500 mft1 = proc_parser_mft_pre(entp, file1, &crl1, &crl1file, mft2, 501 &err1); 502 } 503 504 if (proc_parser_mft_check(file1, mft1)) { 505 mft_free(mft2); 506 crl_free(crl2); 507 free(crl2file); 508 free(file2); 509 510 *mp = mft1; 511 crl = crl1; 512 file = file1; 513 *crlfile = crl1file; 514 } else { 515 if (mft1 != NULL && mft2 != NULL) 516 warnx("%s: failed fetch, continuing with #%s " 517 "from cache", file2, mft2->seqnum); 518 519 if (!proc_parser_mft_check(file2, mft2)) { 520 mft_free(mft2); 521 mft2 = NULL; 522 523 if (err2 == NULL) 524 err2 = err1; 525 if (err2 == NULL) 526 err2 = "no valid manifest available"; 527 if (certid <= CERTID_MAX) 528 warnx("%s: %s", file2, err2); 529 } 530 531 mft_free(mft1); 532 crl_free(crl1); 533 free(crl1file); 534 free(file1); 535 536 *mp = mft2; 537 crl = crl2; 538 file = file2; 539 *crlfile = crl2file; 540 } 541 542 if (*mp != NULL) { 543 *crlmtime = crl->thisupdate; 544 if (crl_insert(&crlt, crl)) 545 crl = NULL; 546 } 547 crl_free(crl); 548 549 return file; 550 } 551 552 /* 553 * Certificates are from manifests (has a digest and is signed with 554 * another certificate) Parse the certificate, make sure its 555 * signatures are valid (with CRLs), then validate the RPKI content. 556 * This returns a certificate (which must not be freed) or NULL on 557 * parse failure. 558 */ 559 static struct cert * 560 proc_parser_cert(char *file, const unsigned char *der, size_t len, 561 const struct entity *entp) 562 { 563 struct cert *cert; 564 struct crl *crl; 565 struct auth *a; 566 const char *errstr = NULL; 567 568 /* Extract certificate data. */ 569 570 cert = cert_parse_pre(file, der, len); 571 cert = cert_parse(file, cert); 572 if (cert == NULL) 573 goto out; 574 575 a = find_issuer(file, entp->certid, cert->aki, entp->mftaki); 576 if (a == NULL) 577 goto out; 578 crl = crl_get(&crlt, a); 579 580 if (!valid_x509(file, ctx, cert->x509, a, crl, &errstr) || 581 !valid_cert(file, a, cert)) { 582 if (errstr != NULL) 583 warnx("%s: %s", file, errstr); 584 goto out; 585 } 586 587 cert->talid = a->cert->talid; 588 589 if (cert->purpose == CERT_PURPOSE_BGPSEC_ROUTER) { 590 if (!constraints_validate(file, cert)) 591 goto out; 592 } 593 594 /* 595 * Add validated CA certs to the RPKI auth tree. 596 */ 597 if (cert->purpose == CERT_PURPOSE_CA) 598 auth_insert(file, &auths, cert, a); 599 600 return cert; 601 602 out: 603 cert_free(cert); 604 605 return NULL; 606 } 607 608 static int 609 proc_parser_ta_cmp(const struct cert *cert1, const struct cert *cert2) 610 { 611 if (cert1 == NULL) 612 return -1; 613 if (cert2 == NULL) 614 return 1; 615 616 /* 617 * The standards don't specify tiebreakers. While RFC 6487 and other 618 * sources advise against backdating, it's explicitly allowed and some 619 * TAs do. Some TAs have also re-issued with new dates and old 620 * serialNumber. 621 * Our tiebreaker logic: a more recent notBefore is taken to mean a 622 * more recent issuance, and thus preferable. Given equal notBefore 623 * values, prefer the TA cert with the narrower validity window. This 624 * hopefully encourages TA operators to reduce egregiously long TA 625 * validity periods. 626 */ 627 628 if (cert1->notbefore < cert2->notbefore) 629 return -1; 630 if (cert1->notbefore > cert2->notbefore) 631 return 1; 632 633 if (cert1->notafter > cert2->notafter) 634 return -1; 635 if (cert1->notafter < cert2->notafter) 636 return 1; 637 638 /* 639 * Both certs are valid from our perspective. If anything changed, 640 * prefer the freshly-fetched one. We rely on cert_parse_pre() having 641 * cached the extensions and thus libcrypto has already computed the 642 * certs' hashes (SHA-1 for OpenSSL, SHA-512 for LibreSSL). The below 643 * compares them. 644 */ 645 646 return X509_cmp(cert1->x509, cert2->x509) != 0; 647 } 648 649 /* 650 * Root certificates come from TALs. Inspect and validate both options and 651 * compare the two. The cert in out_cert must not be freed. Returns the file 652 * name of the chosen TA. 653 */ 654 static char * 655 proc_parser_root_cert(struct entity *entp, struct cert **out_cert) 656 { 657 struct cert *cert1 = NULL, *cert2 = NULL; 658 char *file1 = NULL, *file2 = NULL; 659 unsigned char *der = NULL, *pkey = entp->data; 660 size_t der_len = 0, pkeysz = entp->datasz; 661 int cmp; 662 663 *out_cert = NULL; 664 665 file2 = parse_filepath(entp->repoid, entp->path, entp->file, DIR_VALID); 666 der = load_file(file2, &der_len); 667 cert2 = cert_parse_pre(file2, der, der_len); 668 free(der); 669 cert2 = ta_parse(file2, cert2, pkey, pkeysz); 670 671 if (!noop) { 672 file1 = parse_filepath(entp->repoid, entp->path, entp->file, 673 DIR_TEMP); 674 der = load_file(file1, &der_len); 675 cert1 = cert_parse_pre(file1, der, der_len); 676 free(der); 677 cert1 = ta_parse(file1, cert1, pkey, pkeysz); 678 } 679 680 if ((cmp = proc_parser_ta_cmp(cert1, cert2)) > 0) { 681 cert_free(cert2); 682 free(file2); 683 684 cert1->talid = entp->talid; 685 auth_insert(file1, &auths, cert1, NULL); 686 687 *out_cert = cert1; 688 return file1; 689 } else { 690 if (cmp < 0 && cert1 != NULL && cert2 != NULL) 691 warnx("%s: cached TA is newer", entp->file); 692 cert_free(cert1); 693 free(file1); 694 695 if (cert2 != 0) { 696 cert2->talid = entp->talid; 697 auth_insert(file2, &auths, cert2, NULL); 698 } 699 700 *out_cert = cert2; 701 return file2; 702 } 703 } 704 705 /* 706 * Parse a ghostbuster record 707 */ 708 static struct gbr * 709 proc_parser_gbr(char *file, const unsigned char *der, size_t len, 710 const struct entity *entp) 711 { 712 struct gbr *gbr; 713 X509 *x509 = NULL; 714 struct crl *crl; 715 struct auth *a; 716 const char *errstr; 717 718 if ((gbr = gbr_parse(&x509, file, entp->talid, der, len)) == NULL) 719 goto out; 720 721 a = find_issuer(file, entp->certid, gbr->aki, entp->mftaki); 722 if (a == NULL) 723 goto out; 724 crl = crl_get(&crlt, a); 725 726 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 727 warnx("%s: %s", file, errstr); 728 goto out; 729 } 730 X509_free(x509); 731 x509 = NULL; 732 733 gbr->talid = a->cert->talid; 734 735 return gbr; 736 737 out: 738 gbr_free(gbr); 739 X509_free(x509); 740 741 return NULL; 742 } 743 744 /* 745 * Parse an ASPA object 746 */ 747 static struct aspa * 748 proc_parser_aspa(char *file, const unsigned char *der, size_t len, 749 const struct entity *entp) 750 { 751 struct aspa *aspa; 752 X509 *x509 = NULL; 753 struct auth *a; 754 struct crl *crl; 755 const char *errstr; 756 757 if ((aspa = aspa_parse(&x509, file, entp->talid, der, len)) == NULL) 758 goto out; 759 760 a = find_issuer(file, entp->certid, aspa->aki, entp->mftaki); 761 if (a == NULL) 762 goto out; 763 crl = crl_get(&crlt, a); 764 765 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 766 warnx("%s: %s", file, errstr); 767 goto out; 768 } 769 X509_free(x509); 770 x509 = NULL; 771 772 aspa->talid = a->cert->talid; 773 774 aspa->expires = x509_find_expires(aspa->notafter, a, &crlt); 775 776 return aspa; 777 778 out: 779 aspa_free(aspa); 780 X509_free(x509); 781 782 return NULL; 783 } 784 785 /* 786 * Parse a TAK object. 787 */ 788 static struct tak * 789 proc_parser_tak(char *file, const unsigned char *der, size_t len, 790 const struct entity *entp) 791 { 792 struct tak *tak; 793 X509 *x509 = NULL; 794 struct crl *crl; 795 struct auth *a; 796 const char *errstr; 797 798 if ((tak = tak_parse(&x509, file, entp->talid, der, len)) == NULL) 799 goto out; 800 801 a = find_issuer(file, entp->certid, tak->aki, entp->mftaki); 802 if (a == NULL) 803 goto out; 804 crl = crl_get(&crlt, a); 805 806 if (!valid_x509(file, ctx, x509, a, crl, &errstr)) { 807 warnx("%s: %s", file, errstr); 808 goto out; 809 } 810 X509_free(x509); 811 x509 = NULL; 812 813 /* TAK EE must be signed by self-signed CA */ 814 if (a->issuer != NULL) 815 goto out; 816 817 tak->talid = a->cert->talid; 818 819 return tak; 820 821 out: 822 tak_free(tak); 823 X509_free(x509); 824 825 return NULL; 826 } 827 828 /* 829 * Load the file specified by the entity information. 830 */ 831 static char * 832 parse_load_file(struct entity *entp, unsigned char **f, size_t *flen) 833 { 834 char *file; 835 836 file = parse_filepath(entp->repoid, entp->path, entp->file, 837 entp->location); 838 if (file == NULL) 839 errx(1, "no path to file"); 840 841 *f = load_file(file, flen); 842 if (*f == NULL) 843 warn("parse file %s", file); 844 845 return file; 846 } 847 848 /* 849 * Process an entity and respond to parent process. 850 */ 851 static void 852 parse_entity(struct entityq *q, struct msgbuf *msgq) 853 { 854 struct entity *entp; 855 struct tal *tal; 856 struct cert *cert; 857 struct mft *mft; 858 struct roa *roa; 859 struct aspa *aspa; 860 struct gbr *gbr; 861 struct tak *tak; 862 struct spl *spl; 863 struct ibuf *b; 864 unsigned char *f; 865 time_t mtime, crlmtime; 866 size_t flen; 867 char *file, *crlfile; 868 int c; 869 870 while ((entp = TAILQ_FIRST(q)) != NULL) { 871 TAILQ_REMOVE(q, entp, entries); 872 873 /* handle RTYPE_REPO first */ 874 if (entp->type == RTYPE_REPO) { 875 repo_add(entp->repoid, entp->path, entp->file); 876 entity_free(entp); 877 continue; 878 } 879 880 /* pass back at least type, repoid and filename */ 881 b = io_new_buffer(); 882 io_simple_buffer(b, &entp->type, sizeof(entp->type)); 883 io_simple_buffer(b, &entp->repoid, sizeof(entp->repoid)); 884 io_simple_buffer(b, &entp->talid, sizeof(entp->talid)); 885 886 file = NULL; 887 f = NULL; 888 mtime = 0; 889 crlmtime = 0; 890 891 switch (entp->type) { 892 case RTYPE_TAL: 893 io_str_buffer(b, entp->file); 894 io_simple_buffer(b, &mtime, sizeof(mtime)); 895 if ((tal = tal_parse(entp->file, entp->data, 896 entp->datasz)) == NULL) 897 errx(1, "%s: could not parse tal file", 898 entp->file); 899 tal->id = entp->talid; 900 tal_buffer(b, tal); 901 tal_free(tal); 902 break; 903 case RTYPE_CER: 904 if (entp->data != NULL) { 905 file = proc_parser_root_cert(entp, &cert); 906 } else { 907 file = parse_load_file(entp, &f, &flen); 908 cert = proc_parser_cert(file, f, flen, entp); 909 } 910 io_str_buffer(b, file); 911 if (cert != NULL) 912 mtime = cert->notbefore; 913 io_simple_buffer(b, &mtime, sizeof(mtime)); 914 c = (cert != NULL); 915 io_simple_buffer(b, &c, sizeof(int)); 916 if (cert != NULL) { 917 cert->repoid = entp->repoid; 918 cert_buffer(b, cert); 919 } 920 /* 921 * The parsed certificate data "cert" is now 922 * managed in the "auths" table, so don't free 923 * it here. 924 */ 925 break; 926 case RTYPE_MFT: 927 file = proc_parser_mft(entp, &mft, &crlfile, &crlmtime); 928 io_str_buffer(b, file); 929 if (mft != NULL) 930 mtime = mft->signtime; 931 io_simple_buffer(b, &mtime, sizeof(mtime)); 932 c = (mft != NULL); 933 io_simple_buffer(b, &c, sizeof(int)); 934 if (mft != NULL) 935 mft_buffer(b, mft); 936 937 /* Push valid CRL together with the MFT. */ 938 if (crlfile != NULL) { 939 enum rtype type; 940 struct ibuf *b2; 941 942 b2 = io_new_buffer(); 943 type = RTYPE_CRL; 944 io_simple_buffer(b2, &type, sizeof(type)); 945 io_simple_buffer(b2, &entp->repoid, 946 sizeof(entp->repoid)); 947 io_simple_buffer(b2, &entp->talid, 948 sizeof(entp->talid)); 949 io_str_buffer(b2, crlfile); 950 io_simple_buffer(b2, &crlmtime, 951 sizeof(crlmtime)); 952 free(crlfile); 953 954 io_close_buffer(msgq, b2); 955 } 956 mft_free(mft); 957 break; 958 case RTYPE_ROA: 959 file = parse_load_file(entp, &f, &flen); 960 io_str_buffer(b, file); 961 roa = proc_parser_roa(file, f, flen, entp); 962 if (roa != NULL) 963 mtime = roa->signtime; 964 io_simple_buffer(b, &mtime, sizeof(mtime)); 965 c = (roa != NULL); 966 io_simple_buffer(b, &c, sizeof(int)); 967 if (roa != NULL) 968 roa_buffer(b, roa); 969 roa_free(roa); 970 break; 971 case RTYPE_GBR: 972 file = parse_load_file(entp, &f, &flen); 973 io_str_buffer(b, file); 974 gbr = proc_parser_gbr(file, f, flen, entp); 975 if (gbr != NULL) 976 mtime = gbr->signtime; 977 io_simple_buffer(b, &mtime, sizeof(mtime)); 978 gbr_free(gbr); 979 break; 980 case RTYPE_ASPA: 981 file = parse_load_file(entp, &f, &flen); 982 io_str_buffer(b, file); 983 aspa = proc_parser_aspa(file, f, flen, entp); 984 if (aspa != NULL) 985 mtime = aspa->signtime; 986 io_simple_buffer(b, &mtime, sizeof(mtime)); 987 c = (aspa != NULL); 988 io_simple_buffer(b, &c, sizeof(int)); 989 if (aspa != NULL) 990 aspa_buffer(b, aspa); 991 aspa_free(aspa); 992 break; 993 case RTYPE_TAK: 994 file = parse_load_file(entp, &f, &flen); 995 io_str_buffer(b, file); 996 tak = proc_parser_tak(file, f, flen, entp); 997 if (tak != NULL) 998 mtime = tak->signtime; 999 io_simple_buffer(b, &mtime, sizeof(mtime)); 1000 tak_free(tak); 1001 break; 1002 case RTYPE_SPL: 1003 file = parse_load_file(entp, &f, &flen); 1004 io_str_buffer(b, file); 1005 if (experimental) { 1006 spl = proc_parser_spl(file, f, flen, entp); 1007 if (spl != NULL) 1008 mtime = spl->signtime; 1009 } else { 1010 if (verbose > 0) 1011 warnx("%s: skipped", file); 1012 spl = NULL; 1013 } 1014 io_simple_buffer(b, &mtime, sizeof(mtime)); 1015 c = (spl != NULL); 1016 io_simple_buffer(b, &c, sizeof(int)); 1017 if (spl != NULL) 1018 spl_buffer(b, spl); 1019 spl_free(spl); 1020 break; 1021 case RTYPE_CRL: 1022 default: 1023 file = parse_filepath(entp->repoid, entp->path, 1024 entp->file, entp->location); 1025 io_str_buffer(b, file); 1026 io_simple_buffer(b, &mtime, sizeof(mtime)); 1027 warnx("%s: unhandled type %d", file, entp->type); 1028 break; 1029 } 1030 1031 free(f); 1032 free(file); 1033 io_close_buffer(msgq, b); 1034 entity_free(entp); 1035 } 1036 } 1037 1038 /* 1039 * Process responsible for parsing and validating content. 1040 * All this process does is wait to be told about a file to parse, then 1041 * it parses it and makes sure that the data being returned is fully 1042 * validated and verified. 1043 * The process will exit cleanly only when fd is closed. 1044 */ 1045 void 1046 proc_parser(int fd) 1047 { 1048 struct entityq q; 1049 struct msgbuf *msgq; 1050 struct pollfd pfd; 1051 struct entity *entp; 1052 struct ibuf *b, *inbuf = NULL; 1053 1054 /* Only allow access to the cache directory. */ 1055 if (unveil(".", "r") == -1) 1056 err(1, "unveil cachedir"); 1057 if (pledge("stdio rpath", NULL) == -1) 1058 err(1, "pledge"); 1059 1060 ERR_load_crypto_strings(); 1061 OpenSSL_add_all_ciphers(); 1062 OpenSSL_add_all_digests(); 1063 x509_init_oid(); 1064 constraints_parse(); 1065 1066 if ((ctx = X509_STORE_CTX_new()) == NULL) 1067 err(1, "X509_STORE_CTX_new"); 1068 if ((bn_ctx = BN_CTX_new()) == NULL) 1069 err(1, "BN_CTX_new"); 1070 1071 TAILQ_INIT(&q); 1072 1073 if ((msgq = msgbuf_new_reader(sizeof(size_t), io_parse_hdr, NULL)) == 1074 NULL) 1075 err(1, NULL); 1076 1077 pfd.fd = fd; 1078 1079 for (;;) { 1080 pfd.events = POLLIN; 1081 if (msgbuf_queuelen(msgq) > 0) 1082 pfd.events |= POLLOUT; 1083 1084 if (poll(&pfd, 1, INFTIM) == -1) { 1085 if (errno == EINTR) 1086 continue; 1087 err(1, "poll"); 1088 } 1089 if ((pfd.revents & (POLLERR|POLLNVAL))) 1090 errx(1, "poll: bad descriptor"); 1091 1092 /* If the parent closes, return immediately. */ 1093 1094 if ((pfd.revents & POLLHUP)) 1095 break; 1096 1097 if ((pfd.revents & POLLIN)) { 1098 switch (ibuf_read(fd, msgq)) { 1099 case -1: 1100 err(1, "ibuf_read"); 1101 case 0: 1102 errx(1, "ibuf_read: connection closed"); 1103 } 1104 while ((b = io_buf_get(msgq)) != NULL) { 1105 entp = calloc(1, sizeof(struct entity)); 1106 if (entp == NULL) 1107 err(1, NULL); 1108 entity_read_req(b, entp); 1109 TAILQ_INSERT_TAIL(&q, entp, entries); 1110 ibuf_free(b); 1111 } 1112 } 1113 1114 if (pfd.revents & POLLOUT) { 1115 if (msgbuf_write(fd, msgq) == -1) { 1116 if (errno == EPIPE) 1117 errx(1, "write: connection closed"); 1118 else 1119 err(1, "write"); 1120 } 1121 } 1122 1123 parse_entity(&q, msgq); 1124 } 1125 1126 while ((entp = TAILQ_FIRST(&q)) != NULL) { 1127 TAILQ_REMOVE(&q, entp, entries); 1128 entity_free(entp); 1129 } 1130 1131 auth_tree_free(&auths); 1132 crl_tree_free(&crlt); 1133 1134 X509_STORE_CTX_free(ctx); 1135 BN_CTX_free(bn_ctx); 1136 1137 msgbuf_free(msgq); 1138 ibuf_free(inbuf); 1139 1140 if (certid > CERTID_MAX) 1141 errx(1, "processing incomplete: too many certificates"); 1142 1143 exit(0); 1144 } 1145