PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

[Net.HttpWebRequest] cannot establish a secure connection to get.skype.com

Open StarsbySea opened this issue 1 year ago • 7 comments

Prerequisites

Steps to reproduce

I want to use the following command

[System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse().ResponseUri.LocalPath

to get the HTTP response content, which should theoretically work, but instead I get

MethodInvocationException: Exception calling "GetResponse" with "0" argument(s): "The SSL connection could not be established, see inner exception."

Expected behavior

PS C:\Users\Kevin> [System.Net.HttpWebRequest]::Create('http://get.skype.com/go/getskype-skypeforwindows').GetResponse().ResponseUri.LocalPath
/s4l/download/win/Skype-8.96.0.207.exe

Actual behavior

PS C:\Users\Kevin> [System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse().ResponseUri.LocalPath
MethodInvocationException: Exception calling "GetResponse" with "0" argument(s): "The SSL connection could not be established, see inner exception."

Error details

Exception             :
    Type           : System.Management.Automation.MethodInvocationException
    ErrorRecord    :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Exception calling "GetResponse" with "0" argument(s): "The SSL connection could not be established, see inner
 exception."
            HResult : -2146233087
        CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : WebException
        InvocationInfo        :
            ScriptLineNumber : 1
            OffsetInLine     : 1
            HistoryId        : -1
            Line             : [System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse
().ResponseUri.LocalPath
            PositionMessage  : At line:1 char:1
                               + [System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskyp …
                               + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    TargetSite     :
        Name          : ConvertToMethodInvocationException
        DeclaringType : System.Management.Automation.ExceptionHandlingOps, System.Management.Automation, Version=7.3.3.500, Culture
=neutral, PublicKeyToken=31bf3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Message        : Exception calling "GetResponse" with "0" argument(s): "The SSL connection could not be established, see inner
exception."
    Data           : System.Collections.ListDictionaryInternal
    InnerException :
        Type           : System.Net.WebException
        Status         : UnknownError
        TargetSite     :
            Name          : GetResponse
            DeclaringType : System.Net.HttpWebRequest
            MemberType    : Method
            Module        : System.Net.Requests.dll
        Message        : The SSL connection could not be established, see inner exception.
        InnerException :
            Type           : System.Net.Http.HttpRequestException
            TargetSite     :
                Name          : MoveNext
                DeclaringType : System.Net.Http.ConnectHelper+<EstablishSslConnectionAsync>d__2, System.Net.Http, Version=7.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
                MemberType    : Method
                Module        : System.Net.Http.dll
            Message        : The SSL connection could not be established, see inner exception.
            InnerException :
                Type           : System.Security.Authentication.AuthenticationException
                TargetSite     :
                    Name          : MoveNext
                    DeclaringType : System.Net.Security.SslStream+<ForceAuthenticationAsync>d__146`1[TIOAdapter]
                    MemberType    : Method
                    Module        : System.Net.Security.dll
                Message        : Authentication failed because the remote party sent a TLS alert: 'HandshakeFailure'.
                InnerException :
                    Type            : System.ComponentModel.Win32Exception
                    NativeErrorCode : -2146893018
                    ErrorCode       : -2147467259
                    Message         : 接收到的消息异常,或格式不正确。
                    HResult         : -2147467259
                Source         : System.Net.Security
                HResult        : -2146233087
                StackTrace     :
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, Cancell
ationToken cancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage reque
st, Boolean async, Stream stream, CancellationToken cancellationToken)
            Source         : System.Net.Http
            HResult        : -2146233087
            StackTrace     :
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage reque
st, Boolean async, Stream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToke
n)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken c
ancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellation(CancellationToken cancellationToken)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(Boolean async, CancellationToken canc
ellationToken)
   at System.Net.Http.HttpConnectionPool.HttpConnectionWaiter`1.WaitForConnectionAsync(Boolean async, CancellationToken requestCanc
ellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean d
oRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancella
tionToken)
   at System.Net.HttpWebRequest.SendRequest(Boolean async)
   at System.Net.HttpWebRequest.GetResponse()
        Source         : System.Net.Requests
        HResult        : -2146233087
        StackTrace     :
   at System.Net.HttpWebRequest.GetResponse()
   at CallSite.Target(Closure, CallSite, Object)
    Source         : System.Management.Automation
    HResult        : -2146233087
    StackTrace     :
   at System.Management.Automation.ExceptionHandlingOps.ConvertToMethodInvocationException(Exception exception, Type typeToThrow, S
tring methodName, Int32 numArgs, MemberInfo memberInfo)
   at CallSite.Target(Closure, CallSite, Object)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : WebException
InvocationInfo        :
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : -1
    Line             : [System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse().Respo
nseUri.LocalPath
    PositionMessage  : At line:1 char:1
                       + [System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskyp …
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1

Environment data

PS C:\Users\Kevin> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.3
PSEdition                      Core
GitCommitId                    7.3.3
OS                             Microsoft Windows 10.0.22621
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

屏幕录制

This might help https://www.ssllabs.com/ssltest/analyze.html?d=get.skype.com

StarsbySea avatar Apr 11 '23 16:04 StarsbySea

"Authentication failed because the remote party sent a TLS alert: 'HandshakeFailure'."

Not quite sure what PowerShell is meant to do here, invoke-WebRequest http://get.skype.com/go/getskype-skypeforwindows does an 8MB download, which I assume is the install file. If there is a problem calling the .NET classes directly that might need to go to .NET instead ?

jhoneill avatar Apr 11 '23 18:04 jhoneill

Unfortunately the error comes from the TLS stack on Windows and the message shared in the inner exception 接收到的消息异常,或格式不正确。 translated to English is

The received message is abnormal, or the format is incorrect.

Something is happening with the TLS handshake causing the failure but due to the nature of how TLS works it's going to be difficult to figure out what that is. What I would do is

  • Use Wireshark to see the TLS handshake captures and see if there is anything special in the output that might indicate why Windows thinks it's the wrong format
  • Try a client that isn't related to Schannel, see if Firefox or Chrome can access this site
  • Try another client that uses Schannel, see if IE/Edge (IEMode) can access this site
  • Try Trace-TlsHandshake to see if it works outside the HTTP request

You could try and use something like PSSPI to call Schannel directly and see what errors it might return directly but that's a pretty complex bit of code. I'm happy to share an example if you are willing to try it out.

jborean93 avatar Apr 11 '23 19:04 jborean93

Can't reproduce the error on windows 10 (PS 5.1 - 7.3.3 - 7.4preview2) from Europe

[System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse().ResponseUri.LocalPath
#--> /s4l/download/win/Skype-8.96.0.207.exe

CarloToso avatar Apr 11 '23 22:04 CarloToso

Can't reproduce the error on windows 10 (PS 5.1 - 7.3.3 - 7.4preview2) from Europe

[System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse().ResponseUri.LocalPath
#--> /s4l/download/win/Skype-8.96.0.207.exe

Strangely enough, I was unable to reproduce this problem on my Windows 10 PC as well. So is this problem related to the OS now?

PS C:\Users\Kevin> [System.Net.HttpWebRequest]::Create('https://get.skype.com/go/getskype-skypeforwindows').GetResponse().ResponseUri.LocalPath
/s4l/download/win/Skype-8.96.0.207.exe
PS C:\Users\Kevin> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.3
PSEdition                      Core
GitCommitId                    7.3.3
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

StarsbySea avatar Apr 12 '23 04:04 StarsbySea

Most likely OP has a configured Cipher Suite set that is too restricted and doesn't allow what the server supports. Unfortunately this happens quite deep in the OS layer and the errors are sometimes hard to track down.

jborean93 avatar Apr 12 '23 05:04 jborean93

Most likely OP has a configured Cipher Suite set that is too restricted and doesn't allow what the server supports. Unfortunately this happens quite deep in the OS layer and the errors are sometimes hard to track down.

I'm afraid I have to say it's not a problem with my system configuration, I wrote the GithubAction configuration and tested it on WinServer 2019 and WinServer 2022 respectively and the results are consistent with the previous ones. No problem under Win10, a problem under Win11.

https://github.com/StarsbySea/test-https/actions/runs/4675488698/jobs/8280670201#step:3:1

https://github.com/StarsbySea/test-https/actions/runs/4675488698/jobs/8280670322#step:3:1

GitHub
Contribute to StarsbySea/test-https development by creating an account on GitHub.
GitHub
Contribute to StarsbySea/test-https development by creating an account on GitHub.

StarsbySea avatar Apr 12 '23 07:04 StarsbySea

Most likely OP has a configured Cipher Suite set that is too restricted and doesn't allow what the server supports. Unfortunately this happens quite deep in the OS layer and the errors are sometimes hard to track down.

I'm afraid I have to say it's not a problem with my system configuration, I wrote the GithubAction configuration and tested it on WinServer 2019 and WinServer 2022 respectively and the results are consistent with the previous ones. No problem under Win10, a problem under Win11.

So it sounds like Win 11 is more restricted. I'd look at [System.Net.ServicePointManager]::SecurityProtocol

When I've had TLS errors in the past I've used this in the catch block for the initial error - if the exception matches "SSL|TLS|Certificate|Secure channel" the following runs.

                    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {
                        param(
                            [object]$sentby,
                            [Security.Cryptography.X509Certificates.X509Certificate] $certificate,
                            [Security.Cryptography.X509Certificates.X509Chain] $chain,
                            [Net.Security.SslPolicyErrors] $sslPolicyErrors
                        )
                        $true
                    }
                    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor `
                          [Net.SecurityProtocolType]::Tls   -bor `
                          [Net.SecurityProtocolType]::Tls11 -bor `
                          [Net.SecurityProtocolType]::Tls12
                    $webclient = [System.Net.HttpWebRequest]::CreateHttp($uri)
                    $result2   = $webclient.GetResponse()
                    Write-Host "GET '$URI' returned a status of $($result2.StatusCode.value__)."

The first part blunders through the cert name not matching the host name, and the second ensure we'll work with old versions of TLS that we really don't want to.

jhoneill avatar Apr 14 '23 12:04 jhoneill

I can generate this same behaviour on two different Windows 10 boxes (21H2 and 22H2) in different domains (so not a GPO) when using Powershell 7.3.4. The system default Powershell 5 on either computer does not have this problem.

Possibly related is this odd result, where the first attempt to connect to an HTTPS resource fails, but the subsequent one does not:

PowerShell 7.3.4
home> Invoke-WebRequest -Verbose -Debug -Uri "https://www.google.com"
VERBOSE: HTTP/1.1 GET with 0-byte payload
Invoke-WebRequest: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
home> Invoke-WebRequest -Verbose -Debug -Uri "https://www.google.com"
VERBOSE: HTTP/1.1 GET with 0-byte payload
VERBOSE: received -byte response of content type text/html

StatusCode        : 200
StatusDescription : OK
etc etc

mkellen1 avatar Jun 01 '23 22:06 mkellen1

Golfing the issue down even more:

> $client = New-Object -TypeName System.Net.Http.HttpClient
> $r1=$client.GetStringAsync('https://www.google.com')
> $r1.Status
Faulted
> $r1.Exception.InnerException.InnerException.Message
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
> $r1.Exception.InnerException.InnerException.InnerException | Select SocketErrorCode,ErrorCode

SocketErrorCode ErrorCode
--------------- ---------
ConnectionReset     10054
> $r2=$client.GetStringAsync('https://www.google.com')
> $r2.Status
RanToCompletion

mkellen1 avatar Jun 02 '23 16:06 mkellen1

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.