From a49f98bb500a13cd0eaf3710623fdab5ebf09962 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Tue, 25 Aug 2026 15:52:58 +0200 Subject: [PATCH] Fix TlsSessionTests TLS resume flakiness by using a unique SNI ServerSession_TlsResume_HonorsAllowTlsResumeOption used the server certificate's name as the client TargetHost. The client-side OpenSSL session cache lives on a process-wide SSL_CTX keyed only by protocols and client certificate, and holds a single session per SNI name, so a test running concurrently in the same assembly could overwrite the cached ticket with one issued by its own server. The second handshake then offered a ticket this server could not decrypt, falling back to a full handshake with a larger ClientHello. Use a unique SNI name per run, matching SslStreamTlsResumeTests. Fixes #132111 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../tests/FunctionalTests/TlsSessionTests.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs index 7864c7e5407bf7..1f141dbff82495 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TlsSessionTests.cs @@ -179,7 +179,13 @@ public async Task ServerSession_TlsResume_HonorsAllowTlsResumeOption(SslProtocol } using X509Certificate2 serverCert = TestCertificates.GetServerCertificate(); - string serverName = serverCert.GetNameInfo(X509NameType.SimpleName, forIssuer: false); + + // Use a unique SNI name, as SslStreamTlsResumeTests does. The client-side session cache + // lives on a process-wide SSL_CTX shared by every client with the same protocols and + // client certificate, and holds a single session per SNI name. With the certificate + // name, a test running concurrently in this assembly can overwrite our cached ticket + // with one issued by its own server, which this server then cannot decrypt. + string targetHost = Guid.NewGuid().ToString("N"); using TlsContext serverCtx = TlsContext.CreateServer(new SslServerAuthenticationOptions { @@ -189,8 +195,8 @@ public async Task ServerSession_TlsResume_HonorsAllowTlsResumeOption(SslProtocol AllowTlsResume = allowResume, }); - long bytes1 = await MeasureHandshakeBytesAsync(serverCtx, serverName, protocol); - long bytes2 = await MeasureHandshakeBytesAsync(serverCtx, serverName, protocol); + long bytes1 = await MeasureHandshakeBytesAsync(serverCtx, targetHost, protocol); + long bytes2 = await MeasureHandshakeBytesAsync(serverCtx, targetHost, protocol); if (allowResume) { @@ -211,7 +217,7 @@ public async Task ServerSession_TlsResume_HonorsAllowTlsResumeOption(SslProtocol } } - private static async Task MeasureHandshakeBytesAsync(TlsContext serverCtx, string serverName, SslProtocols protocol) + private static async Task MeasureHandshakeBytesAsync(TlsContext serverCtx, string targetHost, SslProtocols protocol) { (Socket cs, Socket ss) = await CreateLoopbackSocketPairAsync(); using (cs) @@ -224,7 +230,7 @@ private static async Task MeasureHandshakeBytesAsync(TlsContext serverCtx, Task clientHandshake = clientSsl.AuthenticateAsClientAsync(new SslClientAuthenticationOptions { - TargetHost = serverName, + TargetHost = targetHost, EnabledSslProtocols = protocol, RemoteCertificateValidationCallback = TestHelper.AllowAnyServerCertificate, });