From 29270dd9a9b8ab80a4f54aed8f54a6cb5115a99d Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Mon, 3 Aug 2026 16:40:14 +0200 Subject: [PATCH] Disable TLS resume in SslStreamServer_RejectsClientCert_ClientObservesAlert The test asserts that on OpenSSL TLS 1.2 the server's client certificate rejection surfaces mid-handshake as an AuthenticationException on the client. That contract only holds for a full handshake. The test did not disable TLS session resumption, so when a sibling test in the same assembly had populated the client session cache, the client did an abbreviated handshake. A resumed handshake carries no Certificate exchange and the server sends Finished before the user RemoteCertificateValidationCallback runs, so AuthenticateAsClientAsync completed and no exception was thrown. Set AllowTlsResume = false on both peers so the test always exercises the full handshake it documents. Fixes #131330 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../tests/FunctionalTests/TlsSessionTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs index f89ef77e44c6c1..f379c22651151b 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs @@ -405,6 +405,13 @@ public async Task ServerSession_MutualAuth_InitialHandshake_InvokesValidator() // completes; the rejection surfaces only on the first encrypted I/O after handshake // (TLS 1.3 per RFC 8446 ยง4.4.2.4; SChannel because the user callback fires after ASC). // This pins the protocol-level expectation against which TlsSession behavior is compared. + // + // AllowTlsResume is disabled on both peers because the mid-handshake rejection contract only + // holds for a full handshake. On an abbreviated (resumed) handshake there is no Certificate + // exchange, and the server sends its Finished before the user RemoteCertificateValidationCallback + // runs, so the client's AuthenticateAsClientAsync completes and the rejection surfaces post-hoc. + // Without this, a session cached by a sibling parallel test lets this client resume and the + // Tls12 row observes the post-hoc timing instead. [Theory] [InlineData(SslProtocols.Tls12)] [InlineData(SslProtocols.Tls13)] @@ -431,12 +438,14 @@ public async Task SslStreamServer_RejectsClientCert_ClientObservesAlert(SslProto { ServerCertificate = serverCert, EnabledSslProtocols = protocol, + AllowTlsResume = false, ClientCertificateRequired = true, }); Task clientAuth = clientSsl.AuthenticateAsClientAsync(new SslClientAuthenticationOptions { TargetHost = serverName, EnabledSslProtocols = protocol, + AllowTlsResume = false, ClientCertificates = new X509CertificateCollection { clientCert }, RemoteCertificateValidationCallback = TestHelper.AllowAnyServerCertificate, });