Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WinHTTP] Let OS chose SSL/TLS protocol if not set to WinHttpHandler #113525

Merged
merged 3 commits into from
Mar 17, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions src/libraries/Common/src/System/Net/SecurityProtocol.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -64,8 +64,6 @@ System.Net.Http.WinHttpHandler</PackageDescription>
Link="Common\System\Net\HttpKnownHeaderNames.TryGetHeaderName.cs" />
<Compile Include="$(CommonPath)System\Net\HttpStatusDescription.cs"
Link="Common\System\Net\Http\HttpStatusDescription.cs" />
<Compile Include="$(CommonPath)\System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)\System\Net\UriScheme.cs"
Link="Common\System\Net\UriScheme.cs" />
<Compile Include="$(CommonPath)\System\Net\Http\HttpHandlerDefaults.cs"
Original file line number Diff line number Diff line change
@@ -1176,40 +1176,43 @@ private void SetSessionHandleTlsOptions(SafeWinHttpHandle sessionHandle)
{
const SslProtocols Tls13 = (SslProtocols)12288; // enum is missing in .NET Standard
uint optionData = 0;
SslProtocols sslProtocols =
(_sslProtocols == SslProtocols.None) ? SecurityProtocol.DefaultSecurityProtocols : _sslProtocols;

if (_sslProtocols == SslProtocols.None)
{
return;
}

#pragma warning disable 0618 // SSL2/SSL3 are deprecated
if ((sslProtocols & SslProtocols.Ssl2) != 0)
if ((_sslProtocols & SslProtocols.Ssl2) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_SSL2;
}

if ((sslProtocols & SslProtocols.Ssl3) != 0)
if ((_sslProtocols & SslProtocols.Ssl3) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_SSL3;
}
#pragma warning restore 0618

#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete
if ((sslProtocols & SslProtocols.Tls) != 0)
if ((_sslProtocols & SslProtocols.Tls) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
}

if ((sslProtocols & SslProtocols.Tls11) != 0)
if ((_sslProtocols & SslProtocols.Tls11) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1;
}
#pragma warning restore SYSLIB0039

if ((sslProtocols & SslProtocols.Tls12) != 0)
if ((_sslProtocols & SslProtocols.Tls12) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
}

// Set this only if supported by WinHttp version.
if (s_supportsTls13.Value && (sslProtocols & Tls13) != 0)
if (s_supportsTls13.Value && (_sslProtocols & Tls13) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
}
Original file line number Diff line number Diff line change
@@ -40,8 +40,6 @@
Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
<Compile Include="$(CommonPath)System\Net\UriScheme.cs"
Link="Common\System\Net\UriScheme.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)System\Net\Http\HttpHandlerDefaults.cs"
Link="Common\System\Net\Http\HttpHandlerDefaults.cs" />
<Compile Include="$(CommonPath)\System\Net\Http\WinInetProxyHelper.cs"
4 changes: 0 additions & 4 deletions src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
@@ -391,8 +391,6 @@
Link="Common\System\Net\HttpKnownHeaderNames.cs" />
<Compile Include="$(CommonPath)\System\Net\HttpKnownHeaderNames.TryGetHeaderName.cs"
Link="Common\System\Net\HttpKnownHeaderNames.TryGetHeaderName.cs" />
<Compile Include="$(CommonPath)\System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)\System\Net\UriScheme.cs"
Link="Common\System\Net\UriScheme.cs" />
<Compile Include="$(CommonPath)\System\Net\Http\HttpHandlerDefaults.cs"
@@ -410,8 +408,6 @@
<ItemGroup Condition="'$(TargetPlatformIdentifier)' != '' and '$(TargetPlatformIdentifier)' != 'windows' and '$(TargetPlatformIdentifier)' != 'browser' and '$(TargetPlatformIdentifier)' != 'wasi'">
<Compile Include="$(CommonPath)System\StrongToWeakReference.cs"
Link="Common\Interop\Unix\StrongToWeakReference.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)System\Net\UriScheme.cs"
Link="Common\System\Net\UriScheme.cs" />
<Compile Include="$(CommonPath)Interop\Unix\Interop.Libraries.cs"
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@ internal sealed partial class HttpConnectionPool : IDisposable
public const int DefaultHttpPort = 80;
public const int DefaultHttpsPort = 443;

private static readonly bool s_isWindows7Or2008R2 = GetIsWindows7Or2008R2();
private static readonly List<SslApplicationProtocol> s_http3ApplicationProtocols = new List<SslApplicationProtocol>() { SslApplicationProtocol.Http3 };
private static readonly List<SslApplicationProtocol> s_http2ApplicationProtocols = new List<SslApplicationProtocol>() { SslApplicationProtocol.Http2, SslApplicationProtocol.Http11 };
private static readonly List<SslApplicationProtocol> s_http2OnlyApplicationProtocols = new List<SslApplicationProtocol>() { SslApplicationProtocol.Http2 };
@@ -277,20 +276,6 @@ private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnection
// Set TargetHost for SNI
sslOptions.TargetHost = sslHostName;

// Windows 7 and Windows 2008 R2 support TLS 1.1 and 1.2, but for legacy reasons by default those protocols
// are not enabled when a developer elects to use the system default. However, in .NET Core 2.0 and earlier,
// HttpClientHandler would enable them, due to being a wrapper for WinHTTP, which enabled them. Both for
// compatibility and because we prefer those higher protocols whenever possible, SocketsHttpHandler also
// pretends they're part of the default when running on Win7/2008R2.
if (s_isWindows7Or2008R2 && sslOptions.EnabledSslProtocols == SslProtocols.None)
{
if (NetEventSource.Log.IsEnabled())
{
NetEventSource.Info(poolManager, $"Win7OrWin2K8R2 platform, Changing default TLS protocols to {SecurityProtocol.DefaultSecurityProtocols}");
}
sslOptions.EnabledSslProtocols = SecurityProtocol.DefaultSecurityProtocols;
}

return sslOptions;
}

@@ -1026,19 +1011,6 @@ public bool CleanCacheAndDisposeIfUnused()
return false;
}

/// <summary>Gets whether we're running on Windows 7 or Windows 2008 R2.</summary>
private static bool GetIsWindows7Or2008R2()
{
OperatingSystem os = Environment.OSVersion;
if (os.Platform == PlatformID.Win32NT)
{
// Both Windows 7 and Windows 2008 R2 report version 6.1.
Version v = os.Version;
return v.Major == 6 && v.Minor == 1;
}
return false;
}

// For diagnostic purposes
public override string ToString() =>
$"{nameof(HttpConnectionPool)} " +
Original file line number Diff line number Diff line change
@@ -35,8 +35,6 @@
Link="ProductionCode\Common\System\Net\Logging\NetEventSource.Common.cs" />
<Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.Associate.cs"
Link="Common\System\Net\Logging\NetEventSource.Common.Associate.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="ProductionCode\Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)System\Net\UriScheme.cs"
Link="ProductionCode\Common\System\Net\UriScheme.cs" />
<Compile Include="$(CommonPath)System\Text\SimpleRegex.cs"
2 changes: 0 additions & 2 deletions src/libraries/System.Net.Mail/src/System.Net.Mail.csproj
Original file line number Diff line number Diff line change
@@ -118,8 +118,6 @@
Link="Common\System\Collections\Generic\BidirectionalDictionary.cs" />
<Compile Include="$(CommonPath)System\NotImplemented.cs"
Link="Common\System\NotImplemented.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
</ItemGroup>

<!-- Unix specific files -->
Original file line number Diff line number Diff line change
@@ -120,8 +120,6 @@
Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
<Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.Associate.cs"
Link="Common\System\Net\Logging\NetEventSource.Common.Associate.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)System\Net\DebugSafeHandleZeroOrMinusOneIsInvalid.cs"
Link="Common\System\Net\DebugSafeHandleZeroOrMinusOneIsInvalid.cs" />
<Compile Include="$(CommonPath)System\Net\DebugSafeHandle.cs"
Original file line number Diff line number Diff line change
@@ -81,8 +81,6 @@
Link="Common\System\Net\ContextAwareResult.cs" />
<Compile Include="$(CommonPath)System\Net\ExceptionCheck.cs"
Link="Common\System\Net\ExceptionCheck.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)System\NotImplemented.cs"
Link="Common\System\NotImplemented.cs" />
</ItemGroup>
Original file line number Diff line number Diff line change
@@ -98,8 +98,6 @@
</Compile>
<Compile Include="$(CommonPath)System\Net\ExceptionCheck.cs"
Link="Common\System\Net\ExceptionCheck.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<!-- Common -->
<Compile Include="$(CommonPath)System\NotImplemented.cs"
Link="Common\System\NotImplemented.cs" />
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ public class SslClientAuthenticationOptions
{
private EncryptionPolicy _encryptionPolicy = EncryptionPolicy.RequireEncryption;
private X509RevocationMode _checkCertificateRevocation = X509RevocationMode.NoCheck;
private SslProtocols _enabledSslProtocols = SecurityProtocol.SystemDefaultSecurityProtocols;
private SslProtocols _enabledSslProtocols = SslProtocols.None;
private bool _allowRenegotiation = true;
private bool _allowTlsResume = true;

Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ namespace System.Net.Security
public class SslServerAuthenticationOptions
{
private X509RevocationMode _checkCertificateRevocation = X509RevocationMode.NoCheck;
private SslProtocols _enabledSslProtocols = SecurityProtocol.SystemDefaultSecurityProtocols;
private SslProtocols _enabledSslProtocols = SslProtocols.None;
private EncryptionPolicy _encryptionPolicy = EncryptionPolicy.RequireEncryption;
private bool _allowRenegotiation;
private bool _allowTlsResume = true;
Original file line number Diff line number Diff line change
@@ -228,14 +228,14 @@ public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificat
//
public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, AsyncCallback? asyncCallback, object? asyncState)
{
return BeginAuthenticateAsClient(targetHost, null, SecurityProtocol.SystemDefaultSecurityProtocols, false,
return BeginAuthenticateAsClient(targetHost, null, SslProtocols.None, false,
asyncCallback, asyncState);
}

public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection? clientCertificates,
bool checkCertificateRevocation, AsyncCallback? asyncCallback, object? asyncState)
{
return BeginAuthenticateAsClient(targetHost, clientCertificates, SecurityProtocol.SystemDefaultSecurityProtocols, checkCertificateRevocation, asyncCallback, asyncState);
return BeginAuthenticateAsClient(targetHost, clientCertificates, SslProtocols.None, checkCertificateRevocation, asyncCallback, asyncState);
}

public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection? clientCertificates,
@@ -265,15 +265,15 @@ internal IAsyncResult BeginAuthenticateAsClient(SslClientAuthenticationOptions s
public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, AsyncCallback? asyncCallback, object? asyncState)

{
return BeginAuthenticateAsServer(serverCertificate, false, SecurityProtocol.SystemDefaultSecurityProtocols, false,
return BeginAuthenticateAsServer(serverCertificate, false, SslProtocols.None, false,
asyncCallback,
asyncState);
}

public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired,
bool checkCertificateRevocation, AsyncCallback? asyncCallback, object? asyncState)
{
return BeginAuthenticateAsServer(serverCertificate, clientCertificateRequired, SecurityProtocol.SystemDefaultSecurityProtocols, checkCertificateRevocation, asyncCallback, asyncState);
return BeginAuthenticateAsServer(serverCertificate, clientCertificateRequired, SslProtocols.None, checkCertificateRevocation, asyncCallback, asyncState);
}

public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired,
@@ -307,12 +307,12 @@ private IAsyncResult BeginAuthenticateAsServer(SslServerAuthenticationOptions ss
#region Synchronous methods
public virtual void AuthenticateAsClient(string targetHost)
{
AuthenticateAsClient(targetHost, null, SecurityProtocol.SystemDefaultSecurityProtocols, false);
AuthenticateAsClient(targetHost, null, SslProtocols.None, false);
}

public virtual void AuthenticateAsClient(string targetHost, X509CertificateCollection? clientCertificates, bool checkCertificateRevocation)
{
AuthenticateAsClient(targetHost, clientCertificates, SecurityProtocol.SystemDefaultSecurityProtocols, checkCertificateRevocation);
AuthenticateAsClient(targetHost, clientCertificates, SslProtocols.None, checkCertificateRevocation);
}

public virtual void AuthenticateAsClient(string targetHost, X509CertificateCollection? clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
@@ -341,12 +341,12 @@ public void AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthent

public virtual void AuthenticateAsServer(X509Certificate serverCertificate)
{
AuthenticateAsServer(serverCertificate, false, SecurityProtocol.SystemDefaultSecurityProtocols, false);
AuthenticateAsServer(serverCertificate, false, SslProtocols.None, false);
}

public virtual void AuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation)
{
AuthenticateAsServer(serverCertificate, clientCertificateRequired, SecurityProtocol.SystemDefaultSecurityProtocols, checkCertificateRevocation);
AuthenticateAsServer(serverCertificate, clientCertificateRequired, SslProtocols.None, checkCertificateRevocation);
}

public virtual void AuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
@@ -375,7 +375,7 @@ public void AuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthent
#region Task-based async public methods
public virtual Task AuthenticateAsClientAsync(string targetHost) => AuthenticateAsClientAsync(targetHost, null, false);

public virtual Task AuthenticateAsClientAsync(string targetHost, X509CertificateCollection? clientCertificates, bool checkCertificateRevocation) => AuthenticateAsClientAsync(targetHost, clientCertificates, SecurityProtocol.SystemDefaultSecurityProtocols, checkCertificateRevocation);
public virtual Task AuthenticateAsClientAsync(string targetHost, X509CertificateCollection? clientCertificates, bool checkCertificateRevocation) => AuthenticateAsClientAsync(targetHost, clientCertificates, SslProtocols.None, checkCertificateRevocation);

public virtual Task AuthenticateAsClientAsync(string targetHost, X509CertificateCollection? clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
@@ -401,7 +401,7 @@ public Task AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAu
}

public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate) =>
AuthenticateAsServerAsync(serverCertificate, false, SecurityProtocol.SystemDefaultSecurityProtocols, false);
AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.None, false);

public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation)
{
Original file line number Diff line number Diff line change
@@ -168,8 +168,6 @@
Link="ProductionCode\System\Net\SslStreamContext.cs" />
<Compile Include="..\..\src\System\Net\Security\SslCertificateTrust.cs"
Link="ProductionCode\System\Net\Security\SslCertificateTrust.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="ProductionCode\Common\System\Net\SecurityProtocol.cs" />
<Compile Include="..\..\src\System\Net\Security\TlsAlertType.cs"
Link="ProductionCode\Common\System\Net\TlsAlertType.cs" />
<Compile Include="..\..\src\System\Net\Security\TlsFrameHelper.cs"