Repository: dotnet/runtime
File: src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs (C#)

Code before:
                ;
            }
        }

        private static bool AllowAnyCertificate(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

        private X509Certificate ClientCertSelectionCallback(
            object sender,
            string targetHost,
            X509CertificateCollection localCertificates,
            X509Certificate remoteCertificate,
            string[] acceptableIssuers)
        {
            return _clientCertificate;
        }

        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.SupportsTls13))]
        [PlatformSpecific(TestPlatforms.Linux)] // Regression test for TLS 1.3 session resumption on OpenSSL
        public async Task SslStream_Tls13ResumptionWithClientCert_IsMutuallyAuthenticatedTrue()
        {
            // Use certificate context which enables session caching
            var serverContext = SslStreamCertificateContext.Create(_serverCertificate, null);
            var clientContext = SslStreamCertificateContext.Create(_clientCertificate, null);

            // Use a consistent target host to enable session resumption
            string targetHost = Guid.NewGuid().ToString("N");

            for (int i = 0; i < 3; i++)
            {
                (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
                using (client)
                using (server)
                {
                    var clientOptions = new SslClientAuthenticationOptions
                    {
                        TargetHost = targetHost,
                        ClientCertificateContext = clientContext,
                        EnabledSslProtocols = SslProtocols.Tls13,
                        RemoteCertificateValidationCallback = AllowAnyCertificate,
                    };

                    var serverOptions = new SslServerAuthenticationOptions
                    {
                        ServerCertificateContext = serverContext,

Review comment (security):
Feels like this case should be covered by SslStream_NegotiateClientCertificate_IsMutuallyAuthenticatedCorrect, it just needs to be run also for TLS 1.3.

Code after:
                ;
            }
        }

        [Theory]
        [ClassData(typeof(SslProtocolSupport.SupportedSslProtocolsTestData))]
        public async Task SslStream_Tls13ResumptionWithClientCert_IsMutuallyAuthenticatedTrue(
            SslProtocols protocol)
        {
            string targetHost = Guid.NewGuid().ToString("N");

            var clientOptions = new SslClientAuthenticationOptions
            {
                TargetHost = targetHost,
                ClientCertificates = new X509CertificateCollection { _clientCertificate },
                EnabledSslProtocols = protocol,
                RemoteCertificateValidationCallback = AllowAnyCertificate,
            };

            var serverOptions = new SslServerAuthenticationOptions
            {
                ServerCertificate = _serverCertificate,
                ClientCertificateRequired = true,
                EnabledSslProtocols = protocol,
                RemoteCertificateValidationCallback = AllowAnyCertificate,
            };

            for (int i = 0; i < 3; i++)
            {
                (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
                using (client)
                using (server)
                {
                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        client.AuthenticateAsClientAsync(clientOptions),
                        server.AuthenticateAsServerAsync(serverOptions));

                    // PingPong triggers new session ticket delivery (TLS 1.3)
                    await TestHelper.PingPong(client, server);

                    // Regression test: all connections (including resumed ones) must report mutual auth
                    Assert.True(client.IsMutuallyAuthenticated, $"Client connection {i}: IsMutuallyAuthenticated should be true");
                    Assert.True(server.IsMutuallyAuthenticated, $"Server connection {i}: IsMutuallyAuthenticated should be true");
                    Assert.NotNull(client.LocalCertificate);
                    Assert.NotNull(server.RemoteCertificate);

                    await client.ShutdownAsync();
                    await server.ShutdownAsync();
                }
            }
        }