Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ internal static partial class WinHttp
public const uint WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = 0x00000080;
public const uint WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = 0x00000200;
public const uint WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = 0x00000800;
public const uint WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 = 0x00002000;

public const uint SECURITY_FLAG_IGNORE_UNKNOWN_CA = 0x00000100;
public const uint SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProto
#if !NETFRAMEWORK
handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
#else
handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | (SslProtocols)12288;
#endif
#pragma warning restore 0618
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class WinHttpHandler : HttpMessageHandler

private static readonly StringWithQualityHeaderValue s_gzipHeaderValue = new StringWithQualityHeaderValue("gzip");
private static readonly StringWithQualityHeaderValue s_deflateHeaderValue = new StringWithQualityHeaderValue("deflate");
private static readonly Lazy<bool> s_supportsTls13 = new Lazy<bool>(CheckTls13Support());

[ThreadStatic]
private static StringBuilder? t_requestHeadersBuilder;
Expand Down Expand Up @@ -1153,6 +1154,7 @@ private void SetSessionHandleConnectionOptions(SafeWinHttpHandle sessionHandle)

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;
Expand Down Expand Up @@ -1184,10 +1186,13 @@ private void SetSessionHandleTlsOptions(SafeWinHttpHandle sessionHandle)
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
}

// As of Win10RS5 there's no public constant for WinHTTP + TLS 1.3
// This library builds against netstandard, which doesn't define the Tls13 enum field.
// Set this only if supported by WinHttp version.
if (s_supportsTls13.Value && (sslProtocols & Tls13) != 0)
{
optionData |= Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
}

// If only unknown values (e.g. TLS 1.3) were asked for, report ERROR_INVALID_PARAMETER.
// If only unknown values were asked for, report ERROR_INVALID_PARAMETER.
if (optionData == 0)
{
throw WinHttpException.CreateExceptionUsingError(
Expand All @@ -1198,6 +1203,30 @@ private void SetSessionHandleTlsOptions(SafeWinHttpHandle sessionHandle)
SetWinHttpOption(sessionHandle, Interop.WinHttp.WINHTTP_OPTION_SECURE_PROTOCOLS, ref optionData);
}

private static bool CheckTls13Support()
{
try
{
using (var handler = new WinHttpHandler())
using (SafeWinHttpHandle sessionHandle = Interop.WinHttp.WinHttpOpen(
IntPtr.Zero,
Interop.WinHttp.WINHTTP_ACCESS_TYPE_NO_PROXY,
Interop.WinHttp.WINHTTP_NO_PROXY_NAME,
Interop.WinHttp.WINHTTP_NO_PROXY_BYPASS,
(int)Interop.WinHttp.WINHTTP_FLAG_ASYNC))
{
uint optionData = Interop.WinHttp.WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;

handler.SetWinHttpOption(sessionHandle, Interop.WinHttp.WINHTTP_OPTION_SECURE_PROTOCOLS, ref optionData);
return true;
}
}
catch
{
return false;
}
}

private void SetSessionHandleTimeoutOptions(SafeWinHttpHandle sessionHandle)
{
if (!Interop.WinHttp.WinHttpSetTimeouts(
Expand Down