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

TLS1.3 handshake fails for some SSL clients #5950

Closed
mk270 opened this issue Apr 30, 2022 · 15 comments
Closed

TLS1.3 handshake fails for some SSL clients #5950

mk270 opened this issue Apr 30, 2022 · 15 comments
Assignees
Labels
bug Issue is reported as a bug in progress team:PS Assigned to OTP team PS
Milestone

Comments

@mk270
Copy link

mk270 commented Apr 30, 2022

Describe the bug
When a client attempts to use BearSSL (and possibly other TLS implementations) to access my service, my service crashes; the service is based on OTP's ssl library, that is, the server is running on OTP and using it to provide a TLS-wrapped listener that it wants to accept connections on. The bug only happens with a subset of the TLS client implemenations that are available, and I can only easily reproduce it with BearSSL, but I believe there exist several other client implementations which expose the same problem. Many client implementations work fine and consistently fail to expose the bug.

As I understand it, a client ought not to be able to crash OTP's TLS server at all, no matter what it transmits.

The crashes all look like this:

12:59:04.909 [error] gen_statem <0.347.0> in state internal terminated with reason: {error,[tls_connection_1_3]}
12:59:04.912 [error] CRASH REPORT Process <0.347.0> with 1 neighbours crashed with reason: no function clause matching tls_handshake_1_3:get_supported_groups({elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}) line 2448
12:59:04.916 [error] Supervisor tls_connection_sup had child undefined started with {ssl_gen_statem,start_link,undefined} at <0.347.0> exit with reason no function clause matching tls_handshake_1_3:get_supported_groups({elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}) line 2448 in context child_terminated
12:59:04.917 [error] CRASH REPORT Process <0.348.0> with 0 neighbours exited with reason: {{function_clause,[{tls_handshake_1_3,get_supported_groups,[{elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}],[{file,"tls_handshake_1_3.erl"},{line,2448}]},{tls_handshake_1_3,do_start,2,[{file,"tls_handshake_1_3.erl"},{line,619}]},{tls_connection_1_3,start,3,[{file,"tls_connection_1_3.erl"},{line,268}]},{gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,1194}]},{tls_connection_1_3,init,1,[{file,"tls_connection_1_3.erl"},{line,194}]},{proc_lib,...}]},...} in gen:do_call/4 line 220

To Reproduce
The error seems to occur during the response to the initial SSL handshake.

  1. start a TLS-wrapped TCP listener
  2. attempt to connect via BearSSL

Specifically,

  1. start my blizanci server, which is an Erlang/OTP process that listens on a TCP port in the usual way
  2. try to connect to it with gmni, which uses BearSSL under the hood.

Expected behavior
A normal SSL handshake would occur, without crashing the Erlang process and terminating the connection.

Affected versions

Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [jit]

and

[{sasl,"SASL  CXC 138 11","4.1"},
 {blizanci,"A Gemini protocol server","4.1.0"}, 
 {ppool,"Worker pool library from LearnYouSomeErlang",
        "1.1.1"},
 {mime_lookup,"MIME types lookup service","0.1.1"},
 {realpath,"Filename canonicaliser","1.3.6"},
 {erlexec,"OS Process Manager","1.18.8"},
 {ranch,"Socket acceptor pool for TCP protocols.","2.0.0"},
 {lager,"Erlang logging framework","3.9.2"},
 {goldrush,"Erlang event stream processor","0.1.9"},
 {compiler,"ERTS  CXC 138 10","8.0.2"},
 {syntax_tools,"Syntax tools","2.6"},
 {runtime_tools,"RUNTIME_TOOLS","1.16.2"},
 {inets,"INETS  CXC 138 49","7.4.1"},
 {ssl,"Erlang/OTP SSL application","10.4.2"},
 {public_key,"Public key infrastructure","1.11.1"},
 {asn1,"The Erlang ASN1 compiler version 5.0.16","5.0.16"},
 {crypto,"CRYPTO","5.0.2"},
 {stdlib,"ERTS  CXC 138 10","3.15.2"},
 {kernel,"ERTS  CXC 138 10","8.0.2"}]

Additional context
Not a lot here. The thing reliably occurs whenever accepting a TLS/1.3 connection (but not other versions), and appears to implicate the handling of elliptic curve -based ciphers.

@mk270 mk270 added the bug Issue is reported as a bug label Apr 30, 2022
@IngelaAndin IngelaAndin added the team:PS Assigned to OTP team PS label May 2, 2022
@IngelaAndin
Copy link
Contributor

Could you use the option {log_level, debug} on your server and connect with a client that has the problem and share what the client hello looks like.

@mk270
Copy link
Author

mk270 commented May 2, 2022

Thanks!

I had misunderstood the interactions between lager and the default logger and not realised I was already logging significantly more detailed data:

2022-05-02 12:38:57 =ERROR REPORT====
** State machine <0.343.0> terminating
** Last event = {internal,{client_hello,{3,3},<<0,0,0,0,214,158,41,231,153,219,95,38,215,124,208,226,58,29,55,249,244,166,122,19,15,239,48,187,138,235,223,66>>,<<>>,undefined,[<<"<C3><8C><C2><A9>">>,<<"<C3><8C><C2><A8>">>,<<"<C3><80>+">>,<<"<C3><80>/">>,<<"<C3><80>,">>,<<"<C3><80>0">>,<<"<C3><80><C2><AC>">>,<<"<C3><80><C2><AD>">>,<<"<C3><80><C2><AE>">>,<<"<C3><80><C2><AF>">>,<<"<C3><80>#">>,<<"<C3><80>'">>,<<"<C3><80>$">>,<<"<C3><80>(">>,<<"<C3><80>\t">>,<<192,19>>,<<"<C3><80>\n">>,<<192,20>>,<<"<C3><80>-">>,<<"<C3><80>1">>,<<"<C3><80>.">>,<<"<C3><80>2">>,<<"<C3><80>%">>,<<"<C3><80>)">>,<<"<C3><80>&">>,<<"<C3><80>*">>,<<192,4>>,<<192,14>>,<<192,5>>,<<192,15>>,<<0,156>>,<<0,157>>,<<192,156>>,<<192,157>>,<<"<C3><80><C2><A0>">>,<<"<C3><80><C2><A1>">>,<<0,60>>,<<0,61>>,<<0,47>>,<<0,53>>,<<"<C3><80>\b">>,<<192,18>>,<<192,3>>,<<"<C3><80>\r">>,<<0,10>>],[0],#{alpn => undefined,ec_point_formats => {ec_point_formats,[0]},elliptic_curves => {elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]},next_protocol_negotiation => undefined,renegotiation_info => {renegotiation_info,<<0>>},signature_algs => {hash_sign_algos,[{sha256,ecdsa},{sha224,ecdsa},{sha384,ecdsa},{sha512,ecdsa},{sha,ecdsa},{sha256,rsa},{sha224,rsa},{sha384,rsa},{sha512,rsa},{sha,rsa}]},sni => {sni,"gemini.ucant.org"},srp => undefined}}}
** When server state  = [{data,[{"State",{start,{state,{static_env,server,gen_tcp,tls_gen_connection,tcp,tcp_closed,tcp_error,tcp_passive,"localhost",1965,#Port<0.11>,#Ref<0.3117591183.1176109057.160989>,no_longer_defined,undefined,{ssl_crl_cache,{{#Ref<0.3117591183.1176109057.160992>,#Ref<0.3117591183.1176109057.160993>},[]}},{#Ref<0.3117591183.1176109057.160990>,#Ref<0.3117591183.1176109057.160991>},#Ref<0.3117591183.1175977985.171101>,[{option_tracker,<0.307.0>},{session_tickets_tracker,disabled},{session_id_tracker,not_relevant}]},"***",#{password => "***",supported_groups => {supported_groups,[x25519,x448,secp256r1,secp384r1]},alpn_advertised_protocols => undefined,renegotiate_at => 268435456,cookie => true,ocsp_nonce => true,sni_fun => undefined,erl_dist => false,psk_identity => "***",use_ticket => undefined,reuse_session => #Fun<ssl.13.104474974>,signature_algs_cert => undefined,ocsp_responder_certs => [],key_update_at => 388736063997,session_tickets => disabled,server_name_indication => undefined,reuse_sessions => true,max_handshake_size => 262144,middlebox_comp_mode => true,handshake => full,crl_check => false,log_level => notice,dh => "***",srp_identity => "***",user_lookup_fun => undefined,sni_hosts => [],anti_replay => undefined,cert => "***",fail_if_no_peer_cert => false,ciphers => [<<19,2>>,<<19,1>>,<<19,3>>,<<19,4>>,<<19,5>>],next_protocol_selector => undefined,dhfile => undefined,cacerts => "***",ocsp_stapling => false,keep_secrets => false,client_renegotiation => true,verify_fun => {#Fun<blizanci_config.0.823964>,[]},secure_renegotiate => true,next_protocols_advertised => undefined,verify => verify_peer,versions => [{3,4}],honor_cipher_order => false,cacertfile => <<"/dev/null">>,hibernate_after => infinity,certfile => <<"/home/mk270/ssl/certificate.pem">>,keyfile => <<"/home/mk270/ssl/key.pem">>,alpn_preferred_protocols => undefined,fallback => undefined,beast_mitigation => one_n_minus_one,max_fragment_length => undefined,signature_algs => [ecdsa_secp521r1_sha512,ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,eddsa_ed25519,eddsa_ed448,rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,ecdsa_sha1,rsa_pkcs1_sha1,{sha512,ecdsa},{sha512,rsa},{sha384,ecdsa},{sha384,rsa},{sha256,ecdsa},{sha256,rsa},{sha224,ecdsa},{sha224,rsa},{sha,ecdsa},{sha,rsa},{sha,dsa}],eccs => {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},{1,3,132,0,3},{1,3,132,0,26},{1,3,132,0,27},{1,3,132,0,32},{1,3,132,0,33},{1,3,132,0,24},{1,3,132,0,25},{1,3,132,0,31},{1,2,840,10045,3,1,1},{1,3,132,0,1},{1,3,132,0,2},{1,3,132,0,15},{1,3,132,0,9},{1,3,132,0,8},{1,3,132,0,30}]},depth => 10,key => "***",padding_check => true,early_data => undefined,crl_cache => {ssl_crl_cache,{internal,[]}},honor_ecc_order => false,protocol => tls,customize_hostname_check => [],partial_chain => #Fun<ssl.11.104474974>},{socket_options,binary,raw,0,0,false},"***","***",false,#{active_n => 100,active_n_toggle => false,sender => <0.342.0>},"***",undefined,"***","***","***",undefined,{<0.345.0>,#Ref<0.3117591183.1175977985.171126>},undefined}}}]}]
** Reason for termination = error:function_clause
** Callback modules = [tls_connection_1_3]
** Callback mode = state_functions
** Stacktrace =
**  [{tls_handshake_1_3,get_supported_groups,[{elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}],[{file,"tls_handshake_1_3.erl"},{line,2448}]},{tls_handshake_1_3,do_start,2,[{file,"tls_handshake_1_3.erl"},{line,619}]},{tls_connection_1_3,start,3,[{file,"tls_connection_1_3.erl"},{line,268}]},{gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,1194}]},{tls_connection_1_3,init,1,[{file,"tls_connection_1_3.erl"},{line,194}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]
** Time-outs: {1,[{{timeout,handshake},close}]}
2022-05-02 12:38:57 =CRASH REPORT====
  crasher:
    initial call: ssl_gen_statem:init/1
    pid: <0.343.0>
    registered_name: []
    exception error: {function_clause,[{tls_handshake_1_3,get_supported_groups,[{elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}],[{file,"tls_handshake_1_3.erl"},{line,2448}]},{tls_handshake_1_3,do_start,2,[{file,"tls_handshake_1_3.erl"},{line,619}]},{tls_connection_1_3,start,3,[{file,"tls_connection_1_3.erl"},{line,268}]},{gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,1194}]},{tls_connection_1_3,init,1,[{file,"tls_connection_1_3.erl"},{line,194}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}
    ancestors: [tls_connection_sup,tls_sup,ssl_connection_sup,ssl_sup,<0.82.0>]
    message_queue_len: 0
    messages: []
    links: [<0.342.0>,<0.93.0>]
    dictionary: [{ssl_pem_cache,ssl_pem_cache},{ssl_manager,ssl_manager}]
    trap_exit: true
    status: running
    heap_size: 4185
    stack_size: 29
    reductions: 8010
  neighbours:
    neighbour: [{pid,<0.342.0>},{registered_name,[]},{initial_call,{tls_sender,init,['Argument__1']}},{current_function,{gen_statem,loop_receive,3}},{ancestors,[<0.308.0>]},{message_queue_len,0},{links,[<0.343.0>]},{trap_exit,false},{status,waiting},{heap_size,233},{stack_size,11},{reductions,93},{current_stacktrace,[{gen_statem,loop_receive,3,[{file,"gen_statem.erl"},{line,1034}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}]
2022-05-02 12:38:57 =SUPERVISOR REPORT====
     Supervisor: {local,tls_connection_sup}
     Context:    child_terminated
     Reason:     {function_clause,[{tls_handshake_1_3,get_supported_groups,[{elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}],[{file,"tls_handshake_1_3.erl"},{line,2448}]},{tls_handshake_1_3,do_start,2,[{file,"tls_handshake_1_3.erl"},{line,619}]},{tls_connection_1_3,start,3,[{file,"tls_connection_1_3.erl"},{line,268}]},{gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,1194}]},{tls_connection_1_3,init,1,[{file,"tls_connection_1_3.erl"},{line,194}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}
     Offender:   [{pid,<0.343.0>},{id,undefined},{mfargs,{ssl_gen_statem,start_link,undefined}},{restart_type,temporary},{significant,false},{shutdown,4000},{child_type,worker}]

2022-05-02 12:38:57 =CRASH REPORT====
  crasher:
    initial call: blizanci_gemini:init/1
    pid: <0.345.0>
    registered_name: []
    exception exit: {{{function_clause,[{tls_handshake_1_3,get_supported_groups,[{elliptic_curves,[{1,2,840,10045,3,1,7},{1,3,132,0,34},{1,3,132,0,35},{1,3,101,110}]}],[{file,"tls_handshake_1_3.erl"},{line,2448}]},{tls_handshake_1_3,do_start,2,[{file,"tls_handshake_1_3.erl"},{line,619}]},{tls_connection_1_3,start,3,[{file,"tls_connection_1_3.erl"},{line,268}]},{gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,1194}]},{tls_connection_1_3,init,1,[{file,"tls_connection_1_3.erl"},{line,194}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]},{gen_statem,call,[<0.343.0>,{start,5000},infinity]}},[{gen,do_call,4,[{file,"gen.erl"},{line,220}]},{gen_statem,call_dirty,4,[{file,"gen_statem.erl"},{line,684}]},{ssl_gen_statem,call,2,[{file,"ssl_gen_statem.erl"},{line,1180}]},{ssl_gen_statem,handshake,2,[{file,"ssl_gen_statem.erl"},{line,222}]},{ranch_ssl,handshake,3,[{file,"/home/mk270/Src/blizanci/_build/default/lib/ranch/src/ranch_ssl.erl"},{line,160}]},{ranch,handshake1,2,[{file,"/home/mk270/Src/blizanci/_build/default/lib/ranch/src/ranch.erl"},{line,244}]},{blizanci_gemini,init,1,[{file,"/home/mk270/Src/blizanci/apps/blizanci/src/blizanci_gemini.erl"},{line,137}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}
    ancestors: [<0.296.0>,<0.294.0>,<0.293.0>,ranch_sup,<0.269.0>]
    message_queue_len: 0
    messages: []
    links: [<0.296.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 1598
    stack_size: 29
    reductions: 317
  neighbours:

@IngelaAndin
Copy link
Contributor

It looks like a version mismatch of some kind. The TLS-1.3 state machine seems to be handling TLS-1.2 decode data! Could you try the latest maint branch where one version mismatch problem has been solved, just to make sure? Your problem is not "total" match, but I would like to rule it out before trying to dig deeper.

@mk270
Copy link
Author

mk270 commented May 2, 2022

Ok - I'll give maint a try.

FYI, the only config I'm using is here: https://github.com/mk270/blizanci/blob/master/apps/blizanci/src/blizanci_config.erl#L28; those values are being passed through to ranch here: https://github.com/mk270/blizanci/blob/master/apps/blizanci/src/blizanci_app.erl#L26 ; other than this, I don't think I'm doing anything special/unusual/ill-advised.

@mk270
Copy link
Author

mk270 commented May 2, 2022

I tried

kerl build git https://github.com/erlang/otp.git maint 24.3.3_maint

but I got "Error mirroring remote git repository"; what am I doing wrong?

@IngelaAndin
Copy link
Contributor

IngelaAndin commented May 3, 2022

You can now try OTP-24.3.4 if that is easier for you!

@IngelaAndin
Copy link
Contributor

I noticed you have configured your server to run only TLS-1.3 but the client seems to be wanting to run TLS-1.2. I see that we have fixed an issue in a newer version than yours that is described:

"Corrected error handling to correctly generate an
insufficient security alert when there are no suitable
groups that can be negotiated in TLS-1.3 instead of
crashing resulting in an internal error alert."

It matches your crash fairly well, although I would have expected a protocol version alert. Did you have any luck testing with the latest released version? I could perhaps try out your client later but I do not have time for that at the moment.

@mk270
Copy link
Author

mk270 commented May 10, 2022

ok, well, now under 24.3.4 the server doesn't crash. I can't tell what, if anything, is happening as I can't seem to reconfigure the logger to see what's going on, server-side.

The clients still can't establish a connection, but that may be their own fault.

Thanks

@mk270 mk270 closed this as completed May 10, 2022
@IngelaAndin
Copy link
Contributor

You could try starting a simple Erlang/TLS server in the Erlang shell and then connecting to it, skipping all the Lager/Logger interactions. By default you should then get notice level logs an the erlang server should log its generated TLS ALERT. And you could also add {log_level, debug} to the ssl options list to the server and you should be able to see the clients hello message. Good luck!

@mk270
Copy link
Author

mk270 commented May 11, 2022

I'm very happy to keep investigating, not least as it could be that a bug remains!

@mk270
Copy link
Author

mk270 commented May 11, 2022

Bingo:

After doing:

ssl:start().
{ok, ListenSocket} = ssl:listen(9999, [{certfile, "/home/mk270/ssl/certificate.pem"}, {keyfile, "/home/mk270/ssl/key.pem"}, {reuseaddr, true}, {versions, ['tlsv1.3']}]).
{ok, TLSTransportSocket} = ssl:transport_accept(ListenSocket).
{ok, Socket} = ssl:handshake(TLSTransportSocket).

I get:

4> {ok, Socket} = ssl:handshake(TLSTransportSocket).
                            =NOTICE REPORT==== 11-May-2022::12:56:33.682556 ===                             
TLS server: In state start at tls_handshake_1_3.erl:2964 generated SERVER ALERT: Fatal - Illegal Parameter

** exception error: no match of right hand side value {error,
                                                       {tls_alert,
                                                        {illegal_parameter,
                                                         "TLS server: In state start at tls_handshake_1_3.erl:2964 generated SERVER ALERT: Fatal - Illegal Parameter\n"}}}

@mk270 mk270 reopened this May 11, 2022
@mk270
Copy link
Author

mk270 commented May 11, 2022

reading (216 bytes) TLS 1.0 Record Protocol, handshake
0000 - 16 03 01 00 d3 01 00 00  cf 03 03 00 00 00 00 00    ................
0010 - d3 3b 66 3e 24 31 48 5a  43 3b 00 19 c4 a1 71 65    .;f>$1HZC;....qe
0020 - bf fc ec 7b b6 46 8a 03  56 84 66 00 00 5a cc a9    ...{.F..V.f..Z..
0030 - cc a8 c0 2b c0 2f c0 2c  c0 30 c0 ac c0 ad c0 ae    ...+./.,.0......
0040 - c0 af c0 23 c0 27 c0 24  c0 28 c0 09 c0 13 c0 0a    ...#.'.$.(......
0050 - c0 14 c0 2d c0 31 c0 2e  c0 32 c0 25 c0 29 c0 26    ...-.1...2.%.).&
0060 - c0 2a c0 04 c0 0e c0 05  c0 0f 00 9c 00 9d c0 9c    .*..............
0070 - c0 9d c0 a0 c0 a1 00 3c  00 3d 00 2f 00 35 c0 08    .......<.=./.5..
0080 - c0 12 c0 03 c0 0d 00 0a  01 00 00 4c ff 01 00 01    ...........L....
0090 - 00 00 00 00 15 00 13 00  00 10 67 65 6d 69 6e 69    ..........gemini
00a0 - 2e 75 63 61 6e 74 2e 6f  72 67 00 0d 00 16 00 14    .ucant.org......
00b0 - 04 03 03 03 05 03 06 03  02 03 04 01 03 01 05 01    ................
00c0 - 06 01 02 01 00 0a 00 0a  00 08 00 17 00 18 00 19    ................
00d0 - 00 1d 00 0b 00 02 01 00                             ........
<<< TLS 1.2 Handshake, ClientHello
[{client_version,{3,3}},
 {random,<<0,0,0,0,0,211,59,102,62,36,49,72,90,67,59,0,25,196,161,113,101,191,
           252,236,123,182,70,138,3,86,132,102>>},
 {session_id,<<>>},
 {cookie,undefined},
 {cipher_suites,["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_256_GCM_SHA384",
                 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
                 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM",
                 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM",
                 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8",
                 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8",
                 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
                 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
                 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
                 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
                 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
                 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
                 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
                 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
                 "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
                 "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
                 "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
                 "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
                 "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
                 "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
                 "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
                 "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
                 "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
                 "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
                 "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
                 "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
                 "TLS_RSA_WITH_AES_128_GCM_SHA256",
                 "TLS_RSA_WITH_AES_256_GCM_SHA384","0x0c0xc9","0x0c0xd9",
                 "0x0c0x0a","0x0c0x1a","TLS_RSA_WITH_AES_128_CBC_SHA256",
                 "TLS_RSA_WITH_AES_256_CBC_SHA256",
                 "TLS_RSA_WITH_AES_128_CBC_SHA",
                 "TLS_RSA_WITH_AES_256_CBC_SHA",
                 "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
                 "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
                 "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
                 "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
                 "TLS_RSA_WITH_3DES_EDE_CBC_SHA"]},
 {compression_methods,[0]},
 {extensions,#{alpn => undefined,
               ec_point_formats => {ec_point_formats,[0]},
               elliptic_curves =>
                   {elliptic_curves,[{1,2,840,10045,3,1,7},
                                     {1,3,132,0,34},
                                     {1,3,132,0,35},
                                     {1,3,101,110}]},
               next_protocol_negotiation => undefined,
               renegotiation_info => {renegotiation_info,<<0>>},
               signature_algs =>
                   {hash_sign_algos,[{sha256,ecdsa},
                                     {sha224,ecdsa},
                                     {sha384,ecdsa},
                                     {sha512,ecdsa},
                                     {sha,ecdsa},
                                     {sha256,rsa},
                                     {sha224,rsa},
                                     {sha384,rsa},
                                     {sha512,rsa},
                                     {sha,rsa}]},
               sni => {sni,"gemini.ucant.org"},
               srp => undefined}}]
writing (7 bytes) TLS 1.2 Record Protocol, alert
0000 - 15 03 03 00 02 02 2f                                ....../

@mk270
Copy link
Author

mk270 commented May 11, 2022

It looks like the client doesn't support TLS 1.3 ; I'm surprised neither the client nor OTP's ssl library reports this explicitly.

@IngelaAndin
Copy link
Contributor

Yes, the client does not support TLS-1.3 as it is sending a TLS-1.2 hello message. I am also surprised that our code did not send a protocol version alert instead of an illegal parameter alert. This means that the code somehow missed the protocol version check and later concludes that the hello message does not match a TLS-1.3 hello message. The end result in your case will be sort of the same, that these clients will not be able to connect to the server. However, I think we should fix it so that you will get a protocol version alert instead. The client does not really know that it was the protocol version that was the problem as all it knows is what alert the server responded with.

@mk270
Copy link
Author

mk270 commented May 12, 2022

Well, thank you again for your help. Glad we persisted in tracking this down. It doesn't seem easy to exploit this behaviour from the client-side, but it's probably best (as you imply) to fix it.

IngelaAndin added a commit to IngelaAndin/otp that referenced this issue Jun 5, 2022
Change implementation use gen_statem postpone for hello message when users
want to pause handshake instead of legacy "reimplementation" of postpone

Closes erlang#5950
IngelaAndin added a commit to IngelaAndin/otp that referenced this issue Jun 7, 2022
Change implementation use gen_statem postpone for hello message when users
want to pause handshake instead of legacy "reimplementation" of postpone

Closes erlang#5950
IngelaAndin added a commit to IngelaAndin/otp that referenced this issue Jun 7, 2022
Change implementation use gen_statem postpone for hello message when users
want to pause handshake instead of legacy "reimplementation" of postpone

Closes erlang#5950
IngelaAndin added a commit that referenced this issue Jun 8, 2022
…into maint

* ingela/ssl/protocol-version-TLS-1.3/GH-5950/OTP-18129:
  ssl: Reject unsupported previous version with protocol alert
IngelaAndin pushed a commit that referenced this issue Jun 8, 2022
…into maint-24

* ingela/ssl/protocol-version-TLS-1.3/GH-5950/OTP-18129:
  ssl: Reject unsupported previous version with protocol alert
IngelaAndin pushed a commit that referenced this issue Jun 9, 2022
…into maint-25

* ingela/ssl/protocol-version-TLS-1.3/GH-5950/OTP-18129:
  ssl: Reject unsupported previous version with protocol alert

# Conflicts:
#	lib/ssl/src/ssl_gen_statem.erl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug in progress team:PS Assigned to OTP team PS
Projects
None yet
Development

No branches or pull requests

2 participants