-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Describe the bug
Connecting to SSL socket using TLS 1.2 returns an error: {:error, {:tls_alert, {:handshake_failure, ~c"TLS server: In state hello at tls_handshake.erl:269 generated SERVER ALERT: Fatal - Handshake Failure\n malformed_handshake_data"}}}.
Doing ssl.versions reports both TLS 1.2 and 1.3 are supported:
SSL version [ssl_app: ~c"11.0.2", supported: [:"tlsv1.3", :"tlsv1.2"], supported_dtls: [:"dtlsv1.2"], available: [:"tlsv1.3", :"tlsv1.2", :"tlsv1.1", :tlsv1], available_dtls: [:"dtlsv1.2", :dtlsv1], implemented: [: "tlsv1.3", :"tlsv1.2", :"tlsv1.1", :tlsv1], implemented_dtls: [:"dtlsv1.2", :dtlsv1]]
To Reproduce
defmodule TlsHandshakeTest do
use ExUnit.Case, async: false
setup do
{:module, :ssl} = Code.ensure_loaded(:ssl)
IO.puts("SSL version #{inspect(:ssl.versions())}")
:ok
end
test "SSL client" do
{:ok, sock} =
:ssl.listen(0,
active: false,
reuseaddr: true,
mode: :binary,
packet: :raw, verify: :verify_none,
versions: [:"tlsv1.2", :"tlsv1.3"]
)
{:ok, {_address, port}} = :ssl.sockname(sock)
task =
Task.async(fn ->
{:ok, sock} = :ssl.transport_accept(sock)
{:ok, sock} = :ssl.handshake(sock, 1_000)
{:ok, sock}
end)
assert {:ok, conn} =
:ssl.connect(
to_charlist("localhost"),
port,
[active: false, verify: :verify_none, versions: [:"tlsv1.2"], log_level: :debug],
1_000
)
assert {:ok, _sock} = Task.await(task) end
end
Expected behavior
A normal SSL handshake would occur, without crashing the Erlang process and terminating the connection.
Affected versions
Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]
[nix-shell@jane:~/git/tls-handshake]$ erl -eval '{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), io:fwrite(Version), halt().' -noshell
26.0.2
Additional context
[nix-shell@jane:~/git/tls-handshake]$ mix test --no-start test/integration_test.exs
SSL version [ssl_app: ~c"11.0.2", supported: [:"tlsv1.3", :"tlsv1.2"], supported_dtls: [:"dtlsv1.2"], available: [:"tlsv1.3", :"tlsv1.2", :"tlsv1.1", :tlsv1], available_dtls: [:"dtlsv1.2", :dtlsv1], implemented: [:"tlsv1.3", :"tlsv1.2", :"tlsv1.1", :tlsv1], implemented_dtls: [:"dtlsv1.2", :dtlsv1]]
>>> TLS 1.2 Handshake, ClientHello
[{client_version,{3,3}},
{random,<<100,174,65,159,192,117,62,96,112,144,198,1,226,178,45,154,73,131,
182,38,28,248,173,218,225,6,110,24,227,136,213,78>>},
{session_id,<<>>},
{cookie,undefined},
{cipher_suites,["TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_CCM",
"TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CCM",
"TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8",
"TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
"TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA"]},
{compression_methods,[0]},
{extensions,#{srp => undefined,
signature_algs =>
{hash_sign_algos,[{sha512,ecdsa},
{sha512,rsa_pss_pss},
{sha512,rsa_pss_rsae},
{sha512,rsa},
{sha384,ecdsa},
{sha384,rsa_pss_pss},
{sha384,rsa_pss_rsae},
{sha384,rsa},
{sha256,ecdsa},
{sha256,rsa_pss_pss},
{sha256,rsa_pss_rsae},
{sha256,rsa}]},
signature_algs_cert => undefined,use_srtp => undefined,
elliptic_curves =>
{elliptic_curves,[{1,3,132,0,39},
{1,3,132,0,38},
{1,3,132,0,35},
{1,3,36,3,3,2,8,1,1,13},
{1,3,132,0,36},
{1,3,132,0,37},
{1,3,36,3,3,2,8,1,1,11},
{1,3,132,0,34},
{1,3,132,0,16},
{1,3,132,0,17},
{1,3,36,3,3,2,8,1,1,7},
{1,3,132,0,10},
{1,2,840,10045,3,1,7}]},
sni => {sni,"localhost"},
max_frag_enum => undefined,alpn => undefined,
ec_point_formats => {ec_point_formats,[0]},
next_protocol_negotiation => undefined,
renegotiation_info => {renegotiation_info,undefined}}}]
14:01:04.005 [debug] [message: {:client_hello, {3, 3}, <<100, 174, 65, 159, 192, 117, 62, 96, 112, 144, 198, 1, 226, 178, 45, 154, 73, 131, 182, 38, 28, 248, 173, 218, 225, 6, 110, 24, 227, 136, 213, 78>>, "", :undefined, [<<0, 255>>, <<192, 44>>, <<192, 48>>, <<192, 173>>, <<192, 175>>, <<192, 36>>, <<192, 40>>, "̩", "̨", <<192, 43>>, <<192, 47>>, <<192, 172>>, <<192, 174>>, <<192, 46>>, <<192, 50>>, <<192, 38>>, <<192, 42>>, <<192, 45>>, <<192, 49>>, <<192, 35>>, <<192, 39>>, <<192, 37>>, <<192, 41>>, <<0, 159>>, <<0, 163>>, <<0, 107>>, <<0, 106>>, <<0, 158>>, <<0, 162>>, "̪", <<0, 103>>, <<0, 64>>, <<192, 10>>, <<192, 20>>, <<192, 5>>, <<192, 15>>, <<192, 9>>, <<192, 19>>, <<192, 4>>, <<192, 14>>, <<0, 57>>, <<0, ...>>, <<...>>, ...], [0], %{srp: :undefined, signature_algs: {:hash_sign_algos, [sha512: :ecdsa, sha512: :rsa_pss_pss, sha512: :rsa_pss_rsae, sha512: :rsa, sha384: :ecdsa, sha384: :rsa_pss_pss, sha384: :rsa_pss_rsae, sha384: :rsa, sha256: :ecdsa, sha256: :rsa_pss_pss, sha256: :rsa_pss_rsae, sha256: :rsa]}, signature_algs_cert: :undefined, use_srtp: :undefined, elliptic_curves: {:elliptic_curves, [{1, 3, 132, 0, 39}, {1, 3, 132, 0, 38}, {1, 3, 132, 0, 35}, {1, 3, 36, 3, 3, 2, 8, 1, 1, 13}, {1, 3, 132, 0, 36}, {1, 3, 132, 0, 37}, {1, 3, 36, 3, 3, 2, 8, 1, 1, 11}, {1, 3, 132, 0, 34}, {1, 3, 132, 0, 16}, {1, 3, 132, 0, 17}, {1, 3, 36, 3, 3, 2, 8, 1, 1, 7}, {1, 3, 132, 0, 10}, {1, 2, 840, 10045, 3, 1, 7}]}, sni: {:sni, ~c"localhost"}, max_frag_enum: :undefined, alpn: :undefined, ec_point_formats: {:ec_point_formats, [0]}, next_protocol_negotiation: :undefined, renegotiation_info: {:renegotiation_info, :undefined}}}, protocol: :handshake, direction: :outbound]
writing (224 bytes) TLS 1.2 Record Protocol, handshake
0000 - 16 03 03 00 db 01 00 00 d7 03 03 64 ae 41 9f c0 ...........d.A..
0010 - 75 3e 60 70 90 c6 01 e2 b2 2d 9a 49 83 b6 26 1c u>`p.....-.I..&.
0020 - f8 ad da e1 06 6e 18 e3 88 d5 4e 00 00 58 00 ff .....n....N..X..
0030 - c0 2c c0 30 c0 ad c0 af c0 24 c0 28 cc a9 cc a8 .,.0.....$.(....
0040 - c0 2b c0 2f c0 ac c0 ae c0 2e c0 32 c0 26 c0 2a .+./.......2.&.*
0050 - c0 2d c0 31 c0 23 c0 27 c0 25 c0 29 00 9f 00 a3 .-.1.#.'.%.)....
0060 - 00 6b 00 6a 00 9e 00 a2 cc aa 00 67 00 40 c0 0a .k.j.......g.@..
0070 - c0 14 c0 05 c0 0f c0 09 c0 13 c0 04 c0 0e 00 39 ...............9
0080 - 00 38 00 33 00 32 01 00 00 56 00 0b 00 02 01 00 .8.3.2...V......
0090 - 00 00 00 0e 00 0c 00 00 09 6c 6f 63 61 6c 68 6f .........localho
00a0 - 73 74 00 0a 00 1c 00 1a 00 0e 00 0d 00 19 00 1c st..............
00b0 - 00 0b 00 0c 00 1b 00 18 00 09 00 0a 00 1a 00 16 ................
00c0 - 00 17 00 0d 00 1a 00 18 06 03 08 0b 08 06 06 01 ................
00d0 - 05 03 08 0a 08 05 05 01 04 03 08 09 08 04 04 01 ................
14:01:04.016 [debug] [message: [<<22, 3, 3, 0, 219>>, <<1, 0, 0, 215, 3, 3, 100, 174, 65, 159, 192, 117, 62, 96, 112, 144, 198, 1, 226, 178, 45, 154, 73, 131, 182, 38, 28, 248, 173, 218, 225, 6, 110, 24, 227, 136, 213, 78, 0, 0, 88, 0, 255, 192, 44, 192, 48, ...>>], protocol: :record, direction: :outbound]
14:01:04.024 [debug] [message: {:ssl_tls, 21, {3, 3}, <<2, 40>>, false}, protocol: :record, direction: :inbound]
reading (7 bytes) TLS 1.2 Record Protocol, alert
0000 - 15 03 03 00 02 02 28 ......(
14:01:04.024 [notice] TLS :server: In state :hello at tls_handshake.erl:269 generated SERVER ALERT: Fatal - Handshake Failure
- :malformed_handshake_data
14:01:04.033 [notice] TLS :client: In state :hello received SERVER ALERT: Fatal - Handshake Failure
14:01:04.026 [error] Task #PID<0.234.0> started from #PID<0.230.0> terminating
** (MatchError) no match of right hand side value: {:error, {:tls_alert, {:handshake_failure, ~c"TLS server: In state hello at tls_handshake.erl:269 generated SERVER ALERT: Fatal - Handshake Failure\n malformed_handshake_data"}}}
test/integration_test.exs:28: anonymous fn/1 in TlsHandshakeTest."test SSL client"/1
(elixir 1.15.2) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
(elixir 1.15.2) lib/task/supervised.ex:36: Task.Supervised.reply/4
Function: #Function<0.61065134/0 in TlsHandshakeTest."test SSL client"/1>
Args: []
1) test SSL client (TlsHandshakeTest)
test/integration_test.exs:12
** (EXIT from #PID<0.230.0>) an exception was raised:
** (MatchError) no match of right hand side value: {:error, {:tls_alert, {:handshake_failure, ~c"TLS server: In state hello at tls_handshake.erl:269 generated SERVER ALERT: Fatal - Handshake Failure\n malformed_handshake_data"}}}
test/integration_test.exs:28: anonymous fn/1 in TlsHandshakeTest."test SSL client"/1
(elixir 1.15.2) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
(elixir 1.15.2) lib/task/supervised.ex:36: Task.Supervised.reply/4