Skip to content

Commit

Permalink
use empty server name is client did not specify one (#39671)
Browse files Browse the repository at this point in the history
* use empty server name

* fix merge

* feedback from review

* add missing file
  • Loading branch information
wfurt authored Jul 28, 2020
1 parent 065bf96 commit 25c222b
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ public static bool SslCheckHostnameMatch(SafeSslHandle handle, string hostName,
// this code could be removed.
//
// It was verified as supporting case invariant match as of 10.12.1 (Sierra).
string matchName = s_idnMapping.GetAscii(hostName);
string matchName = string.IsNullOrEmpty(hostName) ? string.Empty : s_idnMapping.GetAscii(hostName);

using (SafeCFDateHandle cfNotBefore = CoreFoundation.CFDateCreate(notBefore))
using (SafeCreateHandle cfHostname = CoreFoundation.CFStringCreateWithCString(matchName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX50
if (!sslAuthenticationOptions.IsServer)
{
// The IdnMapping converts unicode input into the IDNA punycode sequence.
string punyCode = s_idnMapping.GetAscii(sslAuthenticationOptions.TargetHost!);
string punyCode = string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) ? string.Empty : s_idnMapping.GetAscii(sslAuthenticationOptions.TargetHost!);

// Similar to windows behavior, set SNI on openssl by default for client context, ignore errors.
if (!Ssl.SslSetTlsExtHostName(context, punyCode))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ namespace System.Net.Security
{
public partial class SslStream
{
private static int s_uniqueNameInteger = 123;

private SslAuthenticationOptions? _sslAuthenticationOptions;

private int _nestedAuth;
Expand Down Expand Up @@ -66,10 +64,6 @@ private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthe
try
{
_sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback);
if (_sslAuthenticationOptions.TargetHost!.Length == 0)
{
_sslAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
}
_context = new SecureChannel(_sslAuthenticationOptions, this);
}
catch (Win32Exception e)
Expand Down Expand Up @@ -420,12 +414,15 @@ private async ValueTask<ProtocolToken> ReceiveBlobAsync<TIOAdapter>(TIOAdapter a
if (_lastFrame.HandshakeType == TlsHandshakeType.ClientHello)
{
// SNI if it exist. Even if we could not parse the hello, we can fall-back to default certificate.
_sslAuthenticationOptions!.TargetHost = _lastFrame.TargetName;
if (_lastFrame.TargetName != null)
{
_sslAuthenticationOptions!.TargetHost = _lastFrame.TargetName;
}

if (_sslAuthenticationOptions.ServerOptionDelegate != null)
{
SslServerAuthenticationOptions userOptions =
await _sslAuthenticationOptions.ServerOptionDelegate(this, new SslClientHelloInfo(_lastFrame.TargetName, _lastFrame.SupportedVersions),
await _sslAuthenticationOptions.ServerOptionDelegate(this, new SslClientHelloInfo(_sslAuthenticationOptions.TargetHost, _lastFrame.SupportedVersions),
_sslAuthenticationOptions.UserState, adapter.CancellationToken).ConfigureAwait(false);
_sslAuthenticationOptions.UpdateOptions(userOptions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public async Task SslStream_NestedAuth_Throws()
[InlineData(true)]
public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName)
{
string tagetName = useEmptyName ? string.Empty : Guid.NewGuid().ToString("N");
string targetName = useEmptyName ? string.Empty : Guid.NewGuid().ToString("N");

(Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
using (clientStream)
Expand All @@ -218,19 +218,12 @@ public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName)
Assert.Equal(string.Empty, client.TargetHostName);
Assert.Equal(string.Empty, server.TargetHostName);

SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions() { TargetHost = tagetName };
SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions() { TargetHost = targetName };
clientOptions.RemoteCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
{
SslStream stream = (SslStream)sender;
if (useEmptyName)
{
Assert.Equal('?', stream.TargetHostName[0]);
}
else
{
Assert.Equal(tagetName, stream.TargetHostName);
}
Assert.Equal(targetName, stream.TargetHostName);

return true;
};
Expand All @@ -240,31 +233,16 @@ public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName)
(sender, name) =>
{
SslStream stream = (SslStream)sender;
if (useEmptyName)
{
Assert.Equal('?', stream.TargetHostName[0]);
}
else
{
Assert.Equal(tagetName, stream.TargetHostName);
}
Assert.Equal(targetName, stream.TargetHostName);

return certificate;
};

await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
client.AuthenticateAsClientAsync(clientOptions),
server.AuthenticateAsServerAsync(serverOptions));
if (useEmptyName)
{
Assert.Equal('?', client.TargetHostName[0]);
Assert.Equal('?', server.TargetHostName[0]);
}
else
{
Assert.Equal(tagetName, client.TargetHostName);
Assert.Equal(tagetName, server.TargetHostName);
}
Assert.Equal(targetName, client.TargetHostName);
Assert.Equal(targetName, server.TargetHostName);
}
}

Expand Down

0 comments on commit 25c222b

Please sign in to comment.