summaryrefslogtreecommitdiff
path: root/lib/ssl/src/tls_handshake.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/src/tls_handshake.erl')
-rw-r--r--lib/ssl/src/tls_handshake.erl54
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).
+
+