SSL vhost SNI policy: Fix handling of STRICT mode.

Resolves: RHEL-125880 - mod_ssl: allow more fine grained SSL SNI vhost check
to avoid unnecessary 421 errors after CVE-2025-23048 fix
This commit is contained in:
Luboš Uhliarik 2025-11-10 17:03:58 +01:00
parent f57ae09072
commit 0d46269f5b
2 changed files with 29 additions and 28 deletions

View File

@ -1,7 +1,7 @@
From ba168444686368377c6e69373e20e6dae8ebb702 Mon Sep 17 00:00:00 2001
From 165e748a40768183d5973c1f9866940bcbfc6ce8 Mon Sep 17 00:00:00 2001
From: Joe Orton <jorton@apache.org>
Date: Tue, 4 Nov 2025 12:49:36 +0100
Subject: [PATCH] [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the
Date: Mon, 10 Nov 2025 16:34:24 +0100
Subject: [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the
compatibility level required for VirtualHost matching.
For "secure" and "authonly" modes, a hash of the policy-relevant vhost
@ -26,16 +26,16 @@ the runtime code complexity (and overhead).
PR: 69743
GitHub: closes #561
---
docs/manual/mod/mod_ssl.html.en | 77 +++++++++++++++++++
docs/manual/mod/mod_ssl.html.en | 77 ++++++++++++++++++
modules/ssl/mod_ssl.c | 2 +
modules/ssl/ssl_engine_config.c | 41 ++++++++++
modules/ssl/ssl_engine_init.c | 107 ++++++++++++++++++++++++++
modules/ssl/ssl_engine_kernel.c | 131 ++++++--------------------------
modules/ssl/ssl_private.h | 17 +++++
6 files changed, 266 insertions(+), 109 deletions(-)
modules/ssl/ssl_engine_init.c | 107 +++++++++++++++++++++++++
modules/ssl/ssl_engine_kernel.c | 133 ++++++--------------------------
modules/ssl/ssl_private.h | 17 ++++
6 files changed, 267 insertions(+), 110 deletions(-)
diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en
index e2a4a99..95f0667 100644
index 8d83c42..cd62af2 100644
--- a/docs/manual/mod/mod_ssl.html.en
+++ b/docs/manual/mod/mod_ssl.html.en
@@ -125,6 +125,7 @@ to provide the cryptography engine.</p>
@ -202,7 +202,7 @@ index c5dce7f..f856b18 100644
const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd,
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 2fbd076..1bf6ac4 100644
index 5bf7a5b..6d89cc7 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -30,6 +30,7 @@
@ -334,7 +334,7 @@ index 2fbd076..1bf6ac4 100644
/*
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 33aa1f7..a6af633 100644
index 33aa1f7..83ae90e 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -101,112 +101,28 @@ static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc)
@ -371,7 +371,10 @@ index 33aa1f7..a6af633 100644
- }
- return 1;
-}
-
+ /* Policy: strict => fail for any vhost transition. */
+ if (policy == MODSSL_SNIVH_STRICT)
+ return sc1 == sc2;
-static int ssl_pk_server_compatible(modssl_pk_server_t *pks1,
- modssl_pk_server_t *pks2)
-{
@ -395,7 +398,10 @@ index 33aa1f7..a6af633 100644
- }
- return 1;
-}
-
+ /* For authonly/secure policy, compare the hash. */
+ AP_DEBUG_ASSERT(sc1->sni_policy_hash);
+ AP_DEBUG_ASSERT(sc2->sni_policy_hash);
-static int ssl_auth_compatible(modssl_auth_ctx_t *a1,
- modssl_auth_ctx_t *a2)
-{
@ -440,21 +446,16 @@ index 33aa1f7..a6af633 100644
- || (ctx1->protocol != ctx2->protocol)
- || !ssl_auth_compatible(&ctx1->auth, &ctx2->auth)
- || !ssl_pk_server_compatible(ctx1->pks, ctx2->pks)) {
+ /* Policy: strict => fail for any vhost transition. */
+ if (policy == MODSSL_SNIVH_STRICT && sc1 != sc2)
return 0;
- return 0;
- }
- return 1;
-}
-
-static int ssl_server_compatible(server_rec *s1, server_rec *s2)
-{
- SSLSrvConfigRec *sc1 = s1? mySrvConfig(s1) : NULL;
- SSLSrvConfigRec *sc2 = s2? mySrvConfig(s2) : NULL;
+ /* For authonly/secure policy, compare the hash. */
+ AP_DEBUG_ASSERT(sc1->sni_policy_hash);
+ AP_DEBUG_ASSERT(sc2->sni_policy_hash);
-
- /* both use the same TLS protocol? */
- if (!sc1 || !sc2
- || !ssl_ctx_compatible(sc1->server, sc2->server)) {
@ -500,10 +501,10 @@ index 33aa1f7..a6af633 100644
}
}
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 2b18189..dbef182 100644
index 58f0e95..a74e277 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -556,6 +556,19 @@ typedef struct {
@@ -548,6 +548,19 @@ typedef struct {
int nBytes;
} ssl_randseed_t;
@ -523,7 +524,7 @@ index 2b18189..dbef182 100644
/**
* Define the structure of an ASN.1 anything
*/
@@ -689,6 +702,8 @@ typedef struct {
@@ -681,6 +694,8 @@ typedef struct {
#ifdef HAVE_FIPS
BOOL fips;
#endif
@ -532,7 +533,7 @@ index 2b18189..dbef182 100644
} SSLModConfigRec;
/** Structure representing configured filenames for certs and keys for
@@ -843,6 +858,7 @@ struct SSLSrvConfigRec {
@@ -835,6 +850,7 @@ struct SSLSrvConfigRec {
modssl_ctx_t *server;
#ifdef HAVE_TLSEXT
ssl_enabled_t strict_sni_vhost_check;
@ -540,7 +541,7 @@ index 2b18189..dbef182 100644
#endif
#ifndef OPENSSL_NO_COMP
BOOL compression;
@@ -918,6 +934,7 @@ const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *);
@@ -910,6 +926,7 @@ const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg);
const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag);

View File

@ -25,7 +25,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.63
Release: 7%{?dist}
Release: 8%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc
@ -846,7 +846,7 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
* Thu Nov 06 2025 Luboš Uhliarik <luhliari@redhat.com> - 2.4.63-7
* Thu Nov 06 2025 Luboš Uhliarik <luhliari@redhat.com> - 2.4.63-8
- Resolves: RHEL-125880 - mod_ssl: allow more fine grained SSL SNI vhost check
to avoid unnecessary 421 errors after CVE-2025-23048 fix