aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/test/ssl_basic_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/test/ssl_basic_SUITE.erl')
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl863
1 files changed, 644 insertions, 219 deletions
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index a9109c5a6e..93f7209aea 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,15 +27,18 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include("ssl_internal.hrl").
-include("ssl_alert.hrl").
-include("ssl_internal.hrl").
-include("ssl_record.hrl").
+-include("ssl_handshake.hrl").
-define('24H_in_sec', 86400).
-define(TIMEOUT, 60000).
-define(LONG_TIMEOUT, 600000).
-define(EXPIRE, 10).
-define(SLEEP, 500).
+-define(RENEGOTIATION_DISABLE_TIME, 12000).
%% Test server callback functions
%%--------------------------------------------------------------------
@@ -49,10 +52,10 @@
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2),
+ catch crypto:stop(),
try crypto:start() of
ok ->
application:start(public_key),
- ssl:start(),
%% make rsa certs using oppenssl
Result =
@@ -89,46 +92,28 @@ end_per_suite(_Config) ->
%% variable, but should NOT alter/remove any existing entries.
%% Description: Initialization before each test case
%%--------------------------------------------------------------------
-init_per_testcase(session_cache_process_list, Config) ->
- init_customized_session_cache(list, Config);
-
-init_per_testcase(session_cache_process_mnesia, Config) ->
- mnesia:start(),
- init_customized_session_cache(mnesia, Config);
-
-init_per_testcase(reuse_session_expired, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5),
- ssl:stop(),
- application:load(ssl),
- application:set_env(ssl, session_lifetime, ?EXPIRE),
- ssl:start(),
- [{watchdog, Dog} | Config];
-
init_per_testcase(no_authority_key_identifier, Config) ->
%% Clear cach so that root cert will not
%% be found.
- ssl:stop(),
- ssl:start(),
+ ssl:clear_pem_cache(),
Config;
-init_per_testcase(TestCase, Config) when TestCase == ciphers_rsa_signed_certs_ssl3;
- TestCase == ciphers_rsa_signed_certs_openssl_names_ssl3;
- TestCase == ciphers_dsa_signed_certs_ssl3;
- TestCase == ciphers_dsa_signed_certs_openssl_names_ssl3 ->
+init_per_testcase(protocol_versions, Config) ->
ssl:stop(),
application:load(ssl),
- application:set_env(ssl, protocol_version, sslv3),
+ %% For backwards compatibility sslv2 should be filtered out.
+ application:set_env(ssl, protocol_version, [sslv2, sslv3, tlsv1]),
ssl:start(),
Config;
-init_per_testcase(protocol_versions, Config) ->
+init_per_testcase(reuse_session_expired, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5),
ssl:stop(),
application:load(ssl),
- %% For backwards compatibility sslv2 should be filtered out.
- application:set_env(ssl, protocol_version, [sslv2, sslv3, tlsv1]),
+ application:set_env(ssl, session_lifetime, ?EXPIRE),
ssl:start(),
- Config;
+ [{watchdog, Dog} | Config];
init_per_testcase(empty_protocol_versions, Config) ->
ssl:stop(),
@@ -137,24 +122,15 @@ init_per_testcase(empty_protocol_versions, Config) ->
ssl:start(),
Config;
-init_per_testcase(different_ca_peer_sign, Config0) ->
- ssl_test_lib:make_mix_cert(Config0);
+%% init_per_testcase(different_ca_peer_sign, Config0) ->
+%% ssl_test_lib:make_mix_cert(Config0);
init_per_testcase(_TestCase, Config0) ->
+ test_server:format("TLS/SSL version ~p~n ", [ssl_record:supported_protocol_versions()]),
Config = lists:keydelete(watchdog, 1, Config0),
Dog = test_server:timetrap(?TIMEOUT),
[{watchdog, Dog} | Config].
-init_customized_session_cache(Type, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = test_server:timetrap(?TIMEOUT),
- ssl:stop(),
- application:load(ssl),
- application:set_env(ssl, session_cb, ?MODULE),
- application:set_env(ssl, session_cb_init_args, [Type]),
- ssl:start(),
- [{watchdog, Dog} | Config].
-
%%--------------------------------------------------------------------
%% Function: end_per_testcase(TestCase, Config) -> _
%% Case - atom()
@@ -163,27 +139,10 @@ init_customized_session_cache(Type, Config0) ->
%% A list of key/value pairs, holding the test case configuration.
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
-end_per_testcase(session_cache_process_list, Config) ->
- application:unset_env(ssl, session_cb),
- end_per_testcase(default_action, Config);
-end_per_testcase(session_cache_process_mnesia, Config) ->
- application:unset_env(ssl, session_cb),
- application:unset_env(ssl, session_cb_init_args),
- mnesia:stop(),
- ssl:stop(),
- ssl:start(),
- end_per_testcase(default_action, Config);
end_per_testcase(reuse_session_expired, Config) ->
application:unset_env(ssl, session_lifetime),
end_per_testcase(default_action, Config);
-end_per_testcase(TestCase, Config) when TestCase == ciphers_rsa_signed_certs_ssl3;
- TestCase == ciphers_rsa_signed_certs_openssl_names_ssl3;
- TestCase == ciphers_dsa_signed_certs_ssl3;
- TestCase == ciphers_dsa_signed_certs_openssl_names_ssl3;
- TestCase == protocol_versions;
- TestCase == empty_protocol_versions->
- application:unset_env(ssl, protocol_version),
- end_per_testcase(default_action, Config);
+
end_per_testcase(_TestCase, Config) ->
Dog = ?config(watchdog, Config),
case Dog of
@@ -204,69 +163,170 @@ end_per_testcase(_TestCase, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app, alerts, connection_info, protocol_versions,
- empty_protocol_versions, controlling_process,
- controller_dies, client_closes_socket,
- connect_dist, peername, peercert, sockname, socket_options,
- invalid_inet_get_option, invalid_inet_get_option_not_list,
+ [
+ {group, basic},
+ {group, options},
+ {group, session},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'}
+ ].
+
+groups() ->
+ [{basic, [], basic_tests()},
+ {options, [], options_tests()},
+ {'tlsv1.2', [], all_versions_groups()},
+ {'tlsv1.1', [], all_versions_groups()},
+ {'tlsv1', [], all_versions_groups() ++ rizzo_tests()},
+ {'sslv3', [], all_versions_groups() ++ rizzo_tests()},
+ {api,[], api_tests()},
+ {certificate_verify, [], certificate_verify_tests()},
+ {session, [], session_tests()},
+ {renegotiate, [], renegotiate_tests()},
+ {ciphers, [], cipher_tests()},
+ {error_handling_tests, [], error_handling_tests()}
+ ].
+
+all_versions_groups ()->
+ [{group, api},
+ {group, certificate_verify},
+ {group, renegotiate},
+ {group, ciphers},
+ {group, error_handling_tests}].
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+basic_tests() ->
+ [app,
+ alerts,
+ send_close,
+ connect_twice,
+ connect_dist
+ ].
+
+options_tests() ->
+ [der_input,
+ misc_ssl_options,
+ socket_options,
+ invalid_inet_get_option,
+ invalid_inet_get_option_not_list,
invalid_inet_get_option_improper_list,
- invalid_inet_set_option, invalid_inet_set_option_not_list,
+ invalid_inet_set_option,
+ invalid_inet_set_option_not_list,
invalid_inet_set_option_improper_list,
- misc_ssl_options, versions, cipher_suites, upgrade,
- upgrade_with_timeout, tcp_connect, tcp_connect_big, ipv6, ekeyfile,
- ecertfile, ecacertfile, eoptions, shutdown,
- shutdown_write, shutdown_both, shutdown_error,
- ciphers_rsa_signed_certs, ciphers_rsa_signed_certs_ssl3,
- ciphers_rsa_signed_certs_openssl_names,
- ciphers_rsa_signed_certs_openssl_names_ssl3,
- ciphers_dsa_signed_certs, ciphers_dsa_signed_certs_ssl3,
- ciphers_dsa_signed_certs_openssl_names,
- ciphers_dsa_signed_certs_openssl_names_ssl3,
- anonymous_cipher_suites,
- default_reject_anonymous,
- send_close,
- close_transport_accept, dh_params,
- server_verify_peer_passive, server_verify_peer_active,
+ dh_params,
+ ecertfile,
+ ecacertfile,
+ ekeyfile,
+ eoptions,
+ protocol_versions,
+ empty_protocol_versions,
+ ipv6,
+ reuseaddr].
+
+api_tests() ->
+ [connection_info,
+ peername,
+ peercert,
+ sockname,
+ versions,
+ controlling_process,
+ upgrade,
+ upgrade_with_timeout,
+ shutdown,
+ shutdown_write,
+ shutdown_both,
+ shutdown_error,
+ hibernate
+ ].
+
+certificate_verify_tests() ->
+ [server_verify_peer_passive,
+ server_verify_peer_active,
server_verify_peer_active_once,
- server_verify_none_passive, server_verify_none_active,
+ server_verify_none_passive,
+ server_verify_none_active,
server_verify_none_active_once,
- server_verify_no_cacerts, server_require_peer_cert_ok,
+ server_verify_no_cacerts,
+ server_require_peer_cert_ok,
server_require_peer_cert_fail,
server_verify_client_once_passive,
server_verify_client_once_active,
server_verify_client_once_active_once,
- client_verify_none_passive, client_verify_none_active,
+ client_verify_none_passive,
+ client_verify_none_active,
client_verify_none_active_once,
- reuse_session,
- reuse_session_expired,
- server_does_not_want_to_reuse_session,
- client_renegotiate, server_renegotiate,
- client_renegotiate_reused_session,
- server_renegotiate_reused_session,
- client_no_wrap_sequence_number,
- server_no_wrap_sequence_number, extended_key_usage_verify_peer,
+ extended_key_usage_verify_peer,
extended_key_usage_verify_none,
- no_authority_key_identifier, invalid_signature_client,
- invalid_signature_server, cert_expired,
+ invalid_signature_client,
+ invalid_signature_server,
+ cert_expired,
client_with_cert_cipher_suites_handshake,
- unknown_server_ca_fail, der_input,
+ verify_fun_always_run_client,
+ verify_fun_always_run_server,
+ unknown_server_ca_fail,
unknown_server_ca_accept_verify_none,
unknown_server_ca_accept_verify_peer,
unknown_server_ca_accept_backwardscompatibility,
- %%different_ca_peer_sign,
- no_reuses_session_server_restart_new_cert,
- no_reuses_session_server_restart_new_cert_file, reuseaddr,
- hibernate, connect_twice
+ no_authority_key_identifier
].
-groups() ->
- [].
+session_tests() ->
+ [reuse_session,
+ reuse_session_expired,
+ server_does_not_want_to_reuse_session,
+ no_reuses_session_server_restart_new_cert,
+ no_reuses_session_server_restart_new_cert_file].
-init_per_group(_GroupName, Config) ->
- Config.
+renegotiate_tests() ->
+ [client_renegotiate,
+ server_renegotiate,
+ client_renegotiate_reused_session,
+ server_renegotiate_reused_session,
+ client_no_wrap_sequence_number,
+ server_no_wrap_sequence_number,
+ renegotiate_dos_mitigate_active,
+ renegotiate_dos_mitigate_passive].
-end_per_group(_GroupName, Config) ->
- Config.
+cipher_tests() ->
+ [cipher_suites,
+ ciphers_rsa_signed_certs,
+ ciphers_rsa_signed_certs_openssl_names,
+ ciphers_dsa_signed_certs,
+ ciphers_dsa_signed_certs_openssl_names,
+ anonymous_cipher_suites,
+ default_reject_anonymous].
+
+error_handling_tests()->
+ [controller_dies,
+ client_closes_socket,
+ tcp_error_propagation_in_active_mode,
+ tcp_connect,
+ tcp_connect_big,
+ close_transport_accept
+ ].
+
+rizzo_tests() ->
+ [rizzo,
+ no_rizzo_rc4].
%% Test cases starts here.
%%--------------------------------------------------------------------
@@ -393,8 +453,8 @@ controlling_process(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- ClientMsg = "Hello server",
- ServerMsg = "Hello client",
+ ClientMsg = "Server hello",
+ ServerMsg = "Client hello",
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -415,11 +475,15 @@ controlling_process(Config) when is_list(Config) ->
[self(), Client, Server]),
receive
+ {ssl, _, "S"} ->
+ receive_s_rizzo_duong_beast();
{ssl, _, ServerMsg} ->
receive
{ssl, _, ClientMsg} ->
ok
end;
+ {ssl, _, "C"} ->
+ receive_c_rizzo_duong_beast();
{ssl, _, ClientMsg} ->
receive
{ssl, _, ServerMsg} ->
@@ -440,6 +504,28 @@ controlling_process_result(Socket, Pid, Msg) ->
ssl:send(Socket, Msg),
no_result_msg.
+receive_s_rizzo_duong_beast() ->
+ receive
+ {ssl, _, "erver hello"} ->
+ receive
+ {ssl, _, "C"} ->
+ receive
+ {ssl, _, "lient hello"} ->
+ ok
+ end
+ end
+ end.
+receive_c_rizzo_duong_beast() ->
+ receive
+ {ssl, _, "lient hello"} ->
+ receive
+ {ssl, _, "S"} ->
+ receive
+ {ssl, _, "erver hello"} ->
+ ok
+ end
+ end
+ end.
%%--------------------------------------------------------------------
controller_dies(doc) ->
["Test that the socket is closed after controlling process dies"];
@@ -1231,6 +1317,11 @@ upgrade_result(Socket) ->
%% Make sure binary is inherited from tcp socket and that we do
%% not get the list default!
receive
+ {ssl, _, <<"H">>} ->
+ receive
+ {ssl, _, <<"ello world">>} ->
+ ok
+ end;
{ssl, _, <<"Hello world">>} ->
ok
end.
@@ -1532,14 +1623,14 @@ eoptions(Config) when is_list(Config) ->
{cacertfile, ""},
{dhfile,'dh.pem' },
{ciphers, [{foo, bar, sha, ignore}]},
- {reuse_session, foo},
- {reuse_sessions, 0},
+ {reuse_session, foo},
+ {reuse_sessions, 0},
{renegotiate_at, "10"},
- {debug, 1},
+ {debug, 1},
{mode, depech},
- {packet, 8.0},
- {packet_size, "2"},
- {header, a},
+ {packet, 8.0},
+ {packet_size, "2"},
+ {header, a},
{active, trice},
{key, 'key.pem' }],
@@ -1688,21 +1779,7 @@ ciphers_rsa_signed_certs(Config) when is_list(Config) ->
ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
Ciphers = ssl_test_lib:rsa_suites(),
- test_server:format("tls1 erlang cipher suites ~p~n", [Ciphers]),
- run_suites(Ciphers, Version, Config, rsa).
-
-ciphers_rsa_signed_certs_ssl3(doc) ->
- ["Test all rsa ssl cipher suites in ssl3"];
-
-ciphers_rsa_signed_certs_ssl3(suite) ->
- [];
-
-ciphers_rsa_signed_certs_ssl3(Config) when is_list(Config) ->
- Version =
- ssl_record:protocol_version({3,0}),
-
- Ciphers = ssl_test_lib:rsa_suites(),
- test_server:format("ssl3 erlang cipher suites ~p~n", [Ciphers]),
+ test_server:format("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, rsa).
ciphers_rsa_signed_certs_openssl_names(doc) ->
@@ -1719,18 +1796,6 @@ ciphers_rsa_signed_certs_openssl_names(Config) when is_list(Config) ->
run_suites(Ciphers, Version, Config, rsa).
-ciphers_rsa_signed_certs_openssl_names_ssl3(doc) ->
- ["Test all dsa ssl cipher suites in ssl3"];
-
-ciphers_rsa_signed_certs_openssl_names_ssl3(suite) ->
- [];
-
-ciphers_rsa_signed_certs_openssl_names_ssl3(Config) when is_list(Config) ->
- Version = ssl_record:protocol_version({3,0}),
- Ciphers = ssl_test_lib:openssl_rsa_suites(),
- run_suites(Ciphers, Version, Config, rsa).
-
-
ciphers_dsa_signed_certs(doc) ->
["Test all dsa ssl cipher suites in highest support ssl/tls version"];
@@ -1742,23 +1807,8 @@ ciphers_dsa_signed_certs(Config) when is_list(Config) ->
ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
Ciphers = ssl_test_lib:dsa_suites(),
- test_server:format("tls1 erlang cipher suites ~p~n", [Ciphers]),
- run_suites(Ciphers, Version, Config, dsa).
-
-ciphers_dsa_signed_certs_ssl3(doc) ->
- ["Test all dsa ssl cipher suites in ssl3"];
-
-ciphers_dsa_signed_certs_ssl3(suite) ->
- [];
-
-ciphers_dsa_signed_certs_ssl3(Config) when is_list(Config) ->
- Version =
- ssl_record:protocol_version({3,0}),
-
- Ciphers = ssl_test_lib:dsa_suites(),
- test_server:format("ssl3 erlang cipher suites ~p~n", [Ciphers]),
+ test_server:format("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, dsa).
-
ciphers_dsa_signed_certs_openssl_names(doc) ->
["Test all dsa ssl cipher suites in highest support ssl/tls version"];
@@ -1774,18 +1824,6 @@ ciphers_dsa_signed_certs_openssl_names(Config) when is_list(Config) ->
test_server:format("tls1 openssl cipher suites ~p~n", [Ciphers]),
run_suites(Ciphers, Version, Config, dsa).
-
-ciphers_dsa_signed_certs_openssl_names_ssl3(doc) ->
- ["Test all dsa ssl cipher suites in ssl3"];
-
-ciphers_dsa_signed_certs_openssl_names_ssl3(suite) ->
- [];
-
-ciphers_dsa_signed_certs_openssl_names_ssl3(Config) when is_list(Config) ->
- Version = ssl_record:protocol_version({3,0}),
- Ciphers = ssl_test_lib:openssl_dsa_suites(),
- run_suites(Ciphers, Version, Config, dsa).
-
anonymous_cipher_suites(doc)->
["Test the anonymous ciphersuites"];
anonymous_cipher_suites(suite) ->
@@ -1822,7 +1860,7 @@ run_suites(Ciphers, Version, Config, Type) ->
end.
erlang_cipher_suite(Suite) when is_list(Suite)->
- ssl_cipher:suite_definition(ssl_cipher:openssl_suite(Suite));
+ ssl:suite_definition(ssl_cipher:openssl_suite(Suite));
erlang_cipher_suite(Suite) ->
Suite.
@@ -2049,7 +2087,9 @@ reuse_session_expired(Config) when is_list(Config) ->
Server ! listen,
%% Make sure session is unregistered due to expiration
- test_server:sleep((?EXPIRE+1) * 1000),
+ test_server:sleep((?EXPIRE+1)),
+ [{session_id, Id} |_] = SessionInfo,
+ make_sure_expired(Hostname, Port, Id),
Client2 =
ssl_test_lib:start_client([{node, ClientNode},
@@ -2068,6 +2108,22 @@ reuse_session_expired(Config) when is_list(Config) ->
ssl_test_lib:close(Client1),
ssl_test_lib:close(Client2).
+make_sure_expired(Host, Port, Id) ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ Cache = element(2, State),
+ case ssl_session_cache:lookup(Cache, {{Host, Port}, Id}) of
+ undefined ->
+ ok;
+ #session{is_resumable = false} ->
+ ok;
+ _ ->
+ test_server:sleep(?SLEEP),
+ make_sure_expired(Host, Port, Id)
+ end.
+
+
%%--------------------------------------------------------------------
server_does_not_want_to_reuse_session(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -2313,8 +2369,8 @@ server_verify_client_once_passive(Config) when is_list(Config) ->
{options, [{active, false} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client0, ok),
- ssl_test_lib:close(Client0),
Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+ ssl_test_lib:close(Client0),
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -2340,7 +2396,7 @@ server_verify_client_once_active(Config) when is_list(Config) ->
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {?MODULE, send_recv_result_active, []}},
- {options, [{active, once}, {verify, verify_peer},
+ {options, [{active, true}, {verify, verify_peer},
{verify_client_once, true}
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
@@ -2351,8 +2407,8 @@ server_verify_client_once_active(Config) when is_list(Config) ->
{options, [{active, true} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client0, ok),
- ssl_test_lib:close(Client0),
Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+ ssl_test_lib:close(Client0),
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -2389,8 +2445,8 @@ server_verify_client_once_active_once(Config) when is_list(Config) ->
{options, [{active, once} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client0, ok),
- ssl_test_lib:close(Client0),
Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+ ssl_test_lib:close(Client0),
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -2592,7 +2648,7 @@ client_renegotiate(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {?MODULE,
@@ -2724,17 +2780,28 @@ client_no_wrap_sequence_number(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_record:highest_protocol_version(ssl_record:supported_protocol_versions()),
+
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib,
- trigger_renegotiate, [[ErlData, N+2]]}},
+ trigger_renegotiate, [[ErlData, treashold(N, Version)]]}},
{options, [{reuse_sessions, false},
{renegotiate_at, N} | ClientOpts]}]),
ssl_test_lib:check_result(Client, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+ %% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+treashold(N, {3,0}) ->
+ (N div 2) + 1;
+treashold(N, {3,1}) ->
+ (N div 2) + 1;
+treashold(N, _) ->
+ N + 1.
+
%%--------------------------------------------------------------------
server_no_wrap_sequence_number(doc) ->
["Test that erlang server will renegotiate session when",
@@ -2784,7 +2851,7 @@ extended_key_usage_verify_peer(Config) when is_list(Config) ->
KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = public_key:pem_entry_decode(KeyEntry),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ServerCertFile = proplists:get_value(certfile, ServerOpts),
NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"),
@@ -2846,7 +2913,7 @@ extended_key_usage_verify_none(Config) when is_list(Config) ->
KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = public_key:pem_entry_decode(KeyEntry),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ServerCertFile = proplists:get_value(certfile, ServerOpts),
NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"),
@@ -2908,7 +2975,7 @@ no_authority_key_identifier(Config) when is_list(Config) ->
KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = public_key:pem_entry_decode(KeyEntry),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
CertFile = proplists:get_value(certfile, ServerOpts),
NewCertFile = filename:join(PrivDir, "server/new_cert.pem"),
@@ -2966,7 +3033,7 @@ invalid_signature_server(Config) when is_list(Config) ->
KeyFile = filename:join(PrivDir, "server/key.pem"),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = public_key:pem_entry_decode(KeyEntry),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ServerCertFile = proplists:get_value(certfile, ServerOpts),
NewServerCertFile = filename:join(PrivDir, "server/invalid_cert.pem"),
@@ -2988,8 +3055,8 @@ invalid_signature_server(Config) when is_list(Config) ->
{from, self()},
{options, [{verify, verify_peer} | ClientOpts]}]),
- ssl_test_lib:check_result(Server, {error, "bad certificate"},
- Client, {error,"bad certificate"}).
+ tcp_delivery_workaround(Server, {error, "bad certificate"},
+ Client, {error,"bad certificate"}).
%%--------------------------------------------------------------------
@@ -3006,7 +3073,7 @@ invalid_signature_client(Config) when is_list(Config) ->
KeyFile = filename:join(PrivDir, "client/key.pem"),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = public_key:pem_entry_decode(KeyEntry),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ClientCertFile = proplists:get_value(certfile, ClientOpts),
NewClientCertFile = filename:join(PrivDir, "client/invalid_cert.pem"),
@@ -3034,41 +3101,47 @@ invalid_signature_client(Config) when is_list(Config) ->
tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) ->
receive
{Server, ServerMsg} ->
- receive
- {Client, ClientMsg} ->
- ok;
- {Client, {error,closed}} ->
- test_server:format("client got close");
- Unexpected ->
- test_server:fail(Unexpected)
- end;
+ client_msg(Client, ClientMsg);
{Client, ClientMsg} ->
- receive
- {Server, ServerMsg} ->
- ok;
- Unexpected ->
- test_server:fail(Unexpected)
- end;
+ server_msg(Server, ServerMsg);
{Client, {error,closed}} ->
- receive
- {Server, ServerMsg} ->
- ok;
- Unexpected ->
- test_server:fail(Unexpected)
- end;
+ server_msg(Server, ServerMsg);
{Server, {error,closed}} ->
- receive
- {Client, ClientMsg} ->
- ok;
- {Client, {error,closed}} ->
- test_server:format("client got close"),
- ok;
- Unexpected ->
- test_server:fail(Unexpected)
- end;
+ client_msg(Client, ClientMsg);
+ {Client, {error, esslconnect}} ->
+ server_msg(Server, ServerMsg);
+ {Server, {error, esslaccept}} ->
+ client_msg(Client, ClientMsg)
+ end.
+
+client_msg(Client, ClientMsg) ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ {Client, {error,closed}} ->
+ test_server:format("client got close"),
+ ok;
+ {Client, {error, esslconnect}} ->
+ test_server:format("client got econnaborted"),
+ ok;
Unexpected ->
test_server:fail(Unexpected)
end.
+
+server_msg(Server, ServerMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ {Server, {error,closed}} ->
+ test_server:format("server got close"),
+ ok;
+ {Server, {error, esslaccept}} ->
+ test_server:format("server got econnaborted"),
+ ok;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end.
+
%%--------------------------------------------------------------------
cert_expired(doc) ->
["Test server with invalid signature"];
@@ -3083,7 +3156,7 @@ cert_expired(Config) when is_list(Config) ->
KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = public_key:pem_entry_decode(KeyEntry),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ServerCertFile = proplists:get_value(certfile, ServerOpts),
NewServerCertFile = filename:join(PrivDir, "server/expired_cert.pem"),
@@ -3166,6 +3239,105 @@ client_with_cert_cipher_suites_handshake(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+verify_fun_always_run_client(doc) ->
+ ["Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"];
+verify_fun_always_run_client(suite) ->
+ [];
+verify_fun_always_run_client(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ %% If user verify fun is called correctly we fail the connection.
+ %% otherwise we can not tell this case apart form where we miss
+ %% to call users verify fun
+ FunAndState = {fun(_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (_, valid, [ChainLen]) ->
+ {valid, [ChainLen + 1]};
+ (_, valid_peer, [2]) ->
+ {fail, "verify_fun_was_always_run"};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
+ end, [0]},
+
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options,
+ [{verify, verify_peer},
+ {verify_fun, FunAndState}
+ | ClientOpts]}]),
+ %% Server error may be esslaccept or closed depending on timing
+ %% this is not a bug it is a circumstance of how tcp works!
+ receive
+ {Server, ServerError} ->
+ test_server:format("Server Error ~p~n", [ServerError])
+ end,
+
+ ssl_test_lib:check_result(Client, {error, esslconnect}).
+
+%%--------------------------------------------------------------------
+verify_fun_always_run_server(doc) ->
+ ["Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"];
+verify_fun_always_run_server(suite) ->
+ [];
+verify_fun_always_run_server(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ %% If user verify fun is called correctly we fail the connection.
+ %% otherwise we can not tell this case apart form where we miss
+ %% to call users verify fun
+ FunAndState = {fun(_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (_, valid, [ChainLen]) ->
+ {valid, [ChainLen + 1]};
+ (_, valid_peer, [2]) ->
+ {fail, "verify_fun_was_always_run"};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
+ end, [0]},
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options,
+ [{verify, verify_peer},
+ {verify_fun, FunAndState} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options,
+ [{verify, verify_peer}
+ | ClientOpts]}]),
+
+ %% Client error may be esslconnect or closed depending on timing
+ %% this is not a bug it is a circumstance of how tcp works!
+ receive
+ {Client, ClientError} ->
+ test_server:format("Client Error ~p~n", [ClientError])
+ end,
+
+ ssl_test_lib:check_result(Server, {error, esslaccept}).
+
%%--------------------------------------------------------------------
unknown_server_ca_fail(doc) ->
["Test that the client fails if the ca is unknown in verify_peer mode"];
@@ -3358,14 +3530,14 @@ der_input_opts(Opts) ->
Keyfile = proplists:get_value(keyfile, Opts),
Dhfile = proplists:get_value(dhfile, Opts),
[{_, Cert, _}] = ssl_test_lib:pem_to_der(Certfile),
- [{_, Key, _}] = ssl_test_lib:pem_to_der(Keyfile),
+ [{Asn1Type, Key, _}] = ssl_test_lib:pem_to_der(Keyfile),
[{_, DHParams, _}] = ssl_test_lib:pem_to_der(Dhfile),
CaCerts =
lists:map(fun(Entry) ->
{_, CaCert, _} = Entry,
CaCert
end, ssl_test_lib:pem_to_der(CaCertsfile)),
- {Cert, {rsa, Key}, CaCerts, DHParams}.
+ {Cert, {Asn1Type, Key}, CaCerts, DHParams}.
%%--------------------------------------------------------------------
%% different_ca_peer_sign(doc) ->
@@ -3497,6 +3669,8 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client0),
+ ssl:clear_pem_cache(),
+
NewServerOpts = new_config(PrivDir, DsaServerOpts),
Server1 =
@@ -3588,14 +3762,13 @@ hibernate(Config) ->
{from, self()},
{mfa, {?MODULE, send_recv_result_active, []}},
{options, [{hibernate_after, 1000}|ClientOpts]}]),
-
- { current_function, { _M, _F, _A } } =
+ {current_function, _} =
process_info(Pid, current_function),
timer:sleep(1100),
- { current_function, { erlang, hibernate, 3} } =
- process_info(Pid, current_function),
+ {current_function, {erlang, hibernate, 3}} =
+ process_info(Pid, current_function),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
@@ -3647,6 +3820,193 @@ connect_twice(Config) when is_list(Config) ->
ssl_test_lib:close(Client),
ssl_test_lib:close(Client1).
+%%--------------------------------------------------------------------
+renegotiate_dos_mitigate_active(doc) ->
+ ["Mitigate DOS computational attack by not allowing client to renegotiate many times in a row",
+ "immediately after each other"];
+
+renegotiate_dos_mitigate_active(suite) ->
+ [];
+
+renegotiate_dos_mitigate_active(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, 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, {?MODULE,
+ renegotiate_immediately, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+renegotiate_dos_mitigate_passive(doc) ->
+ ["Mitigate DOS computational attack by not allowing client to renegotiate many times in a row",
+ "immediately after each other"];
+
+renegotiate_dos_mitigate_passive(suite) ->
+ [];
+
+renegotiate_dos_mitigate_passive(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_immediately, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+tcp_error_propagation_in_active_mode(doc) ->
+ ["Test that process recives {ssl_error, Socket, closed} when tcp error ocurres"];
+tcp_error_propagation_in_active_mode(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, 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, no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {Client, #sslsocket{pid=Pid} = SslSocket} = ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, receive_msg, []}},
+ {options, ClientOpts}]),
+
+ {status, _, _, StatusInfo} = sys:get_status(Pid),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ Socket = element(10, State),
+
+ %% Fake tcp error
+ Pid ! {tcp_error, Socket, etimedout},
+
+ ssl_test_lib:check_result(Client, {ssl_closed, SslSocket}).
+
+
+%%--------------------------------------------------------------------
+
+recv_error_handling(doc) ->
+ ["Special case of call error handling"];
+recv_error_handling(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, recv_close, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {_Client, #sslsocket{} = SslSocket} = ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+ ssl:close(SslSocket),
+ ssl_test_lib:check_result(Server, ok).
+
+
+%%--------------------------------------------------------------------
+
+rizzo(doc) -> ["Test that there is a 1/n-1-split for non RC4 in 'TLS < 1.1' as it is
+ vunrable to Rizzo/Dungon attack"];
+
+rizzo(Config) when is_list(Config) ->
+ Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(), Y =/= rc4_128],
+ Prop = ?config(tc_group_properties, Config),
+ Version = proplists:get_value(name, Prop),
+ run_send_recv_rizzo(Ciphers, Config, Version,
+ {?MODULE, send_recv_result_active_rizzo, []}).
+%%--------------------------------------------------------------------
+no_rizzo_rc4(doc) ->
+ ["Test that there is no 1/n-1-split for RC4 as it is not vunrable to Rizzo/Dungon attack"];
+
+no_rizzo_rc4(Config) when is_list(Config) ->
+ Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(),Y == rc4_128],
+ Prop = ?config(tc_group_properties, Config),
+ Version = proplists:get_value(name, Prop),
+ run_send_recv_rizzo(Ciphers, Config, Version,
+ {?MODULE, send_recv_result_active_no_rizzo, []}).
+
+%%--------------------------------------------------------------------
+run_send_recv_rizzo(Ciphers, Config, Version, Mfa) ->
+ Result = lists:map(fun(Cipher) ->
+ rizzo_test(Cipher, Config, Version, Mfa) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+rizzo_test(Cipher, Config, Version, Mfa) ->
+ {ClientOpts, ServerOpts} = client_server_opts(Cipher, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, Mfa},
+ {options, [{active, true}, {ciphers, [Cipher]},
+ {versions, [Version]}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, Mfa},
+ {options, [{active, true} | ClientOpts]}]),
+
+ Result = ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ case Result of
+ ok ->
+ [];
+ Error ->
+ [{Cipher, Error}]
+ end.
+
+client_server_opts({KeyAlgo,_,_}, Config) when KeyAlgo == rsa orelse KeyAlgo == dhe_rsa ->
+ {?config(client_opts, Config),
+ ?config(server_opts, Config)};
+client_server_opts({KeyAlgo,_,_}, Config) when KeyAlgo == dss orelse KeyAlgo == dhe_dss ->
+ {?config(client_dsa_opts, Config),
+ ?config(server_dsa_opts, Config)}.
%%--------------------------------------------------------------------
%%% Internal functions
@@ -3656,9 +4016,40 @@ send_recv_result(Socket) ->
{ok,"Hello world"} = ssl:recv(Socket, 11),
ok.
+recv_close(Socket) ->
+ {error, closed} = ssl:recv(Socket, 11),
+ receive
+ {_,{error,closed}} ->
+ error_extra_close_sent_to_user_process
+ after 500 ->
+ ok
+ end.
+
send_recv_result_active(Socket) ->
ssl:send(Socket, "Hello world"),
receive
+ {ssl, Socket, "H"} ->
+ receive
+ {ssl, Socket, "ello world"} ->
+ ok
+ end;
+ {ssl, Socket, "Hello world"} ->
+ ok
+ end.
+
+send_recv_result_active_rizzo(Socket) ->
+ ssl:send(Socket, "Hello world"),
+ receive
+ {ssl, Socket, "H"} ->
+ receive
+ {ssl, Socket, "ello world"} ->
+ ok
+ end
+ end.
+
+send_recv_result_active_no_rizzo(Socket) ->
+ ssl:send(Socket, "Hello world"),
+ receive
{ssl, Socket, "Hello world"} ->
ok
end.
@@ -3666,6 +4057,12 @@ send_recv_result_active(Socket) ->
send_recv_result_active_once(Socket) ->
ssl:send(Socket, "Hello world"),
receive
+ {ssl, Socket, "H"} ->
+ ssl:setopts(Socket, [{active, once}]),
+ receive
+ {ssl, Socket, "ello world"} ->
+ ok
+ end;
{ssl, Socket, "Hello world"} ->
ok
end.
@@ -3686,10 +4083,29 @@ renegotiate(Socket, Data) ->
end.
renegotiate_reuse_session(Socket, Data) ->
- %% Make sure session is registerd
+ %% Make sure session is registered
test_server:sleep(?SLEEP),
renegotiate(Socket, Data).
+renegotiate_immediately(Socket) ->
+ receive
+ {ssl, Socket, "Hello world"} ->
+ ok;
+ %% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+ {ssl, Socket, "H"} ->
+ receive
+ {ssl, Socket, "ello world"} ->
+ ok
+ end
+ end,
+ ok = ssl:renegotiate(Socket),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ test_server:sleep(?RENEGOTIATION_DISABLE_TIME +1),
+ ok = ssl:renegotiate(Socket),
+ test_server:format("Renegotiated again"),
+ ssl:send(Socket, "Hello world"),
+ ok.
+
new_config(PrivDir, ServerOpts0) ->
CaCertFile = proplists:get_value(cacertfile, ServerOpts0),
CertFile = proplists:get_value(certfile, ServerOpts0),
@@ -3863,8 +4279,17 @@ erlang_ssl_receive(Socket, Data) ->
{ssl, Socket, Data} ->
io:format("Received ~p~n",[Data]),
ok;
+ {ssl, Socket, Byte} when length(Byte) == 1 -> %% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+ io:format("Received ~p~n",[Byte]),
+ erlang_ssl_receive(Socket, tl(Data));
Other ->
test_server:fail({unexpected_message, Other})
after ?SLEEP * 3 ->
test_server:fail({did_not_get, Data})
end.
+
+receive_msg(_) ->
+ receive
+ Msg ->
+ Msg
+ end.