diff options
Diffstat (limited to 'lib/ssl/src/tls_handshake.erl')
-rw-r--r-- | lib/ssl/src/tls_handshake.erl | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl index 7a3d9712aa..7704ff7b6b 100644 --- a/lib/ssl/src/tls_handshake.erl +++ b/lib/ssl/src/tls_handshake.erl @@ -42,7 +42,7 @@ -export([encode_handshake/2]). %% Handshake decoding --export([get_tls_handshake/4, decode_handshake/3]). +-export([get_tls_handshakes/4, decode_handshake/3]). %% Handshake helper -export([ocsp_nonce/2]). @@ -245,7 +245,8 @@ hello(#client_hello{client_version = _ClientVersion, Version = ssl_handshake:select_supported_version(ClientVersions, Versions), do_hello(Version, Versions, CipherSuites, Hello, SslOpts, Info, Renegotiation) catch - error:_ -> + error:Reason:ST -> + ?SSL_LOG(info, handshake_error, [{reason,Reason}, {stacktrace, ST}]), throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake_data)) end; @@ -260,7 +261,8 @@ hello(#client_hello{client_version = ClientVersion, error:{case_clause,{asn1, Asn1Reason}} -> %% ASN-1 decode of certificate somehow failed throw(?ALERT_REC(?FATAL, ?INTERNAL_ERROR, {failed_to_decode_own_certificate, Asn1Reason})); - error:_ -> + error:Reason:ST -> + ?SSL_LOG(info, handshake_error, [{reason,Reason}, {stacktrace, ST}]), throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake_data)) end. @@ -285,7 +287,7 @@ encode_handshake(Package, Version) -> %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- --spec get_tls_handshake(tls_record:tls_version(), binary(), binary() | iolist(), +-spec get_tls_handshakes(tls_record:tls_version(), binary(), binary() | iolist(), ssl_options()) -> {[{tls_handshake(), binary()}], binary()}. %% @@ -293,10 +295,10 @@ encode_handshake(Package, Version) -> %% and returns it as a list of handshake messages, also returns leftover %% data. %%-------------------------------------------------------------------- -get_tls_handshake(Version, Data, <<>>, Options) -> - get_tls_handshake_aux(Version, Data, Options, []); -get_tls_handshake(Version, Data, Buffer, Options) -> - get_tls_handshake_aux(Version, list_to_binary([Buffer, Data]), Options, []). +get_tls_handshakes(Version, Data, <<>>, Options) -> + get_tls_handshakes_aux(Version, Data, Options, []); +get_tls_handshakes(Version, Data, Buffer, Options) -> + get_tls_handshakes_aux(Version, list_to_binary([Buffer, Data]), Options, []). %%-------------------------------------------------------------------- %%% Handshake helper @@ -330,8 +332,8 @@ handle_client_hello(Version, true -> SupportedHashSigns = maps:get(signature_algs, SslOpts, undefined), Curves = maps:get(elliptic_curves, HelloExt, undefined), - ClientHashSigns = maps:get(signature_algs, HelloExt, undefined), - ClientSignatureSchemes = maps:get(signature_algs_cert, HelloExt, undefined), + ClientHashSigns = get_signature_ext(signature_algs, HelloExt, Version), + ClientSignatureSchemes = get_signature_ext(signature_algs_cert, HelloExt, Version), AvailableHashSigns = ssl_handshake:available_signature_algs( ClientHashSigns, SupportedHashSigns, Version), ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, Version, ECCOrder), @@ -357,7 +359,7 @@ handle_client_hello(Version, CipherSuites, HelloExt, SslOpts, Session1, ConnectionStates0, - Renegotiation, HashSign) + Renegotiation, HashSign) end end; false -> @@ -426,19 +428,20 @@ enc_handshake(HandshakeMsg, Version) -> ssl_handshake:encode_handshake(HandshakeMsg, Version). %%-------------------------------------------------------------------- -get_tls_handshake_aux(Version, <<?BYTE(Type), ?UINT24(Length), +get_tls_handshakes_aux(Version, <<?BYTE(Type), ?UINT24(Length), Body:Length/binary,Rest/binary>>, #{log_level := LogLevel} = Opts, Acc) -> Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>, try decode_handshake(Version, Type, Body) of Handshake -> ssl_logger:debug(LogLevel, inbound, 'handshake', Handshake), - get_tls_handshake_aux(Version, Rest, Opts, [{Handshake,Raw} | Acc]) + get_tls_handshakes_aux(Version, Rest, Opts, [{Handshake,Raw} | Acc]) catch - error:_ -> - throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, handshake_decode_error)) + error:Reason:ST -> + ?SSL_LOG(info, handshake_error, [{reason,Reason}, {stacktrace, ST}]), + throw(?ALERT_REC(?FATAL, ?DECODE_ERROR, handshake_decode_error)) end; -get_tls_handshake_aux(_Version, Data, _, Acc) -> +get_tls_handshakes_aux(_Version, Data, _, Acc) -> {lists:reverse(Acc), Data}. decode_handshake({3, N}, ?HELLO_REQUEST, <<>>) when N < 4 -> @@ -470,3 +473,22 @@ ocsp_expect(true) -> staple; ocsp_expect(_) -> no_staple. + +get_signature_ext(Ext, HelloExt, {3,3}) -> + case maps:get(Ext, HelloExt, undefined) of + %% Signature algorithms was not sent + undefined -> + undefined; + %% Can happen when connection is upgraded and sni_fun changes + %% the versions option from default + #signature_algorithms{signature_scheme_list = Schemes} -> + #hash_sign_algos{hash_sign_algos = ssl_cipher:signature_schemes_1_2(Schemes)}; + #signature_algorithms_cert{} = Algos -> + Algos; + #hash_sign_algos{} = Algos -> + Algos + end; +get_signature_ext(Ext, HelloExt, _) -> + maps:get(Ext, HelloExt, undefined). + + |