preserve TargetHostName even if we do not send it out via SNI (#89289)
authorTomas Weinfurt <tweinfurt@yahoo.com>
Thu, 3 Aug 2023 18:13:59 +0000 (11:13 -0700)
committerGitHub <noreply@github.com>
Thu, 3 Aug 2023 18:13:59 +0000 (11:13 -0700)
* preserve TargetHostName even if we do not send it out via SNI

* Update src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs

Co-authored-by: campersau <buchholz.bastian@googlemail.com>
* quic

* test

---------

Co-authored-by: campersau <buchholz.bastian@googlemail.com>
src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs
src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs
src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs
src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs

index 3923c9e..c5f4305 100644 (file)
@@ -380,7 +380,7 @@ internal static partial class Interop
 
                 if (sslAuthenticationOptions.IsClient)
                 {
-                    if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost))
+                    if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !TargetHostNameHelper.IsValidAddress(sslAuthenticationOptions.TargetHost))
                     {
                         // Similar to windows behavior, set SNI on openssl by default for client context, ignore errors.
                         if (!Ssl.SslSetTlsExtHostName(sslHandle, sslAuthenticationOptions.TargetHost))
index f8964b5..cccdda4 100644 (file)
@@ -302,23 +302,21 @@ public sealed partial class QuicConnection : IAsyncDisposable
                 MsQuicHelpers.SetMsQuicParameter(_handle, QUIC_PARAM_CONN_LOCAL_ADDRESS, quicAddress);
             }
 
-            // RFC 6066 forbids IP literals
-            // DNI mapping is handled by MsQuic
-            string hostname = TargetHostNameHelper.IsValidAddress(options.ClientAuthenticationOptions.TargetHost)
-                ? string.Empty
-                : options.ClientAuthenticationOptions.TargetHost ?? string.Empty;
-
             _sslConnectionOptions = new SslConnectionOptions(
                 this,
                 isClient: true,
-                hostname,
+                options.ClientAuthenticationOptions.TargetHost ?? string.Empty,
                 certificateRequired: true,
                 options.ClientAuthenticationOptions.CertificateRevocationCheckMode,
                 options.ClientAuthenticationOptions.RemoteCertificateValidationCallback,
                 options.ClientAuthenticationOptions.CertificateChainPolicy?.Clone());
             _configuration = MsQuicConfiguration.Create(options);
 
-            IntPtr targetHostPtr = Marshal.StringToCoTaskMemUTF8(options.ClientAuthenticationOptions.TargetHost ?? host ?? address?.ToString());
+            // RFC 6066 forbids IP literals
+            // DNI mapping is handled by MsQuic
+            string sni = (TargetHostNameHelper.IsValidAddress(options.ClientAuthenticationOptions.TargetHost) ? null : options.ClientAuthenticationOptions.TargetHost) ?? host ?? address?.ToString() ?? string.Empty;
+
+            IntPtr targetHostPtr = Marshal.StringToCoTaskMemUTF8(sni);
             try
             {
                 unsafe
index 0471fdb..2b18c84 100644 (file)
@@ -1359,7 +1359,7 @@ namespace System.Net.Quic.Tests
             await using (clientConnection)
             await using (serverConnection)
             {
-                Assert.Equal(expectedHostName, clientConnection.TargetHostName);
+                Assert.Equal(hostname, clientConnection.TargetHostName);
                 Assert.Equal(expectedHostName, serverConnection.TargetHostName);
             }
         }
index 5005b83..375c8b9 100644 (file)
@@ -252,7 +252,7 @@ namespace System.Net
                 Interop.AndroidCrypto.SSLStreamRequestClientAuthentication(handle);
             }
 
-            if (!isServer && !string.IsNullOrEmpty(authOptions.TargetHost))
+            if (!isServer && !string.IsNullOrEmpty(authOptions.TargetHost) && !TargetHostNameHelper.IsValidAddress(authOptions.TargetHost))
             {
                 Interop.AndroidCrypto.SSLStreamSetTargetHost(handle, authOptions.TargetHost);
             }
index 6cc2077..9071d58 100644 (file)
@@ -95,7 +95,7 @@ namespace System.Net
                 throw;
             }
 
-            if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer)
+            if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer && !TargetHostNameHelper.IsValidAddress(sslAuthenticationOptions.TargetHost))
             {
                 Interop.AppleCrypto.SslSetTargetName(_sslContext, sslAuthenticationOptions.TargetHost);
             }
index 6702c91..06e883e 100644 (file)
@@ -49,11 +49,7 @@ namespace System.Net.Security
             IsServer = false;
             RemoteCertRequired = true;
             CertificateContext = sslClientAuthenticationOptions.ClientCertificateContext;
-
-            // RFC 6066 forbids IP literals
-            TargetHost = TargetHostNameHelper.IsValidAddress(sslClientAuthenticationOptions.TargetHost)
-                ? string.Empty
-                : sslClientAuthenticationOptions.TargetHost ?? string.Empty;
+            TargetHost = sslClientAuthenticationOptions.TargetHost ?? string.Empty;
 
             // Client specific options.
             CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode;
index 806f351..20279b6 100644 (file)
@@ -203,7 +203,7 @@ namespace System.Net.Security.Tests
                         server.AuthenticateAsServerAsync(serverOptions, default));
 
             Assert.Equal(string.Empty, server.TargetHostName);
-            Assert.Equal(string.Empty, client.TargetHostName);
+            Assert.Equal(target, client.TargetHostName);
         }
 
         [Theory]