1 /* $OpenBSD: parser.c,v 1.10 2021/05/11 11:32:51 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 <assert.h> 24 #include <err.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 38 #include "extern.h" 39 40 static void build_chain(const struct auth *, STACK_OF(X509) **); 41 static void build_crls(const struct auth *, struct crl_tree *, 42 STACK_OF(X509_CRL) **); 43 /* 44 * Parse and validate a ROA. 45 * This is standard stuff. 46 * Returns the roa on success, NULL on failure. 47 */ 48 static struct roa * 49 proc_parser_roa(struct entity *entp, 50 X509_STORE *store, X509_STORE_CTX *ctx, 51 struct auth_tree *auths, struct crl_tree *crlt) 52 { 53 struct roa *roa; 54 X509 *x509; 55 int c, i; 56 struct auth *a; 57 STACK_OF(X509) *chain; 58 STACK_OF(X509_CRL) *crls; 59 const ASN1_TIME *at; 60 struct tm expires_tm; 61 time_t expires; 62 63 if ((roa = roa_parse(&x509, entp->file)) == NULL) 64 return NULL; 65 66 a = valid_ski_aki(entp->file, auths, roa->ski, roa->aki); 67 68 build_chain(a, &chain); 69 build_crls(a, crlt, &crls); 70 71 assert(x509 != NULL); 72 if (!X509_STORE_CTX_init(ctx, store, x509, chain)) 73 cryptoerrx("X509_STORE_CTX_init"); 74 X509_STORE_CTX_set_flags(ctx, 75 X509_V_FLAG_IGNORE_CRITICAL | X509_V_FLAG_CRL_CHECK); 76 X509_STORE_CTX_set0_crls(ctx, crls); 77 78 if (X509_verify_cert(ctx) <= 0) { 79 c = X509_STORE_CTX_get_error(ctx); 80 X509_STORE_CTX_cleanup(ctx); 81 if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL) 82 warnx("%s: %s", entp->file, 83 X509_verify_cert_error_string(c)); 84 X509_free(x509); 85 roa_free(roa); 86 sk_X509_free(chain); 87 sk_X509_CRL_free(crls); 88 return NULL; 89 } 90 X509_STORE_CTX_cleanup(ctx); 91 92 /* 93 * Scan the stack of CRLs to figure out the soonest transitive 94 * expiry moment 95 */ 96 for (i = 0; i < sk_X509_CRL_num(crls); i++) { 97 X509_CRL *ci = sk_X509_CRL_value(crls, i); 98 99 at = X509_CRL_get0_nextUpdate(ci); 100 if (at == NULL) { 101 err(1, "X509_CRL_get0_nextUpdate failed"); 102 goto out; 103 } 104 memset(&expires_tm, 0, sizeof(expires_tm)); 105 if (ASN1_time_parse(at->data, at->length, &expires_tm, 106 V_ASN1_UTCTIME) != V_ASN1_UTCTIME) { 107 err(1, "ASN1_time_parse failed"); 108 goto out; 109 } 110 if ((expires = mktime(&expires_tm)) == -1) { 111 err(1, "mktime failed"); 112 goto out; 113 } 114 if (roa->expires > expires) 115 roa->expires = expires; 116 } 117 118 /* 119 * Scan the stack of CAs to figure out the soonest transitive 120 * expiry moment 121 */ 122 for (i = 0; i < sk_X509_num(chain); i++) { 123 X509 *xi = sk_X509_value(chain, i); 124 125 at = X509_get0_notAfter(xi); 126 if (at == NULL) { 127 err(1, "X509_get0_notafter failed"); 128 goto out; 129 } 130 memset(&expires_tm, 0, sizeof(expires_tm)); 131 if (ASN1_time_parse(at->data, at->length, &expires_tm, 132 V_ASN1_UTCTIME) != V_ASN1_UTCTIME) { 133 err(1, "ASN1_time_parse failed"); 134 goto out; 135 } 136 if ((expires = mktime(&expires_tm)) == -1) { 137 err(1, "mktime failed"); 138 goto out; 139 } 140 if (roa->expires > expires) 141 roa->expires = expires; 142 } 143 144 /* 145 * If the ROA isn't valid, we accept it anyway and depend upon 146 * the code around roa_read() to check the "valid" field itself. 147 */ 148 149 if (valid_roa(entp->file, auths, roa)) 150 roa->valid = 1; 151 152 out: 153 sk_X509_free(chain); 154 sk_X509_CRL_free(crls); 155 X509_free(x509); 156 157 return roa; 158 } 159 160 /* 161 * Parse and validate a manifest file. 162 * Here we *don't* validate against the list of CRLs, because the 163 * certificate used to sign the manifest may specify a CRL that the root 164 * certificate didn't, and we haven't scanned for it yet. 165 * This chicken-and-egg isn't important, however, because we'll catch 166 * the revocation list by the time we scan for any contained resources 167 * (ROA, CER) and will see it then. 168 * Return the mft on success or NULL on failure. 169 */ 170 static struct mft * 171 proc_parser_mft(struct entity *entp, X509_STORE *store, X509_STORE_CTX *ctx, 172 struct auth_tree *auths, struct crl_tree *crlt) 173 { 174 struct mft *mft; 175 X509 *x509; 176 int c; 177 struct auth *a; 178 STACK_OF(X509) *chain; 179 180 if ((mft = mft_parse(&x509, entp->file)) == NULL) 181 return NULL; 182 183 a = valid_ski_aki(entp->file, auths, mft->ski, mft->aki); 184 build_chain(a, &chain); 185 186 if (!X509_STORE_CTX_init(ctx, store, x509, chain)) 187 cryptoerrx("X509_STORE_CTX_init"); 188 189 /* CRL checked disabled here because CRL is referenced from mft */ 190 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_IGNORE_CRITICAL); 191 192 if (X509_verify_cert(ctx) <= 0) { 193 c = X509_STORE_CTX_get_error(ctx); 194 X509_STORE_CTX_cleanup(ctx); 195 warnx("%s: %s", entp->file, X509_verify_cert_error_string(c)); 196 mft_free(mft); 197 X509_free(x509); 198 sk_X509_free(chain); 199 return NULL; 200 } 201 202 X509_STORE_CTX_cleanup(ctx); 203 sk_X509_free(chain); 204 X509_free(x509); 205 206 if (!mft_check(entp->file, mft)) { 207 mft_free(mft); 208 return NULL; 209 } 210 211 return mft; 212 } 213 214 /* 215 * Certificates are from manifests (has a digest and is signed with 216 * another certificate) Parse the certificate, make sure its 217 * signatures are valid (with CRLs), then validate the RPKI content. 218 * This returns a certificate (which must not be freed) or NULL on 219 * parse failure. 220 */ 221 static struct cert * 222 proc_parser_cert(const struct entity *entp, 223 X509_STORE *store, X509_STORE_CTX *ctx, 224 struct auth_tree *auths, struct crl_tree *crlt) 225 { 226 struct cert *cert; 227 X509 *x509; 228 int c; 229 struct auth *a = NULL, *na; 230 char *tal; 231 STACK_OF(X509) *chain; 232 STACK_OF(X509_CRL) *crls; 233 234 assert(!entp->has_pkey); 235 236 /* Extract certificate data and X509. */ 237 238 cert = cert_parse(&x509, entp->file); 239 if (cert == NULL) 240 return NULL; 241 242 a = valid_ski_aki(entp->file, auths, cert->ski, cert->aki); 243 build_chain(a, &chain); 244 build_crls(a, crlt, &crls); 245 246 /* 247 * Validate certificate chain w/CRLs. 248 * Only check the CRLs if specifically asked. 249 */ 250 251 assert(x509 != NULL); 252 if (!X509_STORE_CTX_init(ctx, store, x509, chain)) 253 cryptoerrx("X509_STORE_CTX_init"); 254 255 X509_STORE_CTX_set_flags(ctx, 256 X509_V_FLAG_IGNORE_CRITICAL | X509_V_FLAG_CRL_CHECK); 257 X509_STORE_CTX_set0_crls(ctx, crls); 258 259 if (X509_verify_cert(ctx) <= 0) { 260 c = X509_STORE_CTX_get_error(ctx); 261 warnx("%s: %s", entp->file, 262 X509_verify_cert_error_string(c)); 263 X509_STORE_CTX_cleanup(ctx); 264 cert_free(cert); 265 sk_X509_free(chain); 266 sk_X509_CRL_free(crls); 267 X509_free(x509); 268 return NULL; 269 } 270 271 X509_STORE_CTX_cleanup(ctx); 272 sk_X509_free(chain); 273 sk_X509_CRL_free(crls); 274 275 /* Validate the cert to get the parent */ 276 if (!valid_cert(entp->file, auths, cert)) { 277 X509_free(x509); // needed? XXX 278 return cert; 279 } 280 281 /* 282 * Add validated certs to the RPKI auth tree. 283 */ 284 285 cert->valid = 1; 286 287 na = malloc(sizeof(*na)); 288 if (na == NULL) 289 err(1, NULL); 290 291 tal = a->tal; 292 293 na->parent = a; 294 na->cert = cert; 295 na->tal = tal; 296 na->fn = strdup(entp->file); 297 if (na->fn == NULL) 298 err(1, NULL); 299 300 if (RB_INSERT(auth_tree, auths, na) != NULL) 301 err(1, "auth tree corrupted"); 302 303 return cert; 304 } 305 306 307 /* 308 * Root certificates come from TALs (has a pkey and is self-signed). 309 * Parse the certificate, ensure that it's public key matches the 310 * known public key from the TAL, and then validate the RPKI 311 * content. If valid, we add it as a trusted root (trust anchor) to 312 * "store". 313 * 314 * This returns a certificate (which must not be freed) or NULL on 315 * parse failure. 316 */ 317 static struct cert * 318 proc_parser_root_cert(const struct entity *entp, 319 X509_STORE *store, X509_STORE_CTX *ctx, 320 struct auth_tree *auths, struct crl_tree *crlt) 321 { 322 char subject[256]; 323 ASN1_TIME *notBefore, *notAfter; 324 X509_NAME *name; 325 struct cert *cert; 326 X509 *x509; 327 struct auth *na; 328 char *tal; 329 330 assert(entp->has_pkey); 331 332 /* Extract certificate data and X509. */ 333 334 cert = ta_parse(&x509, entp->file, entp->pkey, entp->pkeysz); 335 if (cert == NULL) 336 return NULL; 337 338 if ((name = X509_get_subject_name(x509)) == NULL) { 339 warnx("%s Unable to get certificate subject", entp->file); 340 goto badcert; 341 } 342 if (X509_NAME_oneline(name, subject, sizeof(subject)) == NULL) { 343 warnx("%s: Unable to parse certificate subject name", 344 entp->file); 345 goto badcert; 346 } 347 if ((notBefore = X509_get_notBefore(x509)) == NULL) { 348 warnx("%s: certificate has invalid notBefore, subject='%s'", 349 entp->file, subject); 350 goto badcert; 351 } 352 if ((notAfter = X509_get_notAfter(x509)) == NULL) { 353 warnx("%s: certificate has invalid notAfter, subject='%s'", 354 entp->file, subject); 355 goto badcert; 356 } 357 if (X509_cmp_current_time(notBefore) != -1) { 358 warnx("%s: certificate not yet valid, subject='%s'", entp->file, 359 subject); 360 goto badcert; 361 } 362 if (X509_cmp_current_time(notAfter) != 1) { 363 warnx("%s: certificate has expired, subject='%s'", entp->file, 364 subject); 365 goto badcert; 366 } 367 if (!valid_ta(entp->file, auths, cert)) { 368 warnx("%s: certificate not a valid ta, subject='%s'", 369 entp->file, subject); 370 goto badcert; 371 } 372 373 /* 374 * Add valid roots to the RPKI auth tree and as a trusted root 375 * for chain validation to the X509_STORE. 376 */ 377 378 cert->valid = 1; 379 380 na = malloc(sizeof(*na)); 381 if (na == NULL) 382 err(1, NULL); 383 384 if ((tal = strdup(entp->descr)) == NULL) 385 err(1, NULL); 386 387 na->parent = NULL; 388 na->cert = cert; 389 na->tal = tal; 390 na->fn = strdup(entp->file); 391 if (na->fn == NULL) 392 err(1, NULL); 393 394 if (RB_INSERT(auth_tree, auths, na) != NULL) 395 err(1, "auth tree corrupted"); 396 397 X509_STORE_add_cert(store, x509); 398 399 return cert; 400 badcert: 401 X509_free(x509); // needed? XXX 402 return cert; 403 } 404 405 /* 406 * Parse a certificate revocation list 407 * This simply parses the CRL content itself, optionally validating it 408 * within the digest if it comes from a manifest, then adds it to the 409 * store of CRLs. 410 */ 411 static void 412 proc_parser_crl(struct entity *entp, X509_STORE *store, 413 X509_STORE_CTX *ctx, struct crl_tree *crlt) 414 { 415 X509_CRL *x509_crl; 416 struct crl *crl; 417 418 if ((x509_crl = crl_parse(entp->file)) != NULL) { 419 if ((crl = malloc(sizeof(*crl))) == NULL) 420 err(1, NULL); 421 if ((crl->aki = x509_crl_get_aki(x509_crl, entp->file)) == 422 NULL) 423 errx(1, "x509_crl_get_aki failed"); 424 crl->x509_crl = x509_crl; 425 426 if (RB_INSERT(crl_tree, crlt, crl) != NULL) { 427 warnx("%s: duplicate AKI %s", entp->file, crl->aki); 428 free_crl(crl); 429 } 430 } 431 } 432 433 /* 434 * Parse a ghostbuster record 435 */ 436 static void 437 proc_parser_gbr(struct entity *entp, X509_STORE *store, 438 X509_STORE_CTX *ctx, struct auth_tree *auths, struct crl_tree *crlt) 439 { 440 struct gbr *gbr; 441 X509 *x509; 442 int c; 443 struct auth *a; 444 STACK_OF(X509) *chain; 445 STACK_OF(X509_CRL) *crls; 446 447 if ((gbr = gbr_parse(&x509, entp->file)) == NULL) 448 return; 449 450 a = valid_ski_aki(entp->file, auths, gbr->ski, gbr->aki); 451 452 build_chain(a, &chain); 453 build_crls(a, crlt, &crls); 454 455 assert(x509 != NULL); 456 if (!X509_STORE_CTX_init(ctx, store, x509, chain)) 457 cryptoerrx("X509_STORE_CTX_init"); 458 X509_STORE_CTX_set_flags(ctx, 459 X509_V_FLAG_IGNORE_CRITICAL | X509_V_FLAG_CRL_CHECK); 460 X509_STORE_CTX_set0_crls(ctx, crls); 461 462 if (X509_verify_cert(ctx) <= 0) { 463 c = X509_STORE_CTX_get_error(ctx); 464 if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL) 465 warnx("%s: %s", entp->file, 466 X509_verify_cert_error_string(c)); 467 } 468 469 X509_STORE_CTX_cleanup(ctx); 470 sk_X509_free(chain); 471 sk_X509_CRL_free(crls); 472 X509_free(x509); 473 gbr_free(gbr); 474 } 475 476 /* 477 * Use the parent to walk the tree to the root and build a certificate 478 * chain from cert->x509. Do not include the root node since this node 479 * should already be in the X509_STORE as a trust anchor. 480 */ 481 static void 482 build_chain(const struct auth *a, STACK_OF(X509) **chain) 483 { 484 *chain = NULL; 485 486 if (a == NULL) 487 return; 488 489 if ((*chain = sk_X509_new_null()) == NULL) 490 err(1, "sk_X509_new_null"); 491 for (; a->parent != NULL; a = a->parent) { 492 assert(a->cert->x509 != NULL); 493 if (!sk_X509_push(*chain, a->cert->x509)) 494 errx(1, "sk_X509_push"); 495 } 496 } 497 498 /* 499 * Add the CRL based on the certs SKI value. 500 * No need to insert any other CRL since those were already checked. 501 */ 502 static void 503 build_crls(const struct auth *a, struct crl_tree *crlt, 504 STACK_OF(X509_CRL) **crls) 505 { 506 struct crl find, *found; 507 508 *crls = NULL; 509 510 if (a == NULL) 511 return; 512 513 if ((*crls = sk_X509_CRL_new_null()) == NULL) 514 errx(1, "sk_X509_CRL_new_null"); 515 516 find.aki = a->cert->ski; 517 found = RB_FIND(crl_tree, crlt, &find); 518 if (found && !sk_X509_CRL_push(*crls, found->x509_crl)) 519 err(1, "sk_X509_CRL_push"); 520 } 521 522 /* 523 * Process responsible for parsing and validating content. 524 * All this process does is wait to be told about a file to parse, then 525 * it parses it and makes sure that the data being returned is fully 526 * validated and verified. 527 * The process will exit cleanly only when fd is closed. 528 */ 529 void 530 proc_parser(int fd) 531 { 532 struct tal *tal; 533 struct cert *cert; 534 struct mft *mft; 535 struct roa *roa; 536 struct entity *entp; 537 struct entityq q; 538 int c, rc = 1; 539 struct msgbuf msgq; 540 struct pollfd pfd; 541 struct ibuf *b; 542 X509_STORE *store; 543 X509_STORE_CTX *ctx; 544 struct auth_tree auths = RB_INITIALIZER(&auths); 545 struct crl_tree crlt = RB_INITIALIZER(&crlt); 546 547 ERR_load_crypto_strings(); 548 OpenSSL_add_all_ciphers(); 549 OpenSSL_add_all_digests(); 550 551 if ((store = X509_STORE_new()) == NULL) 552 cryptoerrx("X509_STORE_new"); 553 if ((ctx = X509_STORE_CTX_new()) == NULL) 554 cryptoerrx("X509_STORE_CTX_new"); 555 556 TAILQ_INIT(&q); 557 558 msgbuf_init(&msgq); 559 msgq.fd = fd; 560 561 pfd.fd = fd; 562 563 io_socket_nonblocking(pfd.fd); 564 565 for (;;) { 566 pfd.events = POLLIN; 567 if (msgq.queued) 568 pfd.events |= POLLOUT; 569 570 if (poll(&pfd, 1, INFTIM) == -1) 571 err(1, "poll"); 572 if ((pfd.revents & (POLLERR|POLLNVAL))) 573 errx(1, "poll: bad descriptor"); 574 575 /* If the parent closes, return immediately. */ 576 577 if ((pfd.revents & POLLHUP)) 578 break; 579 580 /* 581 * Start with read events. 582 * This means that the parent process is sending us 583 * something we need to parse. 584 * We don't actually parse it til we have space in our 585 * outgoing buffer for responding, though. 586 */ 587 588 if ((pfd.revents & POLLIN)) { 589 io_socket_blocking(fd); 590 entp = calloc(1, sizeof(struct entity)); 591 if (entp == NULL) 592 err(1, NULL); 593 entity_read_req(fd, entp); 594 TAILQ_INSERT_TAIL(&q, entp, entries); 595 io_socket_nonblocking(fd); 596 } 597 598 if (pfd.revents & POLLOUT) { 599 switch (msgbuf_write(&msgq)) { 600 case 0: 601 errx(1, "write: connection closed"); 602 case -1: 603 err(1, "write"); 604 } 605 } 606 607 /* 608 * If there's nothing to parse, then stop waiting for 609 * the write signal. 610 */ 611 612 if (TAILQ_EMPTY(&q)) { 613 pfd.events &= ~POLLOUT; 614 continue; 615 } 616 617 entp = TAILQ_FIRST(&q); 618 assert(entp != NULL); 619 620 if ((b = ibuf_dynamic(256, UINT_MAX)) == NULL) 621 err(1, NULL); 622 io_simple_buffer(b, &entp->type, sizeof(entp->type)); 623 624 switch (entp->type) { 625 case RTYPE_TAL: 626 if ((tal = tal_parse(entp->file, entp->descr)) == NULL) 627 goto out; 628 tal_buffer(b, tal); 629 tal_free(tal); 630 break; 631 case RTYPE_CER: 632 if (entp->has_pkey) 633 cert = proc_parser_root_cert(entp, store, ctx, 634 &auths, &crlt); 635 else 636 cert = proc_parser_cert(entp, store, ctx, 637 &auths, &crlt); 638 c = (cert != NULL); 639 io_simple_buffer(b, &c, sizeof(int)); 640 if (cert != NULL) 641 cert_buffer(b, cert); 642 /* 643 * The parsed certificate data "cert" is now 644 * managed in the "auths" table, so don't free 645 * it here (see the loop after "out"). 646 */ 647 break; 648 case RTYPE_MFT: 649 mft = proc_parser_mft(entp, store, ctx, &auths, &crlt); 650 c = (mft != NULL); 651 io_simple_buffer(b, &c, sizeof(int)); 652 if (mft != NULL) 653 mft_buffer(b, mft); 654 mft_free(mft); 655 break; 656 case RTYPE_CRL: 657 proc_parser_crl(entp, store, ctx, &crlt); 658 break; 659 case RTYPE_ROA: 660 roa = proc_parser_roa(entp, store, ctx, &auths, &crlt); 661 c = (roa != NULL); 662 io_simple_buffer(b, &c, sizeof(int)); 663 if (roa != NULL) 664 roa_buffer(b, roa); 665 roa_free(roa); 666 break; 667 case RTYPE_GBR: 668 proc_parser_gbr(entp, store, ctx, &auths, &crlt); 669 break; 670 default: 671 abort(); 672 } 673 674 ibuf_close(&msgq, b); 675 TAILQ_REMOVE(&q, entp, entries); 676 entity_free(entp); 677 } 678 679 rc = 0; 680 out: 681 while ((entp = TAILQ_FIRST(&q)) != NULL) { 682 TAILQ_REMOVE(&q, entp, entries); 683 entity_free(entp); 684 } 685 686 /* XXX free auths and crl tree */ 687 688 X509_STORE_CTX_free(ctx); 689 X509_STORE_free(store); 690 691 msgbuf_clear(&msgq); 692 693 exit(rc); 694 } 695