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

Ubuntu18.04 net5.0 HttpClient SendAsync ignores timeout (via token), hangs for some time and eventually crash the app #45010

Closed
dvitel opened this issue Nov 20, 2020 · 19 comments · Fixed by #48221

Comments

@dvitel
Copy link

dvitel commented Nov 20, 2020

Description

Concrete site with this behavior: https://www.goszakup.gov.kz
Expected behavior (as tested on Windows) -
The remote certificate is invalid because of errors in the certificate chain: PartialChain
or at least timeout

Example:

        static async Task Main(string[] args)
        {        
            var sw = new Stopwatch();
            sw.Start();
            try {
                using var cl = new HttpClient();
                using var cts = new CancellationTokenSource(7000);
                var res = await cl.GetStringAsync("https://www.goszakup.gov.kz", cts.Token); 
                Console.WriteLine($"[{sw.Elapsed}] Res: {res}");
            } catch (Exception e) {
                sw.Stop(); //Never here
                Console.WriteLine($"[{sw.Elapsed}] Err: {e}.");
            }
        }

Configuration

.NET SDK (reflecting any global.json):
 Version:   5.0.100
 Commit:    5044b93829

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  18.04
 OS Platform: Linux
 RID:         ubuntu.18.04-x64
 Base Path:   /usr/share/dotnet/sdk/5.0.100/

Host (useful for support):
  Version: 5.0.0
  Commit:  cf258a14b7

.NET SDKs installed:
  2.1.810 [/usr/share/dotnet/sdk]
  2.2.402 [/usr/share/dotnet/sdk]
  3.0.103 [/usr/share/dotnet/sdk]
  5.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.22 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.22 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.10 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.22 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.10 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

OpenSSL 1.1.1 11 Sep 2018

Other information

Same behavior is for SendAsync or GetStringAsync.
Played with SocketsHttpHandler Ssl settings - did not help
On run, app hangs around for 30mins on my machine and then crashes with Aborted (core dumped)
The crash dump contains 10K lines of exception call stack - seems that there is a infinite recursion somewhere
here is two cycles of loop from exception:

   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)
   at System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<EstablishSslConnectionAsyncCore>d__4 ByRef)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean, System.IO.Stream, System.Net.Security.SslClientAuthenticationOptions, System.Threading.CancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(System.Net.Security.SslClientAuthenticationOptions, System.Net.Http.HttpRequestMessage, Boolean, System.IO.Stream, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ConnectAsync>d__82 ByRef)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<CreateHttp11ConnectionAsync>d__86 ByRef)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetHttpConnectionAsync>d__67 ByRef)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.GetConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendWithRetryAsync>d__72 ByRef)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithProxyAuthAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
   at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient+<SendAsyncCore>d__85.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<SendAsyncCore>d__85, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsyncCore>d__85 ByRef)
   at System.Net.Http.HttpClient.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Internal.Cryptography.Pal.CertificateAssetDownloader+<>c__DisplayClass5_0.<CreateDownloadBytesFunc>b__0(System.String, System.Threading.CancellationToken)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadAsset(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadCertificate(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.FindChainViaAia(System.Collections.Generic.List`1<System.Security.Cryptography.X509Certificates.X509Certificate2> ByRef)
   at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean, Internal.Cryptography.ICertificatePal, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.X509Certificates.X509RevocationMode, System.Security.Cryptography.X509Certificates.X509RevocationFlag, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.X509Certificates.X509ChainTrustMode, System.DateTime, System.TimeSpan, Boolean)
   at System.Security.Cryptography.X509Certificates.X509Chain.Build(System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
   at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(System.Security.Cryptography.X509Certificates.X509Chain, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean, System.String)
   at System.Net.Security.SecureChannel.VerifyRemoteCertificate(System.Net.Security.RemoteCertificateValidationCallback, System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream.CompleteHandshake(System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ForceAuthenticationAsync>d__171`1<System.Net.Security.SyncReadWriteAdapter> ByRef)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](System.Net.Security.SyncReadWriteAdapter, Boolean, Byte[], Boolean)
   at System.Net.Security.SslStream.ProcessAuthentication(Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)
   at System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<EstablishSslConnectionAsyncCore>d__4 ByRef)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean, System.IO.Stream, System.Net.Security.SslClientAuthenticationOptions, System.Threading.CancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(System.Net.Security.SslClientAuthenticationOptions, System.Net.Http.HttpRequestMessage, Boolean, System.IO.Stream, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ConnectAsync>d__82 ByRef)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<CreateHttp11ConnectionAsync>d__86 ByRef)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetHttpConnectionAsync>d__67 ByRef)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.GetConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendWithRetryAsync>d__72 ByRef)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithProxyAuthAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
   at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient+<SendAsyncCore>d__85.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<SendAsyncCore>d__85, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsyncCore>d__85 ByRef)
   at System.Net.Http.HttpClient.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Internal.Cryptography.Pal.CertificateAssetDownloader+<>c__DisplayClass5_0.<CreateDownloadBytesFunc>b__0(System.String, System.Threading.CancellationToken)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadAsset(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadCertificate(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.FindChainViaAia(System.Collections.Generic.List`1<System.Security.Cryptography.X509Certificates.X509Certificate2> ByRef)
   at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean, Internal.Cryptography.ICertificatePal, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.X509Certificates.X509RevocationMode, System.Security.Cryptography.X509Certificates.X509RevocationFlag, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.X509Certificates.X509ChainTrustMode, System.DateTime, System.TimeSpan, Boolean)
   at System.Security.Cryptography.X509Certificates.X509Chain.Build(System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
   at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(System.Security.Cryptography.X509Certificates.X509Chain, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean, System.String)
   at System.Net.Security.SecureChannel.VerifyRemoteCertificate(System.Net.Security.RemoteCertificateValidationCallback, System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream.CompleteHandshake(System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ForceAuthenticationAsync>d__171`1<System.Net.Security.SyncReadWriteAdapter> ByRef)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](System.Net.Security.SyncReadWriteAdapter, Boolean, Byte[], Boolean)
   at System.Net.Security.SslStream.ProcessAuthentication(Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)

crash is probably due to StackOverflow. If there is no fix but workaround exists (some global settings (like env) etc) - please share.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net.Http untriaged New issue has not been triaged by the area owner labels Nov 20, 2020
@ghost
Copy link

ghost commented Nov 20, 2020

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Concrete site with this behavior: https://www.goszakup.gov.kz
Expected behavior (as tested on Windows) -
The remote certificate is invalid because of errors in the certificate chain: PartialChain
or at least timeout

Example:

        static async Task Main(string[] args)
        {        
            var sw = new Stopwatch();
            sw.Start();
            try {
                using var cl = new HttpClient();
                using var cts = new CancellationTokenSource(7000);
                var res = await cl.GetStringAsync("https://www.goszakup.gov.kz", cts.Token); 
                Console.WriteLine($"[{sw.Elapsed}] Res: {res}");
            } catch (Exception e) {
                sw.Stop(); //Never here
                Console.WriteLine($"[{sw.Elapsed}] Err: {e}.");
            }
        }

Configuration

.NET SDK (reflecting any global.json):
 Version:   5.0.100
 Commit:    5044b93829

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  18.04
 OS Platform: Linux
 RID:         ubuntu.18.04-x64
 Base Path:   /usr/share/dotnet/sdk/5.0.100/

Host (useful for support):
  Version: 5.0.0
  Commit:  cf258a14b7

.NET SDKs installed:
  2.1.810 [/usr/share/dotnet/sdk]
  2.2.402 [/usr/share/dotnet/sdk]
  3.0.103 [/usr/share/dotnet/sdk]
  5.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.22 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.22 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.10 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.22 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.10 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

OpenSSL 1.1.1 11 Sep 2018

Other information

Same behavior is for SendAsync or GetStringAsync.
Played with SocketsHttpHandler Ssl settings - did not help
On run, app hangs around for 30mins on my machine and then crashes with Aborted (core dumped)
The crash dump contains 10K lines of exception call stack - seems that there is a infinite recursion somewhere
here is two cycles of loop from exception:

   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)
   at System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<EstablishSslConnectionAsyncCore>d__4 ByRef)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean, System.IO.Stream, System.Net.Security.SslClientAuthenticationOptions, System.Threading.CancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(System.Net.Security.SslClientAuthenticationOptions, System.Net.Http.HttpRequestMessage, Boolean, System.IO.Stream, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ConnectAsync>d__82 ByRef)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<CreateHttp11ConnectionAsync>d__86 ByRef)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetHttpConnectionAsync>d__67 ByRef)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.GetConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendWithRetryAsync>d__72 ByRef)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithProxyAuthAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
   at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient+<SendAsyncCore>d__85.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<SendAsyncCore>d__85, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsyncCore>d__85 ByRef)
   at System.Net.Http.HttpClient.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Internal.Cryptography.Pal.CertificateAssetDownloader+<>c__DisplayClass5_0.<CreateDownloadBytesFunc>b__0(System.String, System.Threading.CancellationToken)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadAsset(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadCertificate(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.FindChainViaAia(System.Collections.Generic.List`1<System.Security.Cryptography.X509Certificates.X509Certificate2> ByRef)
   at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean, Internal.Cryptography.ICertificatePal, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.X509Certificates.X509RevocationMode, System.Security.Cryptography.X509Certificates.X509RevocationFlag, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.X509Certificates.X509ChainTrustMode, System.DateTime, System.TimeSpan, Boolean)
   at System.Security.Cryptography.X509Certificates.X509Chain.Build(System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
   at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(System.Security.Cryptography.X509Certificates.X509Chain, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean, System.String)
   at System.Net.Security.SecureChannel.VerifyRemoteCertificate(System.Net.Security.RemoteCertificateValidationCallback, System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream.CompleteHandshake(System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ForceAuthenticationAsync>d__171`1<System.Net.Security.SyncReadWriteAdapter> ByRef)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](System.Net.Security.SyncReadWriteAdapter, Boolean, Byte[], Boolean)
   at System.Net.Security.SslStream.ProcessAuthentication(Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)
   at System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<EstablishSslConnectionAsyncCore>d__4 ByRef)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean, System.IO.Stream, System.Net.Security.SslClientAuthenticationOptions, System.Threading.CancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(System.Net.Security.SslClientAuthenticationOptions, System.Net.Http.HttpRequestMessage, Boolean, System.IO.Stream, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ConnectAsync>d__82 ByRef)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<CreateHttp11ConnectionAsync>d__86 ByRef)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetHttpConnectionAsync>d__67 ByRef)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.GetConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendWithRetryAsync>d__72 ByRef)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithProxyAuthAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
   at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient+<SendAsyncCore>d__85.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<SendAsyncCore>d__85, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsyncCore>d__85 ByRef)
   at System.Net.Http.HttpClient.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Internal.Cryptography.Pal.CertificateAssetDownloader+<>c__DisplayClass5_0.<CreateDownloadBytesFunc>b__0(System.String, System.Threading.CancellationToken)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadAsset(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadCertificate(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.FindChainViaAia(System.Collections.Generic.List`1<System.Security.Cryptography.X509Certificates.X509Certificate2> ByRef)
   at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean, Internal.Cryptography.ICertificatePal, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.X509Certificates.X509RevocationMode, System.Security.Cryptography.X509Certificates.X509RevocationFlag, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.X509Certificates.X509ChainTrustMode, System.DateTime, System.TimeSpan, Boolean)
   at System.Security.Cryptography.X509Certificates.X509Chain.Build(System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
   at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(System.Security.Cryptography.X509Certificates.X509Chain, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean, System.String)
   at System.Net.Security.SecureChannel.VerifyRemoteCertificate(System.Net.Security.RemoteCertificateValidationCallback, System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream.CompleteHandshake(System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ForceAuthenticationAsync>d__171`1<System.Net.Security.SyncReadWriteAdapter> ByRef)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](System.Net.Security.SyncReadWriteAdapter, Boolean, Byte[], Boolean)
   at System.Net.Security.SslStream.ProcessAuthentication(Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)

crash is probably due to StackOverflow. If there is no fix but workaround exists (some global settings (like env) etc) - please share.

Author: dvitel
Assignees: -
Labels:

area-System.Net.Http, untriaged

Milestone: -

@wfurt
Copy link
Member

wfurt commented Nov 20, 2020

This is interesting case. I would agree that the cancelation should kick in but it does not.

It boils to X509Chain and the way how this server set up.

On the get, server presents only it's certificate:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            23:1d:a7:f1:d0:b3:33:4f:95:03:60:f0:cc:8f:b0:b8:80:86:50:1c
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = KZ, CN = \D2\B0\D0\9B\D0\A2\D0\A2\D0\AB\D2\9A \D0\9A\D0\A3\D3\98\D0\9B\D0\90\D0\9D\D0\94\D0\AB\D0\A0\D0\A3\D0\A8\D0\AB \D0\9E\D0\A0\D0\A2\D0\90\D0\9B\D0\AB\D2\9A (RSA)
        Validity
            Not Before: Jan 15 10:44:49 2020 GMT
            Not After : Jan 14 10:44:49 2021 GMT
        Subject: CN = *.GOSZAKUP.GOV.KZ, serialNumber = IIN890316450321, C = KZ, L = \D0\9D\D0\A3\D0\A0-\D0\A1\D0\A3\D0\9B\D0\A2\D0\90\D0\9D, ST = \D0\9D\D0\A3\D0\A0-\D0\A1\D0\A3\D0\9B\D0\A2\D0\90\D0\9D, O = \D0\A0\D0\95\D0\A1\D0\9F\D0\A3\D0\91\D0\9B\D0\98\D0\9A\D0\90\D0\9D\D0\A1\D0\9A\D0\9E\D0\95 \D0\93\D0\9E\D0\A1\D0\A3\D0\94\D0\90\D0\A0\D0\A1\D0\A2\D0\92\D0\95\D0\9D\D0\9D\D0\9E\D0\95 \D0\A3\D0\A7\D0\A0\D0\95\D0\96\D0\94\D0\95\D0\9D\D0\98\D0\95 \"\D0\9C\D0\98\D0\9D\D0\98\D0\A1\D0\A2\D0\95\D0\A0\D0\A1\D0\A2\D0\92\D0\9E \D0\A4\D0\98\D0\9D\D0\90\D0\9D\D0\A1\D0\9E\D0\92 \D0\A0\D0\95\D0\A1\D0\9F\D0\A3\D0\91\D0\9B\D0\98\D0\9A\D0\98 \D0\9A\D0\90\D0\97\D0\90\D0\A5\D0\A1\D0\A2\D0\90\D0\9D\", OU = BIN201040000013, emailAddress = I.ERDENOVA@MINFIN.GOV.KZ
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b2:cc:17:34:53:78:d3:3a:8e:a9:f2:2b:16:42:
                    95:7d:fc:6e:13:1a:25:cf:fa:82:b2:99:9e:08:0f:
                    7e:e8:4e:74:89:eb:66:5e:42:95:aa:93:92:74:41:
                    c1:e6:76:f4:6e:89:e3:61:b9:b2:ae:ef:f4:25:a8:
                    d7:13:56:69:80:b1:1a:14:35:db:31:71:b2:ff:c5:
                    fd:43:aa:59:7d:2b:64:1c:45:93:61:0d:cb:c0:e5:
                    bc:3c:e7:43:d9:a5:8a:02:df:cd:e1:82:55:b5:6b:
                    0e:e8:cc:9c:94:0e:23:ad:10:7b:86:1f:e9:af:57:
                    dd:c9:06:0a:f5:c6:a0:9a:9e:ab:e1:8a:f6:f5:b9:
                    71:a8:75:a4:10:a1:ab:41:0b:56:e8:4e:c4:f2:b2:
                    94:7d:8a:05:34:01:12:04:fa:26:f6:48:ae:fb:7c:
                    13:22:ad:01:68:69:41:8a:a1:e7:7e:05:22:2f:13:
                    df:ae:9f:0f:c9:8c:14:40:e8:14:e9:49:18:fc:a1:
                    d2:47:4a:21:e5:6f:8c:a1:af:cc:57:b0:23:5c:e8:
                    c7:5f:03:5e:f5:f3:d3:d7:68:28:a8:0f:d1:a4:c9:
                    38:fe:2c:82:ab:e2:a9:9a:04:8c:25:6f:f8:71:7e:
                    60:c0:53:2e:93:34:79:9c:51:f3:6c:c3:41:13:b0:
                    94:5b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, 1.2.398.3.3.4.1.2
            X509v3 Authority Key Identifier:
                keyid:5B:6A:74:11

            X509v3 Subject Key Identifier:
                6F:14:BF:33:9A:E6:0D:36:6C:11:E0:77:BB:9D:AF:D8:3E:98:79:68
            X509v3 Certificate Policies:
                Policy: 1.2.398.3.3.2.5
                  CPS: http://pki.gov.kz/cps

            X509v3 Subject Alternative Name:
                DNS:goszakup.gov.kz, DNS:*.goszakup.gov.kz, DNS:*.oebs.goszakup.gov.kz
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:http://crl.pki.gov.kz/nca_rsa.crl
                  URI:http://crl1.pki.gov.kz/nca_rsa.crl

            X509v3 Freshest CRL:

                Full Name:
                  URI:http://crl.pki.gov.kz/nca_d_rsa.crl
                  URI:http://crl1.pki.gov.kz/nca_d_rsa.crl

            Authority Information Access:
                CA Issuers - URI:http://pki.gov.kz/cert/nca_rsa.cer
                OCSP - URI:http://ocsp.pki.gov.kz

    Signature Algorithm: sha256WithRSAEncryption
         1e:cd:53:ed:ab:b3:11:e7:a9:b2:ed:d9:68:d6:bb:f2:7e:d0:

So the X509Chain tries to fetch the CA cert from http://pki.gov.kz/cert/nca_rsa.cer

curl -v http://pki.gov.kz/cert/nca_rsa.cer
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Fri, 20 Nov 2020 20:06:21 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
< Location: https://pki.gov.kz/cert/nca_rsa.cer
< Set-Cookie: cookiesession1=678B76BCVWXYZBCDEFGHIJKLMNOP01EE;Expires=Sat, 20 Nov 2021 20:06:34 GMT;Path=/;HttpOnly

that sends redirect to HTTPS. The chain follow and eventually it hits http://root.gov.kz/cert/root_rsa.cer and that gets redirect to https://pki.gov.kz/cert/nca_rsa.cer.
So it loops endlessly in attempt to verify certificates on HTTPS request to download and validate certificates.

X509Chain unfortunately does not take Cancellation token so there is no way to propagate the desire to give up.

cc: @bartonjs and @vcsjones if it would make sense to detect loops like this and simply fail.

@vcsjones
Copy link
Member

vcsjones commented Nov 20, 2020

I see. That is... interesting. The root certificate is available to download over HTTPS and the root is serving it self. It's rather uncommon for AIA to happen over HTTPS. I don't know how exactly how Windows handles this situation. Failing seems right (especially if that is what Windows is doing.)

The intention in the current AIA implementation is to not use HTTPS at all if it is specified in the certificate as HTTPS:

Uri.TryCreate(name.Uri, UriKind.Absolute, out Uri? uri) &&
uri.Scheme == "http")

But that doesn't help the situation where HTTP -> HTTPS redirection is happening. So maybe a solution is to disable AllowAutoRedirect, and follow the redirects ourselves (or maybe there is a callback we can hook in to that I don't know about). If we end up getting a redirect to a non-HTTP URL (https://, gopher://, whatever) we just fail there.

@bartonjs
Copy link
Member

Hm, yeah, we definitely want to block an http -> https redirection. Following a http -> http redirection seems good, but perhaps with a limit of 2 redirects (3 hops).

And, we probably want to service this when we have a solution.

@wfurt
Copy link
Member

wfurt commented Nov 20, 2020

It is possible this used to work as the links point to http:// but perhaps somebody touched the nginx to do wholesale redirects ;(

It also seems the X509Chain is based on timeout X509ChainPolicy.UrlRetrievalTimeout but HttpClient is based on Cancellation token so it is hard to stick them together in consistency way. It feels like opportunity for better API...

@bartonjs bartonjs added this to the 5.0.x milestone Nov 20, 2020
@vcsjones
Copy link
Member

And, we probably want to service this when we have a solution.

I'll give it a shot over the weekend.

@dvitel
Copy link
Author

dvitel commented Nov 20, 2020

@wfurt so can I set up somehow (through public API) X509ChainPolicy.UrlRetrievalTimeout as temp workaround? And does it take into account redirects of cert downloads?

@wfurt
Copy link
Member

wfurt commented Nov 20, 2020

unfortunately no @dvitel. This is hidden down in SslStream and there is no public API to manipulate this.
You can perhaps try to contact the support@ecc.kz listed on the site. I know this may not work but there was at least one another case when reporting issue lead to fixes.

@wfurt
Copy link
Member

wfurt commented Nov 20, 2020

@vcsjones
Copy link
Member

@wfurt A bit unrelated from the issue, my understanding of the CA is that this is the certificate authority that Kazakhstan has set up to perform mass HTTPS decryption, I don't believe it is expected this certificate chain will work and has been put on a disallow list by many certificate trust stores. https://bugzilla.mozilla.org/show_bug.cgi?id=1232689#c14 provides some additional context.

@geoffkizer
Copy link
Contributor

geoffkizer commented Nov 21, 2020

It also seems the X509Chain is based on timeout X509ChainPolicy.UrlRetrievalTimeout but HttpClient is based on Cancellation token so it is hard to stick them together in consistency way. It feels like opportunity for better API...

Yeah, this seems bad. Is there some reason we don't support CancellationToken in these APIs? Is it just a matter of lack of API surface or is there some underlying issue involved? Which particular API are we talking about here?

Edit: It would certainly be nice to detect loops here, but (a) that's not trivial and (b) that doesn't handle a lot of cases, like slow retrieval or weird chains that go on for ever without actually looping. Seems like we should be robust against those scenarios. We don't necessarily need to have perfect cancellation capabilities (though that would be ideal), but we need to do enough to not block on this forever, whatever the underlying cause is.

@vcsjones
Copy link
Member

Is there some reason we don't support CancellationToken in these APIs?

I would presume this is because only on Linux do we actually do AIA fetches using HttpClient. On Windows and MacOS the chain building and fetching process is opaque and handled by the OS. I don’t know what or how a CancellationToken would do on MacOS or Windows.

@wfurt
Copy link
Member

wfurt commented Nov 21, 2020

If there is any chance of asynchronocy, we could at least release control back to caller with partial result.

@vcsjones
Copy link
Member

If there is any chance of asynchronocy,

Not sure what you mean, but I wouldn't know of a great way do this operation partially. In the case of macOS, SecTrustEvaluate does chain building, revocation checking, AIA fetching, etc. all in one native API call. We couldn't say, do revocation checking, check the cancellation token, and skip AIA fetching if the cancellation token is cancelled. In fact even on macOS, UrlRetrievalTimeout does nothing.

Windows' API shape is similar to macOS, with the exception that UrlRetrievalTimeout works - but not for AIA fetching, only for fetching CRL / OCSP responses.

@vcsjones
Copy link
Member

I wrote a failing test for this over at master...vcsjones:45010-no-follow-https.

That leaves me with the question of the best way to fix it. Setting AllowAutoRedirect to false and re-implementing the logic ourselves looks tricky, more so because we need to do everything with reflection.

Perhaps something new on HttpClientHandler like Func<Uri, bool> AutoRedirectFilter { get; set; } that allows a callback to be defined as to whether a particular redirect is followed or not would be useful. I could see other folks wanting this for other reasons, like ensuring redirects are only automatically followed for first party domains.

Alternatively, we could "best attempt" to implement the redirect logic since I think some of it doesn't really apply to AIA, like worrying about a POST -> GET method change.

@wfurt
Copy link
Member

wfurt commented Nov 24, 2020

Is the reflection only to get hands on the handler?

I'm wondering if we can. add some private.internal flag to control the redirection here:

if (HttpUtilities.IsSupportedSecureScheme(requestUri.Scheme) && !HttpUtilities.IsSupportedSecureScheme(location.Scheme))

instead of duplicating the logic.

@vcsjones
Copy link
Member

Is the reflection only to get hands on the handler?

The whole thing is done with reflection due to cyclic dependencies.

Could certainly add something that is internal and set with reflection since there is a bunch of reflection going on anyway.

// Use reflection to access System.Net.Http:
// Since System.Net.Http.dll explicitly depends on System.Security.Cryptography.X509Certificates.dll,
// the latter can't in turn have an explicit dependency on the former.
// Get the relevant types needed.
Type? socketsHttpHandlerType = Type.GetType("System.Net.Http.SocketsHttpHandler, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
Type? httpClientType = Type.GetType("System.Net.Http.HttpClient, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
Type? httpRequestMessageType = Type.GetType("System.Net.Http.HttpRequestMessage, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
Type? httpResponseMessageType = Type.GetType("System.Net.Http.HttpResponseMessage, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
Type? httpContentType = Type.GetType("System.Net.Http.HttpContent, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
if (socketsHttpHandlerType == null || httpClientType == null || httpRequestMessageType == null || httpResponseMessageType == null || httpContentType == null)

@ghost
Copy link

ghost commented Dec 2, 2020

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Concrete site with this behavior: https://www.goszakup.gov.kz
Expected behavior (as tested on Windows) -
The remote certificate is invalid because of errors in the certificate chain: PartialChain
or at least timeout

Example:

        static async Task Main(string[] args)
        {        
            var sw = new Stopwatch();
            sw.Start();
            try {
                using var cl = new HttpClient();
                using var cts = new CancellationTokenSource(7000);
                var res = await cl.GetStringAsync("https://www.goszakup.gov.kz", cts.Token); 
                Console.WriteLine($"[{sw.Elapsed}] Res: {res}");
            } catch (Exception e) {
                sw.Stop(); //Never here
                Console.WriteLine($"[{sw.Elapsed}] Err: {e}.");
            }
        }

Configuration

.NET SDK (reflecting any global.json):
 Version:   5.0.100
 Commit:    5044b93829

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  18.04
 OS Platform: Linux
 RID:         ubuntu.18.04-x64
 Base Path:   /usr/share/dotnet/sdk/5.0.100/

Host (useful for support):
  Version: 5.0.0
  Commit:  cf258a14b7

.NET SDKs installed:
  2.1.810 [/usr/share/dotnet/sdk]
  2.2.402 [/usr/share/dotnet/sdk]
  3.0.103 [/usr/share/dotnet/sdk]
  5.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.22 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.22 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.10 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.22 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.10 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

OpenSSL 1.1.1 11 Sep 2018

Other information

Same behavior is for SendAsync or GetStringAsync.
Played with SocketsHttpHandler Ssl settings - did not help
On run, app hangs around for 30mins on my machine and then crashes with Aborted (core dumped)
The crash dump contains 10K lines of exception call stack - seems that there is a infinite recursion somewhere
here is two cycles of loop from exception:

   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)
   at System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<EstablishSslConnectionAsyncCore>d__4 ByRef)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean, System.IO.Stream, System.Net.Security.SslClientAuthenticationOptions, System.Threading.CancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(System.Net.Security.SslClientAuthenticationOptions, System.Net.Http.HttpRequestMessage, Boolean, System.IO.Stream, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ConnectAsync>d__82 ByRef)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<CreateHttp11ConnectionAsync>d__86 ByRef)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetHttpConnectionAsync>d__67 ByRef)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.GetConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendWithRetryAsync>d__72 ByRef)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithProxyAuthAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
   at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient+<SendAsyncCore>d__85.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<SendAsyncCore>d__85, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsyncCore>d__85 ByRef)
   at System.Net.Http.HttpClient.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Internal.Cryptography.Pal.CertificateAssetDownloader+<>c__DisplayClass5_0.<CreateDownloadBytesFunc>b__0(System.String, System.Threading.CancellationToken)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadAsset(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadCertificate(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.FindChainViaAia(System.Collections.Generic.List`1<System.Security.Cryptography.X509Certificates.X509Certificate2> ByRef)
   at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean, Internal.Cryptography.ICertificatePal, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.X509Certificates.X509RevocationMode, System.Security.Cryptography.X509Certificates.X509RevocationFlag, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.X509Certificates.X509ChainTrustMode, System.DateTime, System.TimeSpan, Boolean)
   at System.Security.Cryptography.X509Certificates.X509Chain.Build(System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
   at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(System.Security.Cryptography.X509Certificates.X509Chain, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean, System.String)
   at System.Net.Security.SecureChannel.VerifyRemoteCertificate(System.Net.Security.RemoteCertificateValidationCallback, System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream.CompleteHandshake(System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ForceAuthenticationAsync>d__171`1<System.Net.Security.SyncReadWriteAdapter> ByRef)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](System.Net.Security.SyncReadWriteAdapter, Boolean, Byte[], Boolean)
   at System.Net.Security.SslStream.ProcessAuthentication(Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)
   at System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.ConnectHelper+<EstablishSslConnectionAsyncCore>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<EstablishSslConnectionAsyncCore>d__4 ByRef)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean, System.IO.Stream, System.Net.Security.SslClientAuthenticationOptions, System.Threading.CancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(System.Net.Security.SslClientAuthenticationOptions, System.Net.Http.HttpRequestMessage, Boolean, System.IO.Stream, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<ConnectAsync>d__82, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ConnectAsync>d__82 ByRef)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<CreateHttp11ConnectionAsync>d__86, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<CreateHttp11ConnectionAsync>d__86 ByRef)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<GetHttpConnectionAsync>d__67, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetHttpConnectionAsync>d__67 ByRef)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.GetConnectionAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpConnectionPool+<SendWithRetryAsync>d__72, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendWithRetryAsync>d__72 ByRef)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithProxyAuthAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPool.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
   at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient+<SendAsyncCore>d__85.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<SendAsyncCore>d__85, System.Net.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsyncCore>d__85 ByRef)
   at System.Net.Http.HttpClient.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
   at System.Net.Http.HttpClient.Send(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Internal.Cryptography.Pal.CertificateAssetDownloader+<>c__DisplayClass5_0.<CreateDownloadBytesFunc>b__0(System.String, System.Threading.CancellationToken)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadAsset(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.CertificateAssetDownloader.DownloadCertificate(System.String, System.TimeSpan)
   at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.FindChainViaAia(System.Collections.Generic.List`1<System.Security.Cryptography.X509Certificates.X509Certificate2> ByRef)
   at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean, Internal.Cryptography.ICertificatePal, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.OidCollection, System.Security.Cryptography.X509Certificates.X509RevocationMode, System.Security.Cryptography.X509Certificates.X509RevocationFlag, System.Security.Cryptography.X509Certificates.X509Certificate2Collection, System.Security.Cryptography.X509Certificates.X509ChainTrustMode, System.DateTime, System.TimeSpan, Boolean)
   at System.Security.Cryptography.X509Certificates.X509Chain.Build(System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
   at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(System.Security.Cryptography.X509Certificates.X509Chain, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean, System.String)
   at System.Net.Security.SecureChannel.VerifyRemoteCertificate(System.Net.Security.RemoteCertificateValidationCallback, System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream.CompleteHandshake(System.Net.Security.ProtocolToken ByRef, System.Net.Security.SslPolicyErrors ByRef, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags ByRef)
   at System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Security.SslStream+<ForceAuthenticationAsync>d__171`1[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<ForceAuthenticationAsync>d__171`1<System.Net.Security.SyncReadWriteAdapter> ByRef)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[[System.Net.Security.SyncReadWriteAdapter, System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](System.Net.Security.SyncReadWriteAdapter, Boolean, Byte[], Boolean)
   at System.Net.Security.SslStream.ProcessAuthentication(Boolean, Boolean, System.Threading.CancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions)

crash is probably due to StackOverflow. If there is no fix but workaround exists (some global settings (like env) etc) - please share.

Author: dvitel
Assignees: -
Labels:

area-System.Net, untriaged

Milestone: 5.0.x

krwq added a commit to krwq/runtime-1 that referenced this issue Feb 12, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Feb 12, 2021
@krwq
Copy link
Member

krwq commented Feb 12, 2021

This bug is related to dotnet/announcements#175
It's already fixed in 2.1/3.1/5.0, the PR above is port against master branch.

@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Feb 12, 2021
@karelz karelz added bug and removed untriaged New issue has not been triaged by the area owner labels Feb 15, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Mar 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants