dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.12k stars 4.7k forks source link

Test: System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test/SetDelegate_ConnectionSucceeds failed with "System.Net.Http.CurlException : SSL connect error" #22712

Closed ghost closed 4 years ago

ghost commented 7 years ago

Opened on behalf of @Jiayili1

The test System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test/SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) has failed.

System.Net.Http.HttpRequestException : An error occurred while sending the request. ---- System.Net.Http.CurlException : SSL connect error

    Stack Trace:

       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Net.Http.HttpClient.<FinishSendAsyncBuffered>d__58.MoveNext() in /Users/buildagent/agent/_work/41/s/corefx/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:line 462
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.<>c__DisplayClass1_0.<<SetDelegate_ConnectionSucceeds>b__0>d.MoveNext() in /Users/buildagent/agent/_work/41/s/corefx/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AcceptAllCerts.cs:line 46
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Test.Common.LoopbackServer.<>c__DisplayClass3_0.<CreateServerAsync>b__0(Task t) in /Users/buildagent/agent/_work/41/s/corefx/src/Common/tests/System/Net/Http/LoopbackServer.cs:line 57
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.<SetDelegate_ConnectionSucceeds>d__1.MoveNext() in /Users/buildagent/agent/_work/41/s/corefx/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AcceptAllCerts.cs:line 44
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
----- Inner Stack Trace -----
   at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error) in /Users/buildagent/agent/_work/41/s/corefx/src/System.Net.Http/src/System/Net/Http/Unix/CurlHandler.cs:line 644
   at System.Net.Http.CurlHandler.MultiAgent.FinishRequest(StrongToWeakReference`1 easyWrapper, CURLcode messageResult) in /Users/buildagent/agent/_work/41/s/corefx/src/System.Net.Http/src/System/Net/Http/Unix/CurlHandler.MultiAgent.cs:line 869

Build : 2.0.0 - 20170711.01 (Core Tests) Failing configurations:

Detail: https://mc.dot.net/#/product/netcore/200/source/official~2Fcorefx~2Frelease~2F2.0.0~2F/type/test~2Ffunctional~2Fcli~2F/build/20170711.01/workItem/System.Net.Http.Functional.Tests/analysis/xunit/System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test~2FSetDelegate_ConnectionSucceeds(acceptedProtocol:%20Tls,%20requestOnlyThisProtocol:%20False)

Priya91 commented 7 years ago

libcurl on OSX 10.13, with Libressl fails with error when sending a request to a server supporting only TLSv1 protocol.

CURLINFO_TEXT: error:14092105:SSL routines:SSL3_GET_SERVER_HELLO:wrong cipher returned.

The server used in the test is just a socket and it uses the certificate from the configuration settings. The certificate as signature_algorithm as sha256RSA. @bartonjs I don't understand this error, suggests that libressl doesn't support this cipher for tlsv1? The server supports only tlsv1 protocol, and the HttpClient lets libcurl use it's default SSL version. For other cases of specifying the exact ssl version to use through HttpClientHandler, doesn't give this error.

bartonjs commented 7 years ago

Do you have https://github.com/dotnet/corefx/pull/22001 in your repro? I'm wondering if you've hit one of the symptoms @stephentoub ran into (specifically, that if we ask for a single TLS version OpenSSL is in a less-willing-to-negotiate mode).

The scenario seems to work:

# Create a new RSA-2048 key, and create a cert from that.
$ openssl req -new -x509 -out grr.cer -keyout grr.key -newkey rsa:2048 -nodes -sha256
Generating a 2048 bit RSA private key
....................................+++
.........................+++
writing new private key to 'grr.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:localhost
Email Address []:
# Start a TLS 1.0-only server using that certificate as a background process
$ openssl s_server -accept 9833 -cert grr.cer -key grr.key -www -tls1 &
[1] 16819
Builds-MBP:jbarton build$ Using auto DH parameters
Using default temp ECDH parameters
ACCEPT
# [hit enter again to get a prompt]
# Use the curl CLI tool to hit that URI
$ curl https://localhost:9833/ --cacert grr.cer
ACCEPT
<HTML><BODY BGCOLOR="#ffffff">
<pre>

s_server -accept 9833 -cert grr.cer -key grr.key -www -tls1
Secure Renegotiation IS supported
Ciphers supported in s_server binary
TLSv1/SSLv3:ECDHE-ECDSA-CHACHA20-POLY1305TLSv1/SSLv3:ECDHE-RSA-CHACHA20-POLY1305
TLSv1/SSLv3:DHE-RSA-CHACHA20-POLY1305TLSv1/SSLv3:ECDHE-RSA-AES256-GCM-SHA384
TLSv1/SSLv3:ECDHE-ECDSA-AES256-GCM-SHA384TLSv1/SSLv3:ECDHE-RSA-AES256-SHA384
TLSv1/SSLv3:ECDHE-ECDSA-AES256-SHA384TLSv1/SSLv3:ECDHE-RSA-AES256-SHA
TLSv1/SSLv3:ECDHE-ECDSA-AES256-SHA   TLSv1/SSLv3:DHE-DSS-AES256-GCM-SHA384
TLSv1/SSLv3:DHE-RSA-AES256-GCM-SHA384TLSv1/SSLv3:DHE-RSA-AES256-SHA256
TLSv1/SSLv3:DHE-DSS-AES256-SHA256    TLSv1/SSLv3:DHE-RSA-AES256-SHA
TLSv1/SSLv3:DHE-DSS-AES256-SHA       TLSv1/SSLv3:GOST2012256-GOST89-GOST89
TLSv1/SSLv3:DHE-RSA-CAMELLIA256-SHA256TLSv1/SSLv3:DHE-DSS-CAMELLIA256-SHA256
TLSv1/SSLv3:DHE-RSA-CAMELLIA256-SHA  TLSv1/SSLv3:DHE-DSS-CAMELLIA256-SHA
TLSv1/SSLv3:GOST2001-GOST89-GOST89   TLSv1/SSLv3:ECDH-RSA-AES256-GCM-SHA384
TLSv1/SSLv3:ECDH-ECDSA-AES256-GCM-SHA384TLSv1/SSLv3:ECDH-RSA-AES256-SHA384
TLSv1/SSLv3:ECDH-ECDSA-AES256-SHA384 TLSv1/SSLv3:ECDH-RSA-AES256-SHA
TLSv1/SSLv3:ECDH-ECDSA-AES256-SHA    TLSv1/SSLv3:AES256-GCM-SHA384
TLSv1/SSLv3:AES256-SHA256            TLSv1/SSLv3:AES256-SHA
TLSv1/SSLv3:CAMELLIA256-SHA256       TLSv1/SSLv3:CAMELLIA256-SHA
TLSv1/SSLv3:ECDHE-RSA-AES128-GCM-SHA256TLSv1/SSLv3:ECDHE-ECDSA-AES128-GCM-SHA256
TLSv1/SSLv3:ECDHE-RSA-AES128-SHA256  TLSv1/SSLv3:ECDHE-ECDSA-AES128-SHA256
TLSv1/SSLv3:ECDHE-RSA-AES128-SHA     TLSv1/SSLv3:ECDHE-ECDSA-AES128-SHA
TLSv1/SSLv3:DHE-DSS-AES128-GCM-SHA256TLSv1/SSLv3:DHE-RSA-AES128-GCM-SHA256
TLSv1/SSLv3:DHE-RSA-AES128-SHA256    TLSv1/SSLv3:DHE-DSS-AES128-SHA256
TLSv1/SSLv3:DHE-RSA-AES128-SHA       TLSv1/SSLv3:DHE-DSS-AES128-SHA
TLSv1/SSLv3:DHE-RSA-CAMELLIA128-SHA256TLSv1/SSLv3:DHE-DSS-CAMELLIA128-SHA256
TLSv1/SSLv3:DHE-RSA-CAMELLIA128-SHA  TLSv1/SSLv3:DHE-DSS-CAMELLIA128-SHA
TLSv1/SSLv3:ECDH-RSA-AES128-GCM-SHA256TLSv1/SSLv3:ECDH-ECDSA-AES128-GCM-SHA256
TLSv1/SSLv3:ECDH-RSA-AES128-SHA256   TLSv1/SSLv3:ECDH-ECDSA-AES128-SHA256
TLSv1/SSLv3:ECDH-RSA-AES128-SHA      TLSv1/SSLv3:ECDH-ECDSA-AES128-SHA
TLSv1/SSLv3:AES128-GCM-SHA256        TLSv1/SSLv3:AES128-SHA256
TLSv1/SSLv3:AES128-SHA               TLSv1/SSLv3:CAMELLIA128-SHA256
TLSv1/SSLv3:CAMELLIA128-SHA          TLSv1/SSLv3:ECDHE-RSA-RC4-SHA
TLSv1/SSLv3:ECDHE-ECDSA-RC4-SHA      TLSv1/SSLv3:ECDH-RSA-RC4-SHA
TLSv1/SSLv3:ECDH-ECDSA-RC4-SHA       TLSv1/SSLv3:RC4-SHA
TLSv1/SSLv3:RC4-MD5                  TLSv1/SSLv3:ECDHE-RSA-DES-CBC3-SHA
TLSv1/SSLv3:ECDHE-ECDSA-DES-CBC3-SHA TLSv1/SSLv3:EDH-RSA-DES-CBC3-SHA
TLSv1/SSLv3:EDH-DSS-DES-CBC3-SHA     TLSv1/SSLv3:ECDH-RSA-DES-CBC3-SHA
TLSv1/SSLv3:ECDH-ECDSA-DES-CBC3-SHA  TLSv1/SSLv3:DES-CBC3-SHA
TLSv1/SSLv3:EDH-RSA-DES-CBC-SHA      TLSv1/SSLv3:EDH-DSS-DES-CBC-SHA
TLSv1/SSLv3:DES-CBC-SHA
---
Ciphers common between both SSL end points:
ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305
ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA384  ECDHE-RSA-AES256-SHA       ECDHE-ECDSA-AES256-SHA
DHE-DSS-AES256-GCM-SHA384  DHE-RSA-AES256-GCM-SHA384  DHE-RSA-AES256-SHA256
DHE-DSS-AES256-SHA256      DHE-RSA-AES256-SHA         DHE-DSS-AES256-SHA
GOST2012256-GOST89-GOST89  DHE-RSA-CAMELLIA256-SHA256 DHE-DSS-CAMELLIA256-SHA256
DHE-RSA-CAMELLIA256-SHA    DHE-DSS-CAMELLIA256-SHA    GOST2001-GOST89-GOST89
ECDH-RSA-AES256-GCM-SHA384 ECDH-ECDSA-AES256-GCM-SHA384 ECDH-RSA-AES256-SHA384
ECDH-ECDSA-AES256-SHA384   ECDH-RSA-AES256-SHA        ECDH-ECDSA-AES256-SHA
AES256-GCM-SHA384          AES256-SHA256              AES256-SHA
CAMELLIA256-SHA256         CAMELLIA256-SHA            ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256    ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA       ECDHE-ECDSA-AES128-SHA     DHE-DSS-AES128-GCM-SHA256
DHE-RSA-AES128-GCM-SHA256  DHE-RSA-AES128-SHA256      DHE-DSS-AES128-SHA256
DHE-RSA-AES128-SHA         DHE-DSS-AES128-SHA         DHE-RSA-CAMELLIA128-SHA256
DHE-DSS-CAMELLIA128-SHA256 DHE-RSA-CAMELLIA128-SHA    DHE-DSS-CAMELLIA128-SHA
ECDH-RSA-AES128-GCM-SHA256 ECDH-ECDSA-AES128-GCM-SHA256 ECDH-RSA-AES128-SHA256
ECDH-ECDSA-AES128-SHA256   ECDH-RSA-AES128-SHA        ECDH-ECDSA-AES128-SHA
AES128-GCM-SHA256          AES128-SHA256              AES128-SHA
CAMELLIA128-SHA256         CAMELLIA128-SHA            ECDHE-RSA-DES-CBC3-SHA
ECDHE-ECDSA-DES-CBC3-SHA   EDH-RSA-DES-CBC3-SHA       EDH-DSS-DES-CBC3-SHA
ECDH-RSA-DES-CBC3-SHA      ECDH-ECDSA-DES-CBC3-SHA    DES-CBC3-SHA
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 6F0718F6C94259014051296B5D4721909A0EA14651A6554B6E3A505677FC22E8
    Session-ID-ctx: 01000000
    Master-Key: D19DF0220B1D36F24FA2A3C7287593FCF8CDCDFC9313D16BECC9000FDE4FDE09A9E8D8BD9067ECC47399C83F5FF9C081
    Start Time: 1499824259
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
   1 items in the session cache
   0 client connects (SSL_connect())
   0 client renegotiates (SSL_connect())
   0 client connects that finished
   1 server accepts (SSL_accept())
   0 server renegotiates (SSL_accept())
   1 server accepts that finished
   0 session cache hits
   0 session cache misses
   0 session cache timeouts
   0 callback cache hits
   0 cache full overflows (128 allowed)
---
no client certificate available
</BODY></HTML>
# don't forget you left a server running
$ fg
openssl s_server -accept 9833 -cert grr.cer -key grr.key -www -tls1
^C
bartonjs commented 7 years ago

Actually, Steve's change only affects OpenSSL-based SslStream, which we wouldn't have on macOS.

Doing a test more like what we do (using SslStream to open the server side, then using curl to open the client side) I can repro the problem.

The LibreSSL error is that the server side picked a TLS 1.2 cipher suite (in this case, C030 (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)) even though the server said it was only using TLS 1.0.

So this is an Apple bug in SecureTransport; they're not restricting the ciphersuites to the TLS protocol version they're hosting (instead they just looked at the client list and went "ooh, ooh, I know that one").

If we had a [(Tls | Tls11), false] test that'd fail, too, for the same reason.

So our best bet might be to disable this case for High Sierra (I have a High Sierra detector in https://github.com/dotnet/corefx/pull/22150).

Since we don't have a condition on inline data, I'd just add it as an early abort when SslProtocols == Tls1 && restrict == false && PlatformDetection.IsMacOsHighSierra.

stephentoub commented 7 years ago

@bartonjs, any chance it's related to https://github.com/dotnet/corefx/issues/21922? Looks like that's on 10.12, though.

bartonjs commented 7 years ago

@stephentoub Probably not.

d$ openssl s_client -connect localhost:9833 -debug -msg
CONNECTED(00000005)
write to 0x7fce2441d620 [0x7fce24812a00] (318 bytes => 318 (0x13E))
0000 - 16 03 01 01 39 01 00 01-35 03 03 50 e3 11 78 26   ....9...5..P..x&
0010 - d4 3d f9 25 4a b6 91 d7-17 c4 e5 2f 0e 51 d7 e8   .=.%J....../.Q..
0020 - fb a8 d7 d4 26 ec e4 4f-38 a7 97 00 00 98 cc 14   ....&..O8.......
0030 - cc 13 cc 15 c0 30 c0 2c-c0 28 c0 24 c0 14 c0 0a   .....0.,.(.$....
0040 - 00 a3 00 9f 00 6b 00 6a-00 39 00 38 ff 85 00 c4   .....k.j.9.8....
0050 - 00 c3 00 88 00 87 00 81-c0 32 c0 2e c0 2a c0 26   .........2...*.&
0060 - c0 0f c0 05 00 9d 00 3d-00 35 00 c0 00 84 c0 2f   .......=.5...../
0070 - c0 2b c0 27 c0 23 c0 13-c0 09 00 a2 00 9e 00 67   .+.'.#.........g
0080 - 00 40 00 33 00 32 00 be-00 bd 00 45 00 44 c0 31   .@.3.2.....E.D.1
0090 - c0 2d c0 29 c0 25 c0 0e-c0 04 00 9c 00 3c 00 2f   .-.).%.......<./
00a0 - 00 ba 00 41 c0 11 c0 07-c0 0c c0 02 00 05 00 04   ...A............
00b0 - c0 12 c0 08 00 16 00 13-c0 0d c0 03 00 0a 00 15   ................
00c0 - 00 12 00 09 00 ff 01 00-00 74 00 0b 00 04 03 00   .........t......
00d0 - 01 02 00 0a 00 3a 00 38-00 0e 00 0d 00 19 00 1c   .....:.8........
00e0 - 00 0b 00 0c 00 1b 00 18-00 09 00 0a 00 1a 00 16   ................
00f0 - 00 17 00 08 00 06 00 07-00 14 00 15 00 04 00 05   ................
0100 - 00 12 00 13 00 01 00 02-00 03 00 0f 00 10 00 11   ................
0110 - 00 23 00 00 00 0d 00 26-00 24 06 01 06 02 06 03   .#.....&.$......
0120 - ef ef 05 01 05 02 05 03-04 01 04 02 04 03 ee ee   ................
0130 - ed ed 03 01 03 02 03 03-02 01 02 02 02 03         ..............
>>> TLS 1.2 Handshake [length 0139], ClientHello
    01 00 01 35 03 03 50 e3 11 78 26 d4 3d f9 25 4a
    b6 91 d7 17 c4 e5 2f 0e 51 d7 e8 fb a8 d7 d4 26
    ec e4 4f 38 a7 97 00 00 98 cc 14 cc 13 cc 15 c0
    30 c0 2c c0 28 c0 24 c0 14 c0 0a 00 a3 00 9f 00
    6b 00 6a 00 39 00 38 ff 85 00 c4 00 c3 00 88 00
    87 00 81 c0 32 c0 2e c0 2a c0 26 c0 0f c0 05 00
    9d 00 3d 00 35 00 c0 00 84 c0 2f c0 2b c0 27 c0
    23 c0 13 c0 09 00 a2 00 9e 00 67 00 40 00 33 00
    32 00 be 00 bd 00 45 00 44 c0 31 c0 2d c0 29 c0
    25 c0 0e c0 04 00 9c 00 3c 00 2f 00 ba 00 41 c0
    11 c0 07 c0 0c c0 02 00 05 00 04 c0 12 c0 08 00
    16 00 13 c0 0d c0 03 00 0a 00 15 00 12 00 09 00
    ff 01 00 00 74 00 0b 00 04 03 00 01 02 00 0a 00
    3a 00 38 00 0e 00 0d 00 19 00 1c 00 0b 00 0c 00
    1b 00 18 00 09 00 0a 00 1a 00 16 00 17 00 08 00
    06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 00
    01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 00
    0d 00 26 00 24 06 01 06 02 06 03 ef ef 05 01 05
    02 05 03 04 01 04 02 04 03 ee ee ed ed 03 01 03
    02 03 03 02 01 02 02 02 03
read from 0x7fce2441d620 [0x7fce24818000] (7 bytes => 7 (0x7))
0000 - 16 03 01 00 51 02                                 ....Q.
0007 - <SPACES/NULS>
read from 0x7fce2441d620 [0x7fce2481800a] (79 bytes => 79 (0x4F))
0000 - 00 4d 03 01 59 66 63 6b-80 de 7a d5 17 d5 6c b3   .M..Yfck..z...l.
0010 - 28 8e 84 67 66 62 7f e8-dd f8 be 5e 96 f1 e5 7b   (..gfb.....^...{
0020 - 97 42 2b c6 20 d4 07 fa-52 59 30 a3 ba ad 94 ad   .B+. ...RY0.....
0030 - 85 f2 f9 f5 55 a0 4c 64-f3 32 c6 be 59 e3 ea c9   ....U.Ld.2..Y...
0040 - 12 d4 11 c5 32 c0 30 00-00 05 ff 01 00 01         ....2.0.......
004f - <SPACES/NULS>
<<< TLS 1.0 Handshake [length 0051], ServerHello
    02 00 00 4d 03 01 59 66 63 6b 80 de 7a d5 17 d5
    6c b3 28 8e 84 67 66 62 7f e8 dd f8 be 5e 96 f1
    e5 7b 97 42 2b c6 20 d4 07 fa 52 59 30 a3 ba ad
    94 ad 85 f2 f9 f5 55 a0 4c 64 f3 32 c6 be 59 e3
    ea c9 12 d4 11 c5 32 c0 30 00 00 05 ff 01 00 01
    00
write to 0x7fce2441d620 [0x7fce25001000] (7 bytes => 7 (0x7))
0000 - 15 03 01 00 02 02 2f                              ....../
>>> TLS 1.0 Alert [length 0002], fatal illegal_parameter
    02 2f
140736451167112:error:14092105:SSL routines:SSL3_GET_SERVER_HELLO:wrong cipher returned:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22/libressl/ssl/s3_clnt.c:894:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 86 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID: D407FA525930A3BAAD94AD85F2F9F555A04C64F332C6BE59E3EAC912D411C532
    Session-ID-ctx:
    Master-Key:
    Start Time: 1499882348
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

In the ServerHello Apple indicated TLS 1.0 (protocol 03 01), with cipher suite C0 30.

<<< TLS 1.0 Handshake [length 0051], ServerHello 02 00 00 4d 03 01 59 66 63 6b 80 de 7a d5 17 d5 6c b3 28 8e 84 67 66 62 7f e8 dd f8 be 5e 96 f1 e5 7b 97 42 2b c6 20 d4 07 fa 52 59 30 a3 ba ad 94 ad 85 f2 f9 f5 55 a0 4c 64 f3 32 c6 be 59 e3 ea c9 12 d4 11 c5 32 c0 30 00 00 05 ff 01 00 01 00

We get an exception server side and client side, but the test is seeing the client one first. When LibreSSL reported their error (TLS 1.2 ciphersuite on older-than-1.2 protocol) they wrote a TLS alert:

TLS 1.0 Alert [length 0002], fatal illegal_parameter 02 2f

When the server side next pumps (which won't happen, since we aborted) we'd throw System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> Interop+AppleCrypto+SslException: illegal parameter (which was making my selfhost test angry).

bartonjs commented 7 years ago

https://github.com/libressl-portable/openbsd/blob/libressl-v2.2.7/src/lib/libssl/src/ssl/s3_clnt.c#L889

Priya91 commented 7 years ago

@bartonjs If the bug is with SecureTransport choosing the wrong cipher, why does the same test from master branch on the same OSX 10.13 pass for this case? Did we make any changes in MacOS crypto backend in master that's not available in 2.0?

bartonjs commented 7 years ago

Did we make any changes in MacOS crypto backend in master that's not available in 2.0?

git diff shows that System.Net.Security has changed a bit between release/2.0.0 and master, but not anything that should affect a handshake. Nothing in an OSX-specific file, and the OSX Interop directory and shim are identical between the branches.

The System.Net.Http directory has had a lot more changes in master; but in the test logs I see both the default (Curl) handler and the Managed handler passing.

<test
    name="System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False)" 
    type="System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test"
    method="SetDelegate_ConnectionSucceeds"
    time="0.155252"
    result="Pass" />
<test
    name="System.Net.Http.Functional.Tests.ManagedHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False)"
    type="System.Net.Http.Functional.Tests.ManagedHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test"
    method="SetDelegate_ConnectionSucceeds"
    time="0.178225"
    result="Pass" />

So... that's a very good question.

bartonjs commented 7 years ago

So... that's a very good question.

... that I now have the answer to.

I edited the HttpClient library thusly:

--- a/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Unix.cs
+++ b/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Unix.cs
@@ -24,11 +24,13 @@ namespace System.Net.Http
             {
                 _managedHandler = new ManagedHandler();
                 _diagnosticsHandler = new DiagnosticsHandler(_managedHandler);
+Console.WriteLine("Created a ManagedHandler");
             }
             else
             {
                 _curlHandler = new CurlHandler();
                 _diagnosticsHandler = new DiagnosticsHandler(_curlHandler);
+Console.WriteLine("Created a CurlHandler");
             }
         }

$ dotnet xunit.console.netcore.exe System.Net.Http.Functional.Tests.dll -xml testResults.xml -notrait Benchmark=true -notrait category=nonnetcoreapptests -notrait category=nonosxtests -notrait category=OuterLoop -notrait category=failing -showprogress

resulted in

...
   System.Net.Http.Functional.Tests.ManagedHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) [STARTING]
Created a ManagedHandler
Created a ManagedHandler
   System.Net.Http.Functional.Tests.ManagedHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) [FINISHED] Time: 0.263747s

that part made sense (aside from having two messages...). Let's keep going:

...
   System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) [STARTING]
Created a ManagedHandler
   System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) [FINISHED] Time: 0.158235s

Once the word "ManagedHandler" appeared we never went back to CurlHandler. That explains why master passes, in master we're just letting SecureTransport talk to itself, and it's happy to pick a cipher that doesn't belong to the protocol version... after all, it's its bug.

$ dotnet xunit.console.netcore.exe System.Net.Http.Functional.Tests.dll -xml testResults.xml -notrait Benchmark=true -notrait category=nonnetcoreapptests -notrait category=nonosxtests -notrait category=OuterLoop -notrait category=failing -showprogress -method System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds

Discovering: System.Net.Http.Functional.Tests
Discovered:  System.Net.Http.Functional.Tests
Starting:    System.Net.Http.Functional.Tests
   System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) [STARTING]
Created a CurlHandler
Created a CurlHandler
   System.Net.Http.Functional.Tests.HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test.SetDelegate_ConnectionSucceeds(acceptedProtocol: Tls, requestOnlyThisProtocol: False) [FAIL]
      System.Net.Http.HttpRequestException : An error occurred while sending the request.
      ---- System.Net.Http.CurlException : SSL connect error
      Stack Trace:
            at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
stephentoub commented 7 years ago

Once the word "ManagedHandler" appeared we never went back to CurlHandler.

Oops! Have you looked into why?

bartonjs commented 7 years ago

dotnet/corefx#22228 fixed this in 2.0 and dotnet/corefx#22267 made it start failing (which we expected, but weren't seeing) in master. So closing this.