summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/x509/x509_internal.h3
-rw-r--r--src/lib/libcrypto/x509/x509_trs.c20
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c49
3 files changed, 64 insertions, 8 deletions
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h
index beafd365ed..9e80b2d2cf 100644
--- a/src/lib/libcrypto/x509/x509_internal.h
+++ b/src/lib/libcrypto/x509/x509_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_internal.h,v 1.20 2022/11/11 12:02:34 beck Exp $ */ 1/* $OpenBSD: x509_internal.h,v 1.21 2022/11/13 18:37:32 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -134,6 +134,7 @@ int x509_constraints_check(struct x509_constraints_names *names,
134 struct x509_constraints_names *excluded, int *error); 134 struct x509_constraints_names *excluded, int *error);
135int x509_constraints_chain(STACK_OF(X509) *chain, int *error, 135int x509_constraints_chain(STACK_OF(X509) *chain, int *error,
136 int *depth); 136 int *depth);
137int x509_check_trust_no_compat(X509 *x, int id, int flags);
137void x509_verify_cert_info_populate(X509 *cert); 138void x509_verify_cert_info_populate(X509 *cert);
138int x509_vfy_check_security_level(X509_STORE_CTX *ctx); 139int x509_vfy_check_security_level(X509_STORE_CTX *ctx);
139 140
diff --git a/src/lib/libcrypto/x509/x509_trs.c b/src/lib/libcrypto/x509/x509_trs.c
index a967edf933..23eca4927b 100644
--- a/src/lib/libcrypto/x509/x509_trs.c
+++ b/src/lib/libcrypto/x509/x509_trs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_trs.c,v 1.26 2022/11/10 16:52:19 beck Exp $ */ 1/* $OpenBSD: x509_trs.c,v 1.27 2022/11/13 18:37:32 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999. 3 * project 1999.
4 */ 4 */
@@ -110,8 +110,8 @@ int
110 return oldtrust; 110 return oldtrust;
111} 111}
112 112
113int 113static int
114X509_check_trust(X509 *x, int id, int flags) 114X509_check_trust_internal(X509 *x, int id, int flags, int compat)
115{ 115{
116 X509_TRUST *pt; 116 X509_TRUST *pt;
117 int idx; 117 int idx;
@@ -132,7 +132,7 @@ X509_check_trust(X509 *x, int id, int flags)
132 rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); 132 rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
133 if (rv != X509_TRUST_UNTRUSTED) 133 if (rv != X509_TRUST_UNTRUSTED)
134 return rv; 134 return rv;
135 return trust_compat(NULL, x, 0); 135 return compat && trust_compat(NULL, x, 0);
136 } 136 }
137 idx = X509_TRUST_get_by_id(id); 137 idx = X509_TRUST_get_by_id(id);
138 if (idx == -1) 138 if (idx == -1)
@@ -142,6 +142,18 @@ X509_check_trust(X509 *x, int id, int flags)
142} 142}
143 143
144int 144int
145X509_check_trust(X509 *x, int id, int flags)
146{
147 return X509_check_trust_internal(x, id, flags, /*compat =*/1);
148}
149
150int
151x509_check_trust_no_compat(X509 *x, int id, int flags)
152{
153 return X509_check_trust_internal(x, id, flags, /*compat =*/0);
154}
155
156int
145X509_TRUST_get_count(void) 157X509_TRUST_get_count(void)
146{ 158{
147 if (!trtable) 159 if (!trtable)
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) ||