summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2026-03-31 13:58:05 +0000
committerjsing <>2026-03-31 13:58:05 +0000
commit78103634af9a3c6964b84982770f7a76f56e8c2c (patch)
tree6f566df43eb3a05d4615a70ba33def7dad528041 /src
parent848a8ff0f8b9bd889cd059b6040b85d5cd2cc980 (diff)
downloadopenbsd-78103634af9a3c6964b84982770f7a76f56e8c2c.tar.gz
openbsd-78103634af9a3c6964b84982770f7a76f56e8c2c.tar.bz2
openbsd-78103634af9a3c6964b84982770f7a76f56e8c2c.zip
Fix an off-by-one error in the X.509 verifier depth checking.
In x509_verify_build_chains(), ensure that we check the current depth against max_depth prior to turning it into a legacy-style depth index. Additionally, add a guard to x509_verify_chain_append() so that we avoid exceeding the maximum certs per chain, even if we fail to handle this correctly elsewhere. Also prevent the legacy callback from being able to override the maximum verification depth. The current off-by-one allows for a 4 byte overwrite to occur on heap allocated memory - this will likely trigger a crash on OpenBSD (but may go unnoticed elsewhere). This is only reachable if a TLS client is talking to a malicious server or if a TLS server has client certificate verification enabled - in both cases the verification depth also needs to be set to the maximum allowed value of 32. It is worth noting that many TLS clients/servers set the maximum verification depth to a value that is much less than the default. A libtls client or server uses a default depth of 6 and is not impacted in this configuration. Thanks to Calif.io in collaboration with Claude and Anthropic Research, for reporting the issue. ok tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
index f25e2b3f15..a530275ac9 100644
--- a/src/lib/libcrypto/x509/x509_verify.c
+++ b/src/lib/libcrypto/x509/x509_verify.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_verify.c,v 1.73 2025/02/08 10:12:00 tb Exp $ */ 1/* $OpenBSD: x509_verify.c,v 1.74 2026/03/31 13:58:05 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -155,6 +155,11 @@ x509_verify_chain_append(struct x509_verify_chain *chain, X509 *cert,
155 int verify_err = X509_V_ERR_UNSPECIFIED; 155 int verify_err = X509_V_ERR_UNSPECIFIED;
156 size_t idx; 156 size_t idx;
157 157
158 if (sk_X509_num(chain->certs) >= X509_VERIFY_MAX_CHAIN_CERTS) {
159 *error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
160 return 0;
161 }
162
158 if (!x509_constraints_extract_names(chain->names, cert, 163 if (!x509_constraints_extract_names(chain->names, cert,
159 sk_X509_num(chain->certs) == 0, &verify_err)) { 164 sk_X509_num(chain->certs) == 0, &verify_err)) {
160 *error = verify_err; 165 *error = verify_err;
@@ -661,14 +666,14 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
661 return; 666 return;
662 667
663 depth = sk_X509_num(current_chain->certs); 668 depth = sk_X509_num(current_chain->certs);
669 if (depth >= ctx->max_depth) {
670 (void)x509_verify_cert_error(ctx, cert, depth,
671 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
672 return;
673 }
664 if (depth > 0) 674 if (depth > 0)
665 depth--; 675 depth--;
666 676
667 if (depth >= ctx->max_depth &&
668 !x509_verify_cert_error(ctx, cert, depth,
669 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0))
670 return;
671
672 count = ctx->chains_count; 677 count = ctx->chains_count;
673 678
674 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; 679 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;