diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 228 |
1 files changed, 180 insertions, 48 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 28dbf60c38..b1cc9b5a00 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.c,v 1.74 2020/09/12 14:14:02 beck Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.75 2020/09/13 15:06:17 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -77,6 +77,7 @@ | |||
| 77 | #include "vpm_int.h" | 77 | #include "vpm_int.h" |
| 78 | #include "x509_internal.h" | 78 | #include "x509_internal.h" |
| 79 | #include "x509_lcl.h" | 79 | #include "x509_lcl.h" |
| 80 | #include "x509_internal.h" | ||
| 80 | 81 | ||
| 81 | /* CRL score values */ | 82 | /* CRL score values */ |
| 82 | 83 | ||
| @@ -124,7 +125,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx); | |||
| 124 | static int check_name_constraints(X509_STORE_CTX *ctx); | 125 | static int check_name_constraints(X509_STORE_CTX *ctx); |
| 125 | static int check_trust(X509_STORE_CTX *ctx); | 126 | static int check_trust(X509_STORE_CTX *ctx); |
| 126 | static int check_revocation(X509_STORE_CTX *ctx); | 127 | static int check_revocation(X509_STORE_CTX *ctx); |
| 127 | static int check_cert(X509_STORE_CTX *ctx); | 128 | static int check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth); |
| 128 | static int check_policy(X509_STORE_CTX *ctx); | 129 | static int check_policy(X509_STORE_CTX *ctx); |
| 129 | 130 | ||
| 130 | static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, | 131 | static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, |
| @@ -144,6 +145,7 @@ static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, | |||
| 144 | int clamp_notafter); | 145 | int clamp_notafter); |
| 145 | 146 | ||
| 146 | static int internal_verify(X509_STORE_CTX *ctx); | 147 | static int internal_verify(X509_STORE_CTX *ctx); |
| 148 | static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); | ||
| 147 | 149 | ||
| 148 | int ASN1_time_tm_clamp_notafter(struct tm *tm); | 150 | int ASN1_time_tm_clamp_notafter(struct tm *tm); |
| 149 | 151 | ||
| @@ -224,7 +226,21 @@ check_id(X509_STORE_CTX *ctx) | |||
| 224 | } | 226 | } |
| 225 | 227 | ||
| 226 | int | 228 | int |
| 227 | X509_verify_cert(X509_STORE_CTX *ctx) | 229 | x509_vfy_check_id(X509_STORE_CTX *ctx) { |
| 230 | return check_id(ctx); | ||
| 231 | } | ||
| 232 | |||
| 233 | /* | ||
| 234 | * This is the effectively broken legacy OpenSSL chain builder. It | ||
| 235 | * might find an unvalidated chain and leave it sitting in | ||
| 236 | * ctx->chain. It does not correctly handle many cases where multiple | ||
| 237 | * chains could exist. | ||
| 238 | * | ||
| 239 | * Oh no.. I know a dirty word... | ||
| 240 | * Oooooooh.. | ||
| 241 | */ | ||
| 242 | static int | ||
| 243 | X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad) | ||
| 228 | { | 244 | { |
| 229 | X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; | 245 | X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; |
| 230 | int bad_chain = 0; | 246 | int bad_chain = 0; |
| @@ -234,39 +250,6 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 234 | int (*cb) (int xok, X509_STORE_CTX *xctx); | 250 | int (*cb) (int xok, X509_STORE_CTX *xctx); |
| 235 | STACK_OF(X509) *sktmp = NULL; | 251 | STACK_OF(X509) *sktmp = NULL; |
| 236 | 252 | ||
| 237 | if (ctx->cert == NULL) { | ||
| 238 | X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); | ||
| 239 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 240 | return -1; | ||
| 241 | } | ||
| 242 | if (ctx->chain != NULL) { | ||
| 243 | /* | ||
| 244 | * This X509_STORE_CTX has already been used to verify | ||
| 245 | * a cert. We cannot do another one. | ||
| 246 | */ | ||
| 247 | X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 248 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 249 | return -1; | ||
| 250 | } | ||
| 251 | if (ctx->param->id->poisoned) { | ||
| 252 | /* | ||
| 253 | * This X509_STORE_CTX had failures setting | ||
| 254 | * up verify parameters. We can not use it. | ||
| 255 | */ | ||
| 256 | X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 257 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 258 | return -1; | ||
| 259 | } | ||
| 260 | if (ctx->error != X509_V_ERR_INVALID_CALL) { | ||
| 261 | /* | ||
| 262 | * This X509_STORE_CTX has not been properly initialized. | ||
| 263 | */ | ||
| 264 | X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 265 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 266 | return -1; | ||
| 267 | } | ||
| 268 | ctx->error = X509_V_OK; /* Initialize to OK */ | ||
| 269 | |||
| 270 | cb = ctx->verify_cb; | 253 | cb = ctx->verify_cb; |
| 271 | 254 | ||
| 272 | /* | 255 | /* |
| @@ -534,6 +517,23 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 534 | if (!ok) | 517 | if (!ok) |
| 535 | goto end; | 518 | goto end; |
| 536 | } | 519 | } |
| 520 | end: | ||
| 521 | sk_X509_free(sktmp); | ||
| 522 | X509_free(chain_ss); | ||
| 523 | *bad = bad_chain; | ||
| 524 | return ok; | ||
| 525 | } | ||
| 526 | |||
| 527 | static int | ||
| 528 | X509_verify_cert_legacy(X509_STORE_CTX *ctx) | ||
| 529 | { | ||
| 530 | int ok = 0, bad_chain; | ||
| 531 | |||
| 532 | ctx->error = X509_V_OK; /* Initialize to OK */ | ||
| 533 | |||
| 534 | ok = X509_verify_cert_legacy_build_chain(ctx, &bad_chain); | ||
| 535 | if (!ok) | ||
| 536 | goto end; | ||
| 537 | 537 | ||
| 538 | /* We have the chain complete: now we need to check its purpose */ | 538 | /* We have the chain complete: now we need to check its purpose */ |
| 539 | ok = check_chain_extensions(ctx); | 539 | ok = check_chain_extensions(ctx); |
| @@ -548,6 +548,7 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 548 | ok = check_id(ctx); | 548 | ok = check_id(ctx); |
| 549 | if (!ok) | 549 | if (!ok) |
| 550 | goto end; | 550 | goto end; |
| 551 | |||
| 551 | /* | 552 | /* |
| 552 | * Check revocation status: we do this after copying parameters because | 553 | * Check revocation status: we do this after copying parameters because |
| 553 | * they may be needed for CRL signature verification. | 554 | * they may be needed for CRL signature verification. |
| @@ -569,15 +570,125 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 569 | ok = ctx->check_policy(ctx); | 570 | ok = ctx->check_policy(ctx); |
| 570 | 571 | ||
| 571 | end: | 572 | end: |
| 572 | sk_X509_free(sktmp); | ||
| 573 | X509_free(chain_ss); | ||
| 574 | |||
| 575 | /* Safety net, error returns must set ctx->error */ | 573 | /* Safety net, error returns must set ctx->error */ |
| 576 | if (ok <= 0 && ctx->error == X509_V_OK) | 574 | if (ok <= 0 && ctx->error == X509_V_OK) |
| 577 | ctx->error = X509_V_ERR_UNSPECIFIED; | 575 | ctx->error = X509_V_ERR_UNSPECIFIED; |
| 576 | |||
| 578 | return ok; | 577 | return ok; |
| 579 | } | 578 | } |
| 580 | 579 | ||
| 580 | int | ||
| 581 | X509_verify_cert(X509_STORE_CTX *ctx) | ||
| 582 | { | ||
| 583 | STACK_OF(X509) *roots = NULL; | ||
| 584 | struct x509_verify_ctx *vctx = NULL; | ||
| 585 | int chain_count = 0; | ||
| 586 | |||
| 587 | if (ctx->cert == NULL) { | ||
| 588 | X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); | ||
| 589 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 590 | return -1; | ||
| 591 | } | ||
| 592 | if (ctx->chain != NULL) { | ||
| 593 | /* | ||
| 594 | * This X509_STORE_CTX has already been used to verify | ||
| 595 | * a cert. We cannot do another one. | ||
| 596 | */ | ||
| 597 | X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 598 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 599 | return -1; | ||
| 600 | } | ||
| 601 | if (ctx->param->id->poisoned) { | ||
| 602 | /* | ||
| 603 | * This X509_STORE_CTX had failures setting | ||
| 604 | * up verify parameters. We can not use it. | ||
| 605 | */ | ||
| 606 | X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 607 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 608 | return -1; | ||
| 609 | } | ||
| 610 | if (ctx->error != X509_V_ERR_INVALID_CALL) { | ||
| 611 | /* | ||
| 612 | * This X509_STORE_CTX has not been properly initialized. | ||
| 613 | */ | ||
| 614 | X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 615 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 616 | return -1; | ||
| 617 | } | ||
| 618 | |||
| 619 | /* | ||
| 620 | * If flags request legacy, use the legacy verifier. If we | ||
| 621 | * requested "no alt chains" from the age of hammer pants, use | ||
| 622 | * the legacy verifier because the multi chain verifier really | ||
| 623 | * does find all the "alt chains". | ||
| 624 | * | ||
| 625 | * XXX deprecate the NO_ALT_CHAINS flag? | ||
| 626 | */ | ||
| 627 | if ((ctx->param->flags & X509_V_FLAG_LEGACY_VERIFY) || | ||
| 628 | (ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) | ||
| 629 | return X509_verify_cert_legacy(ctx); | ||
| 630 | |||
| 631 | /* Use the modern multi-chain verifier from x509_verify_cert */ | ||
| 632 | |||
| 633 | /* Find our trusted roots */ | ||
| 634 | ctx->error = X509_V_ERR_OUT_OF_MEM; | ||
| 635 | |||
| 636 | if (ctx->get_issuer == get_issuer_sk) { | ||
| 637 | /* | ||
| 638 | * We are using the trusted stack method. so | ||
| 639 | * the roots are in the aptly named "ctx->other_ctx" | ||
| 640 | * pointer. (It could have been called "al") | ||
| 641 | */ | ||
| 642 | if ((roots = X509_chain_up_ref(ctx->other_ctx)) == NULL) | ||
| 643 | return -1; | ||
| 644 | } else { | ||
| 645 | /* | ||
| 646 | * We have a X509_STORE and need to pull out the roots. | ||
| 647 | * Don't look Ethel... | ||
| 648 | */ | ||
| 649 | STACK_OF(X509_OBJECT) *objs; | ||
| 650 | size_t i, good = 1; | ||
| 651 | |||
| 652 | if ((roots = sk_X509_new_null()) == NULL) | ||
| 653 | return -1; | ||
| 654 | |||
| 655 | CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | ||
| 656 | if ((objs = X509_STORE_get0_objects(ctx->ctx)) == NULL) | ||
| 657 | good = 0; | ||
| 658 | for (i = 0; good && i < sk_X509_OBJECT_num(objs); i++) { | ||
| 659 | X509_OBJECT *obj; | ||
| 660 | X509 *root; | ||
| 661 | obj = sk_X509_OBJECT_value(objs, i); | ||
| 662 | if (obj->type != X509_LU_X509) | ||
| 663 | continue; | ||
| 664 | root = obj->data.x509; | ||
| 665 | if (X509_up_ref(root) == 0) | ||
| 666 | good = 0; | ||
| 667 | if (sk_X509_push(roots, root) == 0) { | ||
| 668 | X509_free(root); | ||
| 669 | good = 0; | ||
| 670 | } | ||
| 671 | } | ||
| 672 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | ||
| 673 | |||
| 674 | if (!good) { | ||
| 675 | sk_X509_pop_free(roots, X509_free); | ||
| 676 | return -1; | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 680 | if ((vctx = x509_verify_ctx_new_from_xsc(ctx, roots)) != NULL) { | ||
| 681 | ctx->error = X509_V_OK; /* Initialize to OK */ | ||
| 682 | chain_count = x509_verify(vctx, NULL, NULL); | ||
| 683 | } | ||
| 684 | |||
| 685 | sk_X509_pop_free(roots, X509_free); | ||
| 686 | x509_verify_ctx_free(vctx); | ||
| 687 | |||
| 688 | /* if we succeed we have a chain in ctx->chain */ | ||
| 689 | return (chain_count > 0 && ctx->chain != NULL); | ||
| 690 | } | ||
| 691 | |||
| 581 | /* Given a STACK_OF(X509) find the issuer of cert (if any) | 692 | /* Given a STACK_OF(X509) find the issuer of cert (if any) |
| 582 | */ | 693 | */ |
| 583 | 694 | ||
| @@ -637,8 +748,8 @@ get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | |||
| 637 | * with the supplied purpose | 748 | * with the supplied purpose |
| 638 | */ | 749 | */ |
| 639 | 750 | ||
| 640 | static int | 751 | int |
| 641 | check_chain_extensions(X509_STORE_CTX *ctx) | 752 | x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx) |
| 642 | { | 753 | { |
| 643 | #ifdef OPENSSL_NO_CHAIN_VERIFY | 754 | #ifdef OPENSSL_NO_CHAIN_VERIFY |
| 644 | return 1; | 755 | return 1; |
| @@ -781,6 +892,11 @@ end: | |||
| 781 | } | 892 | } |
| 782 | 893 | ||
| 783 | static int | 894 | static int |
| 895 | check_chain_extensions(X509_STORE_CTX *ctx) { | ||
| 896 | return x509_vfy_check_chain_extensions(ctx); | ||
| 897 | } | ||
| 898 | |||
| 899 | static int | ||
| 784 | check_name_constraints(X509_STORE_CTX *ctx) | 900 | check_name_constraints(X509_STORE_CTX *ctx) |
| 785 | { | 901 | { |
| 786 | if (!x509_constraints_chain(ctx->chain, &ctx->error, | 902 | if (!x509_constraints_chain(ctx->chain, &ctx->error, |
| @@ -875,6 +991,11 @@ static int check_trust(X509_STORE_CTX *ctx) | |||
| 875 | return X509_TRUST_UNTRUSTED; | 991 | return X509_TRUST_UNTRUSTED; |
| 876 | } | 992 | } |
| 877 | 993 | ||
| 994 | int x509_vfy_check_trust(X509_STORE_CTX *ctx) | ||
| 995 | { | ||
| 996 | return check_trust(ctx); | ||
| 997 | } | ||
| 998 | |||
| 878 | static int | 999 | static int |
| 879 | check_revocation(X509_STORE_CTX *ctx) | 1000 | check_revocation(X509_STORE_CTX *ctx) |
| 880 | { | 1001 | { |
| @@ -891,24 +1012,29 @@ check_revocation(X509_STORE_CTX *ctx) | |||
| 891 | last = 0; | 1012 | last = 0; |
| 892 | } | 1013 | } |
| 893 | for (i = 0; i <= last; i++) { | 1014 | for (i = 0; i <= last; i++) { |
| 894 | ctx->error_depth = i; | 1015 | ok = check_cert(ctx, ctx->chain, i); |
| 895 | ok = check_cert(ctx); | ||
| 896 | if (!ok) | 1016 | if (!ok) |
| 897 | return ok; | 1017 | return ok; |
| 898 | } | 1018 | } |
| 899 | return 1; | 1019 | return 1; |
| 900 | } | 1020 | } |
| 901 | 1021 | ||
| 1022 | int | ||
| 1023 | x509_vfy_check_revocation(X509_STORE_CTX *ctx) | ||
| 1024 | { | ||
| 1025 | return check_revocation(ctx); | ||
| 1026 | } | ||
| 1027 | |||
| 902 | static int | 1028 | static int |
| 903 | check_cert(X509_STORE_CTX *ctx) | 1029 | check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth) |
| 904 | { | 1030 | { |
| 905 | X509_CRL *crl = NULL, *dcrl = NULL; | 1031 | X509_CRL *crl = NULL, *dcrl = NULL; |
| 906 | X509 *x; | 1032 | X509 *x; |
| 907 | int ok = 0, cnum; | 1033 | int ok = 0, cnum; |
| 908 | unsigned int last_reasons; | 1034 | unsigned int last_reasons; |
| 909 | 1035 | ||
| 910 | cnum = ctx->error_depth; | 1036 | cnum = ctx->error_depth = depth; |
| 911 | x = sk_X509_value(ctx->chain, cnum); | 1037 | x = sk_X509_value(chain, cnum); |
| 912 | ctx->current_cert = x; | 1038 | ctx->current_cert = x; |
| 913 | ctx->current_issuer = NULL; | 1039 | ctx->current_issuer = NULL; |
| 914 | ctx->current_crl_score = 0; | 1040 | ctx->current_crl_score = 0; |
| @@ -1660,8 +1786,8 @@ cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | |||
| 1660 | return 1; | 1786 | return 1; |
| 1661 | } | 1787 | } |
| 1662 | 1788 | ||
| 1663 | static int | 1789 | int |
| 1664 | check_policy(X509_STORE_CTX *ctx) | 1790 | x509_vfy_check_policy(X509_STORE_CTX *ctx) |
| 1665 | { | 1791 | { |
| 1666 | int ret; | 1792 | int ret; |
| 1667 | 1793 | ||
| @@ -1707,6 +1833,12 @@ check_policy(X509_STORE_CTX *ctx) | |||
| 1707 | return 1; | 1833 | return 1; |
| 1708 | } | 1834 | } |
| 1709 | 1835 | ||
| 1836 | static int | ||
| 1837 | check_policy(X509_STORE_CTX *ctx) | ||
| 1838 | { | ||
| 1839 | return x509_vfy_check_policy(ctx); | ||
| 1840 | } | ||
| 1841 | |||
| 1710 | /* | 1842 | /* |
| 1711 | * Inform the verify callback of an error. | 1843 | * Inform the verify callback of an error. |
| 1712 | * | 1844 | * |
