diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-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 | * |