diff --git a/lib/ssl/src/tls_record_1_3.erl b/lib/ssl/src/tls_record_1_3.erl index 1ce9449f57e..951b0fe7525 100644 --- a/lib/ssl/src/tls_record_1_3.erl +++ b/lib/ssl/src/tls_record_1_3.erl @@ -104,24 +104,21 @@ encode_plain_text(Type, Data, ConnectionStates) -> %% tls_cipher_text in decoding context so that we can reuse the code %% from earlier versions. %% -------------------------------------------------------------------- -decode_cipher_text(#ssl_tls{type = ?OPAQUE_TYPE,version = ?LEGACY_VERSION,fragment = CipherFragment}, - #{current_read := - #{aead_handle := Handle, - sequence_number := Seq, - cipher_state := #cipher_state{iv = IV} - } = ReadState0 - } = ConnectionStates0) -> - case decipher_aead(Handle, CipherFragment, Seq, IV) of - #alert{} = Alert -> - Alert; - PlainFragment -> - ConnectionStates = - ConnectionStates0#{current_read => - ReadState0#{sequence_number => Seq + 1, - aead_handle => Handle - }}, - {decode_inner_plaintext(PlainFragment), ConnectionStates} - end; +%% decode_cipher_text(#ssl_tls{type = ?OPAQUE_TYPE,version = ?LEGACY_VERSION,fragment = CipherFragment}, +%% #{current_read := +%% #{aead_handle := Handle, +%% sequence_number := Seq, +%% cipher_state := #cipher_state{iv = IV} +%% } = ReadState0 +%% } = ConnectionStates0) -> +%% case decipher_aead(Handle, CipherFragment, Seq, IV) of +%% #alert{} = Alert -> +%% Alert; +%% PlainFragment -> +%% ConnectionStates = +%% ConnectionStates0#{current_read => ReadState0#{sequence_number => Seq + 1}}, +%% {decode_inner_plaintext(PlainFragment), ConnectionStates} +%% end; decode_cipher_text(#ssl_tls{type = ?OPAQUE_TYPE,version = ?LEGACY_VERSION,fragment = CipherFragment}, #{current_read := #{sequence_number := Seq, @@ -139,10 +136,26 @@ decode_cipher_text(#ssl_tls{type = ?OPAQUE_TYPE,version = ?LEGACY_VERSION,fragme early_data_accepted := EarlyDataAccepted } } = ReadState0} = ConnectionStates0) -> + + Old = decipher_aead(CipherFragment, BulkCipherAlgo, Key, Seq, IV, TagLen), + + Cipher = ssl_cipher:aead_type(BulkCipherAlgo,byte_size(Key)), Handle = crypto:crypto_one_time_aead_init(Cipher, Key, TagLen, false), - case decipher_aead(Handle, CipherFragment, Seq, IV) of + Decoded = decipher_aead(Handle, CipherFragment, Seq, IV), + + ct:log("Decode: ~p ~0.p ~0.p ~0.p ~0.p ~0.p", [byte_size(CipherFragment), Cipher, Seq, TagLen, Key, IV]), + + case Old == Decoded of + true -> ok; + false -> + ct:log("FAIL: ~0.p~n=> ~0.p~n", [Old, Decoded]), + ct:log(" ~0.p ~0.p Seq=~0.p TagLen=~0.p Msg=~p", + [BulkCipherAlgo, Cipher, Seq, TagLen, byte_size(CipherFragment)]) + end, + + case Decoded of #alert{} when TrialDecryption =:= true andalso EarlyDataAccepted =:= false andalso PendingMaxEarlyDataSize0 > 0 -> %% Trial decryption @@ -351,6 +364,28 @@ encode_tls_cipher_text(Type, {MajVer,MinVer}, Encoded) -> Length = erlang:iolist_size(Encoded), [<>, Encoded]. +decipher_aead(CipherFragment0, BulkCipherAlgo, Key, Seq, IV, TagLen) -> + try + CipherFragment = iolist_to_binary(CipherFragment0), + FragLen = byte_size(CipherFragment), + AAD = additional_data(FragLen), + Nonce = nonce(Seq, IV), + CipherLen = FragLen - TagLen, + <> = CipherFragment, + case ssl_cipher:aead_decrypt(BulkCipherAlgo, Key, Nonce, CipherText, CipherTag, AAD) of + Content when is_binary(Content) -> + Content; + Reason -> + ?SSL_LOG(info, decrypt_error, [{reason,Reason}, + {stacktrace, process_info(self(), current_stacktrace)}]), + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, decryption_failed) + end + catch + _:Reason2:ST -> + ?SSL_LOG(info, decrypt_error, [{reason,Reason2}, {stacktrace, ST}]), + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, decryption_failed) + end. + decipher_aead(Handle, CipherFragment, Seq, IV) -> try FragLen = iolist_size(CipherFragment), %% Includes TagLen @@ -360,13 +395,13 @@ decipher_aead(Handle, CipherFragment, Seq, IV) -> Content when is_binary(Content) -> Content; Reason -> - ?SSL_LOG(debug, decrypt_error, [{reason,Reason}, - {stacktrace, process_info(self(), current_stacktrace)}]), + ?SSL_LOG(info, decrypt_error, [{reason,Reason}, + {stacktrace, process_info(self(), current_stacktrace)}]), ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, decryption_failed) end catch _:Reason2:ST -> - ?SSL_LOG(debug, decrypt_error, [{reason,Reason2}, {stacktrace, ST}]), + ?SSL_LOG(info, decrypt_error, [{reason,Reason2}, {stacktrace, ST}]), ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, decryption_failed) end. diff --git a/lib/ssl/src/tls_socket_tcp.erl b/lib/ssl/src/tls_socket_tcp.erl index fb5aeef9178..4b17db8e8e6 100644 --- a/lib/ssl/src/tls_socket_tcp.erl +++ b/lib/ssl/src/tls_socket_tcp.erl @@ -71,6 +71,8 @@ getopts(Socket, Keys) -> Get = fun(Key, Acc) -> case maps:get(Key, socket_opts(), not_existing_opt) of not_existing_opt -> + throw({error, {not_supported, Key}}); + inet_option_only -> Acc; SocketKey -> {ok, Val} = socket:getopt(Socket, SocketKey), @@ -337,6 +339,12 @@ check_opts_1(Opt, Opts) -> socket_opts() -> #{ + mode => inet_option_only, + active => inet_option_only, + header => inet_option_only, + packet => inet_option_only, + packet_size => inet_option_only, + %% Level: otp buffer => {otp, rcvbuf}, debug => {otp, debug}, diff --git a/lib/ssl/test/openssl_client_cert_SUITE.erl b/lib/ssl/test/openssl_client_cert_SUITE.erl index 9a692067aa2..13b3c68cb5f 100644 --- a/lib/ssl/test/openssl_client_cert_SUITE.erl +++ b/lib/ssl/test/openssl_client_cert_SUITE.erl @@ -79,7 +79,9 @@ all() -> groups() -> [ {openssl_client, [], protocol_groups()}, + %%{'tlsv1.3', [], transport_group()}, {'tlsv1.3', [], tls_1_3_protocol_groups()}, + {transport_socket, [], tls_1_3_protocol_groups()}, {'tlsv1.2', [], pre_tls_1_3_protocol_groups() ++ [{group, ecdsa}, {group, rsa_pss_rsae}, {group, rsa_pss_pss}]}, {'tlsv1.1', [], pre_tls_1_3_protocol_groups()}, {'tlsv1', [], pre_tls_1_3_protocol_groups()}, @@ -88,8 +90,9 @@ groups() -> {rsa, [], all_version_tests()}, {ecdsa, [], all_version_tests()}, {dsa, [], all_version_tests()}, - {rsa_1_3, [], all_version_tests() ++ tls_1_3_tests() ++ [unsupported_sign_algo_client_auth, - unsupported_sign_algo_cert_client_auth]}, + {rsa_1_3, [], []}, + %% all_version_tests() ++ tls_1_3_tests() ++ [unsupported_sign_algo_client_auth, + %% unsupported_sign_algo_cert_client_auth]}, {rsa_pss_rsae, [], all_version_tests()}, {rsa_pss_pss, [], all_version_tests()}, {rsa_pss_rsae_1_3, [], all_version_tests() ++ tls_1_3_tests()}, @@ -119,6 +122,9 @@ pre_tls_1_3_protocol_groups() -> [{group, rsa}, {group, dsa}]. +transport_group() -> + [{group, transport_socket}]. + tls_1_3_protocol_groups() -> [{group, rsa_1_3}, {group, rsa_pss_rsae_1_3}, diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl index 39a4c9fe6c8..9e1b4a201e0 100644 --- a/lib/ssl/test/ssl_api_SUITE.erl +++ b/lib/ssl/test/ssl_api_SUITE.erl @@ -262,15 +262,16 @@ groups() -> new_options_in_handshake, handshake_continue_tls13_client]) ++ (since_1_2() -- [conf_signature_algs])}, - {'tlsv1.2', [], gen_api_tests() ++ since_1_2() ++ handshake_paus_tests() ++ pre_1_3() ++ [honor_client_cipher_order_tls12, - honor_server_cipher_order_tls12]}, + {'tlsv1.2', [], gen_api_tests() ++ since_1_2() ++ handshake_paus_tests() ++ pre_1_3() ++ + [honor_client_cipher_order_tls12,honor_server_cipher_order_tls12]}, {'tlsv1.1', [], gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3() ++ pre_1_2()}, - {'tlsv1', [], gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3() ++ pre_1_2() ++ beast_mitigation_test()}, + {'tlsv1', [], gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3() ++ pre_1_2() ++ + beast_mitigation_test()}, {'dtlsv1.2', [], gen_api_tests() -- [new_options_in_handshake, hibernate_server] ++ handshake_paus_tests() -- [handshake_continue_tls13_client] ++ pre_1_3()}, {'dtlsv1', [], gen_api_tests() -- [new_options_in_handshake, hibernate_server] ++ handshake_paus_tests() -- [handshake_continue_tls13_client] ++ pre_1_3() ++ pre_1_2()}, - {transport_socket, gen_api_tests() -- [ssl_not_started]} + {transport_socket, gen_api_tests() -- [ssl_not_started, dh_params]} ]. since_1_2() -> @@ -2236,19 +2237,23 @@ new_options_in_handshake(Config) when is_list(Config) -> ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config), Version = ssl_test_lib:protocol_version(Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Filter = fun(any) when Version =:= 'tlsv1.3' -> + true; + (_) when Version =:= 'tlsv1.3' -> + false; + (dhe_rsa) -> + true; + (ecdhe_rsa) -> + true; + (rsa) -> + false; + (_) -> + false + end, Ciphers = [_, Cipher | _] = ssl:filter_cipher_suites(ssl:cipher_suites(all, Version), - [{key_exchange, - fun(dhe_rsa) -> - true; - (ecdhe_rsa) -> - true; - (rsa) -> - false; - (_) -> - false - end - }]), + [{key_exchange, Filter}]), Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, {from, self()}, diff --git a/lib/ssl/test/ssl_bench_SUITE.erl b/lib/ssl/test/ssl_bench_SUITE.erl index 0573aad58c6..77f94638ac9 100644 --- a/lib/ssl/test/ssl_bench_SUITE.erl +++ b/lib/ssl/test/ssl_bench_SUITE.erl @@ -22,6 +22,7 @@ -behaviour(ct_suite). -include_lib("common_test/include/ct_event.hrl"). +-include_lib("ssl/src/ssl_api.hrl"). %% Callback functions -export([suite/0, @@ -69,7 +70,7 @@ --define(COUNT, 400). +-define(COUNT, 100). -define(REDUCE, 40). % (?COUNT rem ?REDUCE) should be 0 %% (?COUNT div ?REDUCE) is the count used for a non-benchmark run @@ -160,7 +161,8 @@ count(Config) -> -define(FPROF_CLIENT, false). -define(FPROF_SERVER, false). --define(EPROF_CLIENT, true). + +-define(EPROF_CLIENT, false). -define(EPROF_SERVER, false). -define(TPROF_CLIENT, false). @@ -278,7 +280,7 @@ erlperf() -> done => "ssl_bench_SUITE:erlperf_close()." } ], - Run = #{sample_duration=> 1000, samples => 25, report => full, warmup => 20}, + Run = #{sample_duration=> 2500, samples => 10, report => full, warmup => 5}, Res = erlperf:benchmark(Rs, Run, undefined), io:put_chars(erlperf_cli:format(Res, #{format => extended})). @@ -332,14 +334,15 @@ do_test(Type, {Func, _}=TC, Loop, ParallellConnections, Server) -> Me = self(), Test = fun(Id) -> CData = client_init(Me, Type, TC, Host, Port, Certs), + Pids = measure_pids(CData), receive go -> ?FPROF_CLIENT andalso Id =:= 1 andalso - start_profile(fprof, [self(),new]), + start_profile(fprof, [self(),new|Pids]), ?EPROF_CLIENT andalso Id =:= 1 andalso - start_profile(eprof, []), + start_profile(eprof, Pids), ?TPROF_CLIENT andalso Id =:= 1 andalso - start_profile(tprof, []), + start_profile(tprof, Pids), ok = ?MODULE:Func(Loop, Type, CData), ?FPROF_CLIENT andalso Id =:= 1 andalso stop_profile(fprof, "test_connection_client_res.fprof"), @@ -359,8 +362,15 @@ do_test(Type, {Func, _}=TC, Loop, ParallellConnections, Server) -> [Pid ! go || Pid <- Pids], [receive Pid -> ok end || Pid <- Pids] end, - io:format("~nStarting in 2 seconds~n perf record --call-graph=lbr --pid ~s~n~n", [os:getpid()]), - timer:sleep(3000), + case os:getenv("PERF") of + "true" -> + io:format("~nStarting perf record~n"), + Cmd = io_lib:format("perf record --call-graph=lbr --freq=max --pid ~s &~n", [os:getpid()]), + os:cmd(Cmd), + timer:sleep(500); + _ -> + ignore + end, io:format("Starting~n"), {TimeInMicro, _} = timer:tc(Run), TotalTests = ParallellConnections * Loop, @@ -517,15 +527,21 @@ tc(Fun, Mod, Line) -> end. -endif. +measure_pids({#sslsocket{connection_handler = Pid1, payload_sender = Pid2}, _}) -> + [Pid || Pid <- [Pid1, Pid2], is_pid(Pid1)]; +measure_pids(_) -> + []. + start_profile(eprof, _Procs) -> tprof:start(#{type => call_time}), tprof:enable_trace({all_children, ssl_sup}), + %% tprof:enable_trace(Procs), io:format("(T)Profiling ...",[]), tprof:set_pattern('_', '_' , '_'); start_profile(fprof, Procs) -> fprof:trace([start, {procs, Procs}]), io:format("(F)Profiling ...",[]); -start_profile(tprof, _) -> +start_profile(tprof, _Procs) -> tprof:start(#{type => call_memory}), tprof:enable_trace({all_children, ssl_sup}), io:format("(T)Profiling ...",[]), @@ -570,8 +586,10 @@ ssl_opts(Role, TCOpts, Certs) -> {reuseaddr, true}, {mode,binary}, {nodelay, true}, - %% {cb_info, tls_socket_tcp:cb_info()}, + {cb_info, tls_socket_tcp:cb_info()}, {versions, [Version]}, + {receiver_spawn_opts, [{min_heap_size, 10000}]}, + {sender_spawn_opts, [{min_heap_size, 10000}]}, {ciphers, [ #{key_exchange => KeyEx, cipher => aes_128_gcm, mac => aead, prf => sha256} ]} diff --git a/lib/ssl/test/ssl_key_update_SUITE.erl b/lib/ssl/test/ssl_key_update_SUITE.erl index 0da60169f87..c8a396ce047 100644 --- a/lib/ssl/test/ssl_key_update_SUITE.erl +++ b/lib/ssl/test/ssl_key_update_SUITE.erl @@ -47,7 +47,8 @@ all() -> [{group, 'tlsv1.3'}]. groups() -> - [{'tlsv1.3', [], tls_1_3_tests()}]. + [{'tlsv1.3', [], [{group, transport_socket} | tls_1_3_tests()]}, + {transport_socket, [], tls_1_3_tests()}]. tls_1_3_tests() -> [key_update_at_client, diff --git a/lib/ssl/test/ssl_mfl_SUITE.erl b/lib/ssl/test/ssl_mfl_SUITE.erl index fd957833d8c..3ac500ddc99 100644 --- a/lib/ssl/test/ssl_mfl_SUITE.erl +++ b/lib/ssl/test/ssl_mfl_SUITE.erl @@ -64,7 +64,8 @@ groups() -> {'tlsv1.1', [], common_tests() ++ pre_tls_1_3()}, {'tlsv1', [], common_tests() ++ pre_tls_1_3()}, {'dtlsv1.2', [], common_tests() ++ pre_tls_1_3()}, - {'dtlsv1', [], common_tests() ++ pre_tls_1_3()} + {'dtlsv1', [], common_tests() ++ pre_tls_1_3()}, + {transport_socket, [], common_tests()} ]. common_tests() -> diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl index 152b325df0b..59ffa8c5aa8 100644 --- a/lib/ssl/test/ssl_payload_SUITE.erl +++ b/lib/ssl/test/ssl_payload_SUITE.erl @@ -113,7 +113,8 @@ all() -> {group, 'tlsv1.3'}, {group, 'tlsv1.2'}, {group, 'tlsv1.1'}, - {group, 'tlsv1'} + {group, 'tlsv1'}, + {group, transport_socket} ]. groups() -> @@ -121,7 +122,8 @@ groups() -> {'tlsv1.3', [], payload_tests()}, {'tlsv1.2', [], payload_tests()}, {'tlsv1.1', [], payload_tests()}, - {'tlsv1', [], payload_tests()} + {'tlsv1', [], payload_tests()}, + {transport_socket, [], payload_tests()} ]. payload_tests() -> @@ -169,7 +171,7 @@ init_per_group(GroupName, Config) -> ssl_test_lib:init_per_group(GroupName, Config). end_per_group(GroupName, Config) -> - ssl_test_lib:end_per_group(GroupName, Config). + ssl_test_lib:end_per_group(GroupName, Config). init_per_testcase(TestCase, Config) diff --git a/lib/ssl/test/ssl_renegotiate_SUITE.erl b/lib/ssl/test/ssl_renegotiate_SUITE.erl index 3c19750ed0f..e82a7f1ae0e 100644 --- a/lib/ssl/test/ssl_renegotiate_SUITE.erl +++ b/lib/ssl/test/ssl_renegotiate_SUITE.erl @@ -92,7 +92,8 @@ all() -> groups() -> [{'dtlsv1.2', [], renegotiate_tests()}, {'dtlsv1', [], renegotiate_tests()}, - {'tlsv1.2', [], renegotiate_tests()}, + {'tlsv1.2', [], [{group, transport_socket}]}, + {transport_socket, [], renegotiate_tests()}, {'tlsv1.1', [], renegotiate_tests()}, {'tlsv1', [], renegotiate_tests()} ]. diff --git a/lib/ssl/test/ssl_socket_SUITE.erl b/lib/ssl/test/ssl_socket_SUITE.erl index 585237f53f0..ebaeb560f8a 100644 --- a/lib/ssl/test/ssl_socket_SUITE.erl +++ b/lib/ssl/test/ssl_socket_SUITE.erl @@ -75,13 +75,15 @@ all() -> [ {group, tls}, - {group, dtls} + {group, dtls}, + {group, transport_socket} ]. groups() -> [ {tls,[], socket_tests() ++ raw_inet_opt()}, - {dtls,[], socket_tests()} + {dtls,[], socket_tests()}, + {transport_socket, [], socket_tests() ++ raw_inet_opt()} ]. socket_tests() -> @@ -117,13 +119,12 @@ end_per_suite(_Config) -> application:unload(ssl), application:stop(crypto). -init_per_group(dtls, Config) -> +init_per_group(dtls, Config) -> [{group_opts, [{protocol, dtls}]} | proplists:delete(group_opts, Config)]; -init_per_group(tls, Config) -> +init_per_group(tls, Config) -> [{group_opts, [{protocol, tls}]} | proplists:delete(group_opts, Config)]; -init_per_group(_GroupName, Config) -> - [{client_type, erlang}, - {server_type, erlang} | Config]. +init_per_group(transport_socket, Config) -> + [{group_opts, [{protocol, tls}, {cb_info, tls_socket_tcp:cb_info()}]}| Config]. end_per_group(_GroupName, Config) -> Config. @@ -442,7 +443,7 @@ get_invalid_inet_option(Socket) -> get_invalid_inet_option_not_list(Socket) -> {error, {options, {socket_options, some_invalid_atom_here}}} - = ssl:getopts(Socket, some_invalid_atom_here), + = ssl:getopts(Socket, some_invalid_atom_here), ok. get_invalid_inet_option_improper_list(Socket) -> diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index 95a8db6193a..c97b7398179 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -2926,7 +2926,8 @@ openssl_tls_version_support(Proto, Opts, Port, Exe, Args0) -> OpensslPort = portable_open_port(Exe, Args), try wait_for_openssl_server(Port, Proto) of ok -> - case ssl:connect("localhost", Port, Opts, 5000) of + logger:set_application_level(ssl, debug), + case ssl:connect("localhost", Port, [{log_level,debug}|Opts], 5000) of {ok, Socket} -> ssl:close(Socket), close_port(OpensslPort),