aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/doc/src/notes.xml76
-rw-r--r--lib/ssl/src/ssl_cipher.erl10
-rw-r--r--lib/ssl/src/ssl_handshake.erl18
-rw-r--r--lib/ssl/src/tls_connection.erl5
-rw-r--r--lib/ssl/src/tls_v1.erl22
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl80
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl41
-rw-r--r--lib/ssl/test/ssl_test_lib.erl2
-rw-r--r--lib/ssl/vsn.mk2
9 files changed, 239 insertions, 17 deletions
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index b0473ff7d7..f320b4c006 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -27,6 +27,66 @@
</header>
<p>This document describes the changes made to the SSL application.</p>
+<section><title>SSL 9.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct handshake handling, might cause strange symptoms
+ such as ASN.1 certificate decoding issues.</p>
+ <p>
+ Own Id: OTP-15879 Aux Id: ERL-968 </p>
+ </item>
+ <item>
+ <p>
+ Fix handling of the signature_algorithms_cert extension
+ in the ClientHello handshake message.</p>
+ <p>
+ Own Id: OTP-15887 Aux Id: ERL-973 </p>
+ </item>
+ <item>
+ <p>
+ Handle new ClientHello extensions when handshake is
+ paused by the {handshake, hello} ssl option.</p>
+ <p>
+ Own Id: OTP-15888 Aux Id: ERL-975 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 9.3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Returned "alert error string" is now same as logged alert
+ string</p>
+ <p>
+ Own Id: OTP-15844</p>
+ </item>
+ <item>
+ <p>
+ Fix returned extension map fields to follow the
+ documentation.</p>
+ <p>
+ Own Id: OTP-15862 Aux Id: ERL-951 </p>
+ </item>
+ <item>
+ <p>
+ Avoid DTLS crash due to missing gen_server return value
+ in DTLS packet demux process.</p>
+ <p>
+ Own Id: OTP-15864 Aux Id: ERL-962 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SSL 9.3.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -119,6 +179,22 @@
</section>
+<section><title>SSL 9.2.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct handshake handling, might cause strange symptoms
+ such as ASN.1 certificate decoding issues.</p>
+ <p>
+ Own Id: OTP-15879 Aux Id: ERL-968 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SSL 9.2.3.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 21db887bb5..4da50d2af8 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -923,6 +923,12 @@ signature_scheme(rsa_pss_pss_sha384) -> ?RSA_PSS_PSS_SHA384;
signature_scheme(rsa_pss_pss_sha512) -> ?RSA_PSS_PSS_SHA512;
signature_scheme(rsa_pkcs1_sha1) -> ?RSA_PKCS1_SHA1;
signature_scheme(ecdsa_sha1) -> ?ECDSA_SHA1;
+%% Handling legacy signature algorithms
+signature_scheme({Hash0, Sign0}) ->
+ Hash = hash_algorithm(Hash0),
+ Sign = sign_algorithm(Sign0),
+ <<?UINT16(SigAlg)>> = <<?BYTE(Hash),?BYTE(Sign)>>,
+ SigAlg;
signature_scheme(?RSA_PKCS1_SHA256) -> rsa_pkcs1_sha256;
signature_scheme(?RSA_PKCS1_SHA384) -> rsa_pkcs1_sha384;
signature_scheme(?RSA_PKCS1_SHA512) -> rsa_pkcs1_sha512;
@@ -962,7 +968,9 @@ scheme_to_components(rsa_pss_pss_sha256) -> {sha256, rsa_pss_pss, undefined};
scheme_to_components(rsa_pss_pss_sha384) -> {sha384, rsa_pss_pss, undefined};
scheme_to_components(rsa_pss_pss_sha512) -> {sha512, rsa_pss_pss, undefined};
scheme_to_components(rsa_pkcs1_sha1) -> {sha1, rsa_pkcs1, undefined};
-scheme_to_components(ecdsa_sha1) -> {sha1, ecdsa, undefined}.
+scheme_to_components(ecdsa_sha1) -> {sha1, ecdsa, undefined};
+%% Handling legacy signature algorithms
+scheme_to_components({Hash,Sign}) -> {Hash, Sign, undefined}.
%% TODO: Add support for EC and RSA-SSA signatures
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 53676ab355..c6698bc74a 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -364,7 +364,7 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef,
CertDbHandle, CertDbRef)
end
catch
- error:{badmatch,{asn1, Asn1Reason}} ->
+ error:{badmatch,{error, {asn1, Asn1Reason}}} ->
%% ASN-1 decode of certificate somehow failed
?ALERT_REC(?FATAL, ?CERTIFICATE_UNKNOWN, {failed_to_decode_certificate, Asn1Reason});
error:OtherReason ->
@@ -1194,10 +1194,7 @@ signature_algs_ext(undefined) ->
signature_algs_ext(SignatureSchemes0) ->
%% The SSL option signature_algs contains both hash-sign algorithms (tuples) and
%% signature schemes (atoms) if TLS 1.3 is configured.
- %% Filter out all hash-sign tuples when creating the signature_algs extension.
- %% (TLS 1.3 specific record type)
- SignatureSchemes = lists:filter(fun is_atom/1, SignatureSchemes0),
- #signature_algorithms{signature_scheme_list = SignatureSchemes}.
+ #signature_algorithms{signature_scheme_list = SignatureSchemes0}.
signature_algs_cert(undefined) ->
undefined;
@@ -1482,7 +1479,16 @@ extension_value(#next_protocol_negotiation{extension_data = Data}) ->
extension_value(#srp{username = Name}) ->
Name;
extension_value(#renegotiation_info{renegotiated_connection = Data}) ->
- Data.
+ Data;
+extension_value(#signature_algorithms{signature_scheme_list = Schemes}) ->
+ Schemes;
+extension_value(#signature_algorithms_cert{signature_scheme_list = Schemes}) ->
+ Schemes;
+extension_value(#key_share_client_hello{client_shares = ClientShares}) ->
+ ClientShares;
+extension_value(#client_hello_versions{versions = Versions}) ->
+ Versions.
+
%%--------------------------------------------------------------------
%%% Internal functions
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 2651fc09bd..323d9e3284 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -259,7 +259,7 @@ next_event(StateName, Record, State) ->
next_event(StateName, no_record, State0, Actions) ->
case next_record(StateName, State0) of
{no_record, State} ->
- {next_state, StateName, State, Actions};
+ ssl_connection:hibernate_after(StateName, State, Actions);
{Record, State} ->
next_event(StateName, Record, State, Actions)
end;
@@ -317,8 +317,7 @@ handle_protocol_record(#ssl_tls{type = ?HANDSHAKE, fragment = Data},
_ ->
HsEnv = State#state.handshake_env,
{next_state, StateName,
- State#state{protocol_buffers = Buffers,
- handshake_env =
+ State#state{handshake_env =
HsEnv#handshake_env{unprocessed_handshake_events
= unprocessed_events(Events)}}, Events}
end
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 27cd5765e5..f7c8c770ae 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -606,8 +606,26 @@ signature_schemes(Version, SignatureSchemes) when is_tuple(Version)
Acc
end;
%% Special clause for filtering out the legacy hash-sign tuples.
- (_ , Acc) ->
- Acc
+ ({Hash, dsa = Sign} = Alg, Acc) ->
+ case proplists:get_bool(dss, PubKeys)
+ andalso proplists:get_bool(Hash, Hashes)
+ andalso is_pair(Hash, Sign, Hashes)
+ of
+ true ->
+ [Alg | Acc];
+ false ->
+ Acc
+ end;
+ ({Hash, Sign} = Alg, Acc) ->
+ case proplists:get_bool(Sign, PubKeys)
+ andalso proplists:get_bool(Hash, Hashes)
+ andalso is_pair(Hash, Sign, Hashes)
+ of
+ true ->
+ [Alg | Acc];
+ false ->
+ Acc
+ end
end,
Supported = lists:foldl(Fun, [], SignatureSchemes),
lists:reverse(Supported);
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index ce4479020e..0cdfea0ac2 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -244,11 +244,13 @@ rizzo_tests() ->
%% For testing TLS 1.3 features and possible regressions
tls13_test_group() ->
- [tls13_enable_client_side,
+ [handshake_continue_tls13_client,
+ tls13_enable_client_side,
tls13_enable_server_side,
tls_record_1_3_encode_decode,
tls13_finished_verify_data,
tls13_1_RTT_handshake,
+ tls12_ssl_server_tls13_ssl_client,
tls13_basic_ssl_server_openssl_client,
tls13_basic_ssl_server_ssl_client,
tls13_basic_openssl_server_ssl_client,
@@ -687,6 +689,43 @@ handshake_continue(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+handshake_continue_tls13_client() ->
+ [{doc, "Test API function ssl:handshake_continue/3"}].
+handshake_continue_tls13_client(Config) when is_list(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+
+ ClientOptsHello0 = ssl_test_lib:ssl_options([{handshake, hello}], Config),
+ ClientOptsHello = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOptsHello0],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ssl_test_lib:ssl_options([{reuseaddr, true}, {handshake, hello}],
+ Config)},
+ {continue_options, proplists:delete(reuseaddr, ServerOpts)}
+ ]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOptsHello},
+ {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
%%------------------------------------------------------------------
handshake_continue_timeout() ->
[{doc, "Test API function ssl:handshake_continue/3 with short timeout"}].
@@ -3637,7 +3676,7 @@ hibernate(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
- timer:sleep(1500),
+ ct:sleep(1500),
{current_function, {erlang, hibernate, 3}} =
process_info(Pid, current_function),
@@ -3673,6 +3712,8 @@ hibernate_right_away(Config) ->
[{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]),
ssl_test_lib:check_result(Server1, ok, Client1, ok),
+
+ ct:sleep(1000), %% Schedule out
{current_function, {erlang, hibernate, 3}} =
process_info(Pid1, current_function),
@@ -5367,6 +5408,41 @@ tls13_finished_verify_data(_Config) ->
FinishedKey = tls_v1:finished_key(BaseKey, sha256),
VerifyData = tls_v1:finished_verify_data(FinishedKey, sha256, Messages).
+
+tls12_ssl_server_tls13_ssl_client() ->
+ [{doc,"Test basic connection between TLS 1.2 server and TLS 1.3 client"}].
+
+tls12_ssl_server_tls13_ssl_client(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ %% Set versions
+ ServerOpts = [{versions, ['tlsv1.2']}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {signature_algs_cert, [ecdsa_secp384r1_sha384,
+ rsa_pss_rsae_sha256,
+ rsa_pkcs1_sha256,
+ {sha256,rsa},{sha256,dsa}]}|ClientOpts0],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(Client).
+
+
tls13_basic_ssl_server_openssl_client() ->
[{doc,"Test TLS 1.3 basic connection between ssl server and openssl s_client"}].
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index c6982bb928..4de4a35e59 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -91,7 +91,8 @@ tests() ->
critical_extension_verify_server,
critical_extension_verify_none,
customize_hostname_check,
- incomplete_chain
+ incomplete_chain,
+ long_chain
].
error_handling_tests()->
@@ -1166,6 +1167,44 @@ incomplete_chain(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+long_chain() ->
+ [{doc,"Test option verify_peer"}].
+long_chain(Config) when is_list(Config) ->
+ #{server_config := ServerConf,
+ client_config := ClientConf} = public_key:pkix_test_data(#{server_chain => #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}],
+ [{key, ssl_test_lib:hardcode_rsa_key(3)}],
+ [{key, ssl_test_lib:hardcode_rsa_key(4)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(5)}]},
+ client_chain => #{root => [{key, ssl_test_lib:hardcode_rsa_key(3)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(1)}]}}),
+ [ServerRoot| _] = ServerCas = proplists:get_value(cacerts, ServerConf),
+ ClientCas = proplists:get_value(cacerts, ClientConf),
+
+ Active = proplists:get_value(active, Config),
+ ReceiveFunction = proplists:get_value(receive_function, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{active, Active}, {verify, verify_peer},
+ {cacerts, [ServerRoot]} |
+ proplists:delete(cacerts, ServerConf)]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{active, Active},
+ {verify, verify_peer},
+ {depth, 5},
+ {cacerts, ServerCas ++ ClientCas} |
+ proplists:delete(cacerts, ClientConf)]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 15f6a04862..32fd917937 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1105,7 +1105,7 @@ run_client_error(Opts) ->
ct:log("~p:~p~nssl:connect(~p, ~p, ~p)~n", [?MODULE,?LINE, Host, Port, Options]),
Error = Transport:connect(Host, Port, Options),
case Error of
- {error, {tls_alert, _}} ->
+ {error, _} ->
Pid ! {self(), Error};
{ok, _Socket} ->
receive
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index cbc32cd5a8..01dee392f5 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 9.3.1
+SSL_VSN = 9.3.3