Skip to content

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

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

Merged
merged 3 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
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
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)} " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
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
Expand Up @@ -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 -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down