summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_vfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index fb87877e72..11bf3d9292 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.103 2022/08/31 07:15:31 tb Exp $ */ 1/* $OpenBSD: x509_vfy.c,v 1.104 2022/11/13 18:37:32 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 *
@@ -724,6 +724,43 @@ get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
724 return 0; 724 return 0;
725} 725}
726 726
727/*
728 * X509_check_purpose is special.
729 * 0 is bad, 1 is good, values > 1 are maybe good for web pki necromancy
730 * and certificates that were checked into software unit tests years ago
731 * that nobody knows how to change. (Netscape Server Gated Crypto Forever!)
732 */
733#define PURPOSE_GOOD(x) (x == 1)
734#define PURPOSE_BAD(x) (x == 0)
735static int
736check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
737 int must_be_ca)
738{
739 int purpose_check, trust;
740
741 purpose_check = X509_check_purpose(x, purpose, must_be_ca > 0);
742 trust = X509_TRUST_UNTRUSTED;
743
744 /*
745 * For trusted certificates we want to see whether any auxiliary trust
746 * settings for the desired purpose override the purpose constraints
747 * from the certificate EKU.
748 */
749 if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose)
750 trust = x509_check_trust_no_compat(x, ctx->param->trust, 0);
751
752 /* XXX STRICT should really be the default */
753 if (trust != X509_TRUST_REJECTED && !PURPOSE_BAD(purpose_check)) {
754 return PURPOSE_GOOD(purpose_check) ||
755 (ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0;
756 }
757
758 ctx->error = X509_V_ERR_INVALID_PURPOSE;
759 ctx->error_depth = depth;
760 ctx->current_cert = x;
761 return ctx->verify_cb(0, ctx);
762}
763
727/* Check a certificate chains extensions for consistency 764/* Check a certificate chains extensions for consistency
728 * with the supplied purpose 765 * with the supplied purpose
729 */ 766 */
@@ -740,6 +777,7 @@ x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx)
740 int proxy_path_length = 0; 777 int proxy_path_length = 0;
741 int purpose; 778 int purpose;
742 int allow_proxy_certs; 779 int allow_proxy_certs;
780 size_t chain_len;
743 781
744 cb = ctx->verify_cb; 782 cb = ctx->verify_cb;
745 783
@@ -763,8 +801,8 @@ x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx)
763 purpose = ctx->param->purpose; 801 purpose = ctx->param->purpose;
764 } 802 }
765 803
766 /* Check all untrusted certificates */ 804 chain_len = sk_X509_num(ctx->chain);
767 for (i = 0; i < ctx->num_untrusted; i++) { 805 for (i = 0; i < chain_len; i++) {
768 int ret; 806 int ret;
769 x = sk_X509_value(ctx->chain, i); 807 x = sk_X509_value(ctx->chain, i);
770 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && 808 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
@@ -818,6 +856,11 @@ x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx)
818 if (!ok) 856 if (!ok)
819 goto end; 857 goto end;
820 } 858 }
859 if (purpose > 0) {
860 ok = check_purpose(ctx, x, purpose, i, must_be_ca);
861 if (!ok)
862 goto end;
863 }
821 if (ctx->param->purpose > 0) { 864 if (ctx->param->purpose > 0) {
822 ret = X509_check_purpose(x, purpose, must_be_ca > 0); 865 ret = X509_check_purpose(x, purpose, must_be_ca > 0);
823 if ((ret == 0) || 866 if ((ret == 0) ||