aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/test')
-rw-r--r--lib/ssl/test/Makefile12
-rw-r--r--lib/ssl/test/make_certs.erl30
-rw-r--r--lib/ssl/test/ssl.spec7
-rw-r--r--lib/ssl/test/ssl_ECC.erl1
-rw-r--r--lib/ssl/test/ssl_alpn_handshake_SUITE.erl25
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl527
-rw-r--r--lib/ssl/test/ssl_bench.spec2
-rw-r--r--lib/ssl/test/ssl_bench_SUITE.erl65
-rw-r--r--lib/ssl/test/ssl_bench_test_lib.erl75
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl146
-rw-r--r--lib/ssl/test/ssl_crl_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_dist_SUITE.erl328
-rw-r--r--lib/ssl/test/ssl_dist_bench_SUITE.erl526
-rw-r--r--lib/ssl/test/ssl_dist_test_lib.erl343
-rw-r--r--lib/ssl/test/ssl_dist_test_lib.hrl26
-rw-r--r--lib/ssl/test/ssl_engine_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl38
-rw-r--r--lib/ssl/test/ssl_npn_handshake_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl52
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_pem_cache_SUITE.erl47
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl6
-rw-r--r--lib/ssl/test/ssl_sni_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_test_lib.erl269
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl823
25 files changed, 2323 insertions, 1035 deletions
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 256c0bb017..9dfb2eba53 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2017. All Rights Reserved.
+# Copyright Ericsson AB 1999-2018. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -37,6 +37,8 @@ VSN=$(GS_VSN)
MODULES = \
ssl_test_lib \
+ ssl_bench_test_lib \
+ ssl_dist_test_lib \
ssl_alpn_handshake_SUITE \
ssl_basic_SUITE \
ssl_bench_SUITE \
@@ -44,6 +46,7 @@ MODULES = \
ssl_certificate_verify_SUITE\
ssl_crl_SUITE\
ssl_dist_SUITE \
+ ssl_dist_bench_SUITE \
ssl_engine_SUITE\
ssl_handshake_SUITE \
ssl_npn_hello_SUITE \
@@ -53,9 +56,9 @@ MODULES = \
ssl_pem_cache_SUITE \
ssl_session_cache_SUITE \
ssl_to_openssl_SUITE \
+ ssl_ECC_SUITE \
+ ssl_ECC_openssl_SUITE \
ssl_ECC\
- ssl_ECC_SUITE \
- ssl_ECC_openssl_SUITE\
ssl_upgrade_SUITE\
ssl_sni_SUITE \
make_certs\
@@ -64,7 +67,8 @@ MODULES = \
ERL_FILES = $(MODULES:%=%.erl)
-HRL_FILES =
+HRL_FILES = \
+ ssl_dist_test_lib.hrl
HRL_FILES_SRC = \
ssl_api.hrl\
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
index ecbacc1590..8fe7c54549 100644
--- a/lib/ssl/test/make_certs.erl
+++ b/lib/ssl/test/make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
%%
-module(make_certs).
--compile([export_all]).
+-compile([export_all, nowarn_export_all]).
%-export([all/1, all/2, rootCA/2, intermediateCA/3, endusers/3, enduser/3, revoke/3, gencrl/2, verify/3]).
@@ -34,14 +34,15 @@
ecc_certs = false,
issuing_distribution_point = false,
crl_port = 8000,
- openssl_cmd = "openssl"}).
+ openssl_cmd = "openssl",
+ hostname = "host.example.com"}).
default_config() ->
- #config{}.
+ #config{hostname = net_adm:localhost()}.
make_config(Args) ->
- make_config(Args, #config{}).
+ make_config(Args, default_config()).
make_config([], C) ->
C;
@@ -66,7 +67,9 @@ make_config([{ecc_certs, Bool}|T], C) when is_boolean(Bool) ->
make_config([{issuing_distribution_point, Bool}|T], C) when is_boolean(Bool) ->
make_config(T, C#config{issuing_distribution_point = Bool});
make_config([{openssl_cmd, Cmd}|T], C) when is_list(Cmd) ->
- make_config(T, C#config{openssl_cmd = Cmd}).
+ make_config(T, C#config{openssl_cmd = Cmd});
+make_config([{hostname, Hostname}|T], C) when is_list(Hostname) ->
+ make_config(T, C#config{hostname = Hostname}).
all([DataDir, PrivDir]) ->
@@ -384,8 +387,11 @@ req_cnf(Root, C) ->
"subjectKeyIdentifier = hash\n"
"subjectAltName = email:copy\n"].
-ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
- Hostname = net_adm:localhost(),
+ca_cnf(
+ Root,
+ #config{
+ issuing_distribution_point = true,
+ hostname = Hostname} = C) ->
["# Purpose: Configuration for CAs.\n"
"\n"
"ROOTDIR = " ++ Root ++ "\n"
@@ -464,8 +470,12 @@ ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
"crlDistributionPoints=@crl_section\n"
];
-ca_cnf(Root, C = #config{issuing_distribution_point = false}) ->
- Hostname = net_adm:localhost(),
+ca_cnf(
+ Root,
+ #config{
+ issuing_distribution_point = false,
+ hostname = Hostname
+ } = C) ->
["# Purpose: Configuration for CAs.\n"
"\n"
"ROOTDIR = " ++ Root ++ "\n"
diff --git a/lib/ssl/test/ssl.spec b/lib/ssl/test/ssl.spec
index 0ad94e22bc..cb54168d36 100644
--- a/lib/ssl/test/ssl.spec
+++ b/lib/ssl/test/ssl.spec
@@ -1,5 +1,4 @@
{suites,"../ssl_test",all}.
-{skip_cases, "../ssl_test",
- ssl_bench_SUITE, [setup_sequential, setup_concurrent, payload_simple,
- use_pem_cache, bypass_pem_cache],
- "Benchmarks run separately"}.
+{skip_suites, "../ssl_test",
+ [ssl_bench_SUITE, ssl_dist_bench_SUITE],
+ "Benchmarks run separately"}.
diff --git a/lib/ssl/test/ssl_ECC.erl b/lib/ssl/test/ssl_ECC.erl
index 6422cd75e9..36d949f74b 100644
--- a/lib/ssl/test/ssl_ECC.erl
+++ b/lib/ssl/test/ssl_ECC.erl
@@ -1,3 +1,4 @@
+
%%
%% %CopyrightBegin%
%%
diff --git a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
index 055f05a900..04c4b257d9 100644
--- a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -155,7 +155,7 @@ empty_client(Config) when is_list(Config) ->
run_failing_handshake(Config,
[{alpn_advertised_protocols, []}],
[{alpn_preferred_protocols, [<<"spdy/2">>, <<"spdy/3">>, <<"http/2">>]}],
- {connect_failed,{tls_alert,"no application protocol"}}).
+ {error,{tls_alert,"no application protocol"}}).
%--------------------------------------------------------------------------------
@@ -163,7 +163,7 @@ empty_server(Config) when is_list(Config) ->
run_failing_handshake(Config,
[{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
[{alpn_preferred_protocols, []}],
- {connect_failed,{tls_alert,"no application protocol"}}).
+ {error,{tls_alert,"no application protocol"}}).
%--------------------------------------------------------------------------------
@@ -171,7 +171,7 @@ empty_client_empty_server(Config) when is_list(Config) ->
run_failing_handshake(Config,
[{alpn_advertised_protocols, []}],
[{alpn_preferred_protocols, []}],
- {connect_failed,{tls_alert,"no application protocol"}}).
+ {error,{tls_alert,"no application protocol"}}).
%--------------------------------------------------------------------------------
@@ -179,7 +179,7 @@ no_matching_protocol(Config) when is_list(Config) ->
run_failing_handshake(Config,
[{alpn_advertised_protocols, [<<"http/1.0">>, <<"http/1.1">>]}],
[{alpn_preferred_protocols, [<<"spdy/2">>, <<"spdy/3">>, <<"http/2">>]}],
- {connect_failed,{tls_alert,"no application protocol"}}).
+ {error,{tls_alert,"no application protocol"}}).
%--------------------------------------------------------------------------------
@@ -342,18 +342,19 @@ run_failing_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedResult)
ServerOpts = ServerExtraOpts ++ ssl_test_lib:ssl_options(server_rsa_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {?MODULE, placeholder, []}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
- ExpectedResult
- = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, placeholder, []}},
- {options, ClientOpts}]).
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, placeholder, []}},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ExpectedResult,
+ Client, ExpectedResult).
run_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) ->
Data = "hello world",
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 0023c8656a..f474d7f978 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-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -108,7 +108,8 @@ basic_tests() ->
clear_pem_cache,
defaults,
fallback,
- cipher_format
+ cipher_format,
+ suite_to_str
].
basic_tests_tls() ->
@@ -146,8 +147,7 @@ options_tests_tls() ->
tls_tcp_reuseaddr].
api_tests() ->
- [connection_info,
- secret_connection_info,
+ [secret_connection_info,
connection_information,
peercert,
peercert_with_client_cert,
@@ -164,7 +164,10 @@ api_tests() ->
accept_pool,
prf,
socket_options,
- cipher_suites
+ cipher_suites,
+ handshake_continue,
+ hello_client_cancel,
+ hello_server_cancel
].
api_tests_tls() ->
@@ -194,6 +197,7 @@ renegotiate_tests() ->
[client_renegotiate,
server_renegotiate,
client_secure_renegotiate,
+ client_secure_renegotiate_fallback,
client_renegotiate_reused_session,
server_renegotiate_reused_session,
client_no_wrap_sequence_number,
@@ -214,6 +218,8 @@ cipher_tests() ->
ciphers_rsa_signed_certs_openssl_names,
ciphers_dsa_signed_certs,
ciphers_dsa_signed_certs_openssl_names,
+ chacha_rsa_cipher_suites,
+ chacha_ecdsa_cipher_suites,
anonymous_cipher_suites,
psk_cipher_suites,
psk_with_hint_cipher_suites,
@@ -236,7 +242,10 @@ error_handling_tests()->
[close_transport_accept,
recv_active,
recv_active_once,
- recv_error_handling
+ recv_error_handling,
+ call_in_error_state,
+ close_in_error_state,
+ abuse_transport_accept_socket
].
error_handling_tests_tls()->
@@ -267,7 +276,8 @@ init_per_suite(Config0) ->
proplists:get_value(priv_dir, Config0)),
Config1 = ssl_test_lib:make_dsa_cert(Config0),
Config2 = ssl_test_lib:make_ecdsa_cert(Config1),
- Config = ssl_test_lib:make_ecdh_rsa_cert(Config2),
+ Config3 = ssl_test_lib:make_rsa_cert(Config2),
+ Config = ssl_test_lib:make_ecdh_rsa_cert(Config3),
ssl_test_lib:cert_options(Config)
catch _:_ ->
{skip, "Crypto did not start"}
@@ -288,6 +298,7 @@ init_per_group(GroupName, Config) when GroupName == basic_tls;
->
ssl_test_lib:clean_tls_version(Config);
init_per_group(GroupName, Config) ->
+ ssl_test_lib:clean_tls_version(Config),
case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of
true ->
ssl_test_lib:init_tls_version(GroupName, Config);
@@ -467,6 +478,8 @@ init_per_testcase(TestCase, Config) when TestCase == tls_ssl_accept_timeout;
TestCase == tls_client_closes_socket;
TestCase == tls_closed_in_active_once;
TestCase == tls_downgrade ->
+ ssl:stop(),
+ ssl:start(),
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 15}),
Config;
@@ -601,7 +614,16 @@ new_options_in_accept(Config) when is_list(Config) ->
[_ , _ | ServerSslOpts] = ssl_test_lib:ssl_options(server_opts, Config), %% Remove non ssl opts
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Version = ssl_test_lib:protocol_options(Config, [{tls, sslv3}, {dtls, dtlsv1}]),
- Cipher = ssl_test_lib:protocol_options(Config, [{tls, {rsa,rc4_128,sha}}, {dtls, {rsa,aes_128_cbc,sha}}]),
+ Cipher = ssl_test_lib:protocol_options(Config, [{tls, #{key_exchange =>rsa,
+ cipher => rc4_128,
+ mac => sha,
+ prf => default_prf
+ }},
+ {dtls, #{key_exchange =>rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf
+ }}]),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{ssl_extra_opts, [{versions, [Version]},
@@ -626,6 +648,89 @@ new_options_in_accept(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+handshake_continue() ->
+ [{doc, "Test API function ssl:handshake_continue/3"}].
+handshake_continue(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_verification_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, 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, ssl_test_lib:ssl_options([{handshake, hello}],
+ Config)},
+ {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).
+
+%%--------------------------------------------------------------------
+hello_client_cancel() ->
+ [{doc, "Test API function ssl:handshake_cancel/1 on the client side"}].
+hello_client_cancel(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
+ {continue_options, proplists:delete(reuseaddr, ServerOpts)}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ %% That is ssl:handshake_cancel returns ok
+ {connect_failed, ok} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
+ {continue_options, cancel}]),
+ receive
+ {Server, {error, {tls_alert, "user canceled"}}} ->
+ ok;
+ {Server, {error, closed}} ->
+ ct:pal("Did not receive the ALERT"),
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+hello_server_cancel() ->
+ [{doc, "Test API function ssl:handshake_cancel/1 on the server side"}].
+hello_server_cancel(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
+ {continue_options, cancel}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ {connect_failed, _} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
+ {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
+
+ ssl_test_lib:check_result(Server, ok).
+
%%--------------------------------------------------------------------
prf() ->
[{doc,"Test that ssl:prf/5 uses the negotiated PRF."}].
@@ -647,41 +752,6 @@ prf(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-connection_info() ->
- [{doc,"Test the API function ssl:connection_information/2"}].
-connection_info(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_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, connection_info_result, []}},
- {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, connection_info_result, []}},
- {options,
- [{ciphers,[{rsa, aes_128_cbc, sha}]} |
- ClientOpts]}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- Version = ssl_test_lib:protocol_version(Config),
-
- ServerMsg = ClientMsg = {ok, {Version, {rsa, aes_128_cbc, sha}}},
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
secret_connection_info() ->
[{doc,"Test the API function ssl:connection_information/2"}].
secret_connection_info(Config) when is_list(Config) ->
@@ -959,7 +1029,7 @@ controller_dies(Config) when is_list(Config) ->
{mfa, {?MODULE,
controller_dies_result, [self(),
ClientMsg]}},
- {options, [{reuseaddr,true}|ClientOpts]}]),
+ {options, ClientOpts}]),
ct:sleep(?SLEEP), %% so that they are connected
exit(Server, killed),
@@ -984,7 +1054,7 @@ tls_client_closes_socket(Config) when is_list(Config) ->
Connect = fun() ->
{ok, _Socket} = rpc:call(ClientNode, gen_tcp, connect,
- [Hostname, Port, TcpOpts]),
+ [Hostname, Port, [binary]]),
%% Make sure that ssl_accept is called before
%% client process ends and closes socket.
ct:sleep(?SLEEP)
@@ -1114,16 +1184,16 @@ fallback(Config) when is_list(Config) ->
Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client_error([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {from, self()}, {options,
- [{fallback, true},
- {versions, ['tlsv1']}
- | ClientOpts]}]),
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()}, {options,
+ [{fallback, true},
+ {versions, ['tlsv1']}
+ | ClientOpts]}]),
- ssl_test_lib:check_result(Server, {error,{tls_alert,"inappropriate fallback"}},
- Client, {error,{tls_alert,"inappropriate fallback"}}).
+ ssl_test_lib:check_result(Server, {error,{tls_alert,"inappropriate fallback"}},
+ Client, {error,{tls_alert,"inappropriate fallback"}}).
%%--------------------------------------------------------------------
cipher_format() ->
@@ -1136,7 +1206,27 @@ cipher_format(Config) when is_list(Config) ->
ssl:close(Socket1),
{ok, Socket2} = ssl:listen(0, [{ciphers, ssl:cipher_suites(openssl)}]),
ssl:close(Socket2).
-
+
+%%--------------------------------------------------------------------
+suite_to_str() ->
+ [{doc, "Test that the suite_to_str API works"}].
+suite_to_str(Config) when is_list(Config) ->
+ "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" =
+ ssl:suite_to_str(#{key_exchange => null,
+ cipher => null,
+ mac => null,
+ prf => null}),
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" =
+ ssl:suite_to_str(#{key_exchange => ecdhe_ecdsa,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}),
+ "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256" =
+ ssl:suite_to_str(#{key_exchange => ecdh_rsa,
+ cipher => aes_128_cbc,
+ mac => sha256,
+ prf => sha256}).
+
%%--------------------------------------------------------------------
peername() ->
@@ -1293,6 +1383,14 @@ cipher_suites() ->
" and prepend|append_cipher_suites/2"}].
cipher_suites(Config) when is_list(Config) ->
+ MandatoryCipherSuiteTLS1_0TLS1_1 = #{key_exchange => rsa,
+ cipher => '3des_ede_cbc',
+ mac => sha,
+ prf => default_prf},
+ MandatoryCipherSuiteTLS1_0TLS1_2 = #{key_exchange =>rsa,
+ cipher => 'aes_128_cbc',
+ mac => sha,
+ prf => default_prf},
Version = ssl_test_lib:protocol_version(Config),
All = [_|_] = ssl:cipher_suites(all, Version),
Default = [_|_] = ssl:cipher_suites(default, Version),
@@ -1334,8 +1432,9 @@ cipher_suites(Config) when is_list(Config) ->
true = lists:member(Cipher, Default),
false = lists:member(Cipher, Rest1),
[] = lists:dropwhile(fun(X) -> not lists:member(X, Default) end, Anonymous),
- [] = lists:dropwhile(fun(X) -> not lists:member(X, All) end, Anonymous).
-
+ [] = lists:dropwhile(fun(X) -> not lists:member(X, All) end, Anonymous),
+ true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_1, All),
+ true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_2, All).
%%--------------------------------------------------------------------
@@ -1343,18 +1442,18 @@ old_cipher_suites() ->
[{doc,"Test API function cipher_suites/0"}].
old_cipher_suites(Config) when is_list(Config) ->
- MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha},
+ MandatoryCipherSuite = {rsa, '3des_ede_cbc', sha},
[_|_] = Suites = ssl:cipher_suites(),
- true = lists:member(MandatoryCipherSuite, Suites),
Suites = ssl:cipher_suites(erlang),
- [_|_] =ssl:cipher_suites(openssl).
+ [_|_] = ssl:cipher_suites(openssl),
+ true = lists:member(MandatoryCipherSuite, ssl:cipher_suites(all)).
%%--------------------------------------------------------------------
cipher_suites_mix() ->
[{doc,"Test to have old and new cipher suites at the same time"}].
cipher_suites_mix(Config) when is_list(Config) ->
- CipherSuites = [{ecdh_rsa,aes_128_cbc,sha256,sha256}, {rsa,aes_128_cbc,sha}],
+ CipherSuites = [{dhe_rsa,aes_128_cbc,sha256,sha256}, {dhe_rsa,aes_128_cbc,sha}],
ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
@@ -1799,7 +1898,7 @@ tls_send_close(Config) when is_list(Config) ->
{options, [{active, false} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
{ok, TcpS} = rpc:call(ClientNode, gen_tcp, connect,
- [Hostname,Port,[binary, {active, false}, {reuseaddr, true}]]),
+ [Hostname,Port,[binary, {active, false}]]),
{ok, SslS} = rpc:call(ClientNode, ssl, connect,
[TcpS,[{active, false}|ClientOpts]]),
@@ -1943,7 +2042,7 @@ tls_upgrade(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{mfa, {?MODULE, upgrade_result, []}},
- {tcp_options, TcpOpts},
+ {tcp_options, [binary]},
{ssl_options, ClientOpts}]),
ct:log("Testcase ~p, Client ~p Server ~p ~n",
@@ -2422,7 +2521,24 @@ ciphers_dsa_signed_certs_openssl_names() ->
ciphers_dsa_signed_certs_openssl_names(Config) when is_list(Config) ->
Ciphers = ssl_test_lib:openssl_dsa_suites(),
run_suites(Ciphers, Config, dsa).
+
%%-------------------------------------------------------------------
+chacha_rsa_cipher_suites()->
+ [{doc,"Test the cacha with ECDSA signed certs ciphersuites"}].
+chacha_rsa_cipher_suites(Config) when is_list(Config) ->
+ NVersion = ssl_test_lib:protocol_version(Config, tuple),
+ Ciphers = [S || {KeyEx,_,_} = S <- ssl_test_lib:chacha_suites(NVersion),
+ KeyEx == ecdhe_rsa, KeyEx == dhe_rsa],
+ run_suites(Ciphers, Config, chacha_ecdsa).
+
+%%-------------------------------------------------------------------
+chacha_ecdsa_cipher_suites()->
+ [{doc,"Test the cacha with ECDSA signed certs ciphersuites"}].
+chacha_ecdsa_cipher_suites(Config) when is_list(Config) ->
+ NVersion = ssl_test_lib:protocol_version(Config, tuple),
+ Ciphers = [S || {ecdhe_ecdsa,_,_} = S <- ssl_test_lib:chacha_suites(NVersion)],
+ run_suites(Ciphers, Config, chacha_rsa).
+%%-----------------------------------------------------------------
anonymous_cipher_suites()->
[{doc,"Test the anonymous ciphersuites"}].
anonymous_cipher_suites(Config) when is_list(Config) ->
@@ -2502,14 +2618,15 @@ rc4_ecdsa_cipher_suites(Config) when is_list(Config) ->
des_rsa_cipher_suites()->
[{doc, "Test the des_rsa ciphersuites"}].
des_rsa_cipher_suites(Config) when is_list(Config) ->
- Ciphers = ssl_test_lib:des_suites(Config),
+ NVersion = tls_record:highest_protocol_version([]),
+ Ciphers = [S || {rsa,_,_} = S <- ssl_test_lib:des_suites(NVersion)],
run_suites(Ciphers, Config, des_rsa).
%-------------------------------------------------------------------
des_ecdh_rsa_cipher_suites()->
[{doc, "Test ECDH rsa signed ciphersuites"}].
des_ecdh_rsa_cipher_suites(Config) when is_list(Config) ->
NVersion = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl_test_lib:des_suites(NVersion),
+ Ciphers = [S || {dhe_rsa,_,_} = S <- ssl_test_lib:des_suites(NVersion)],
run_suites(Ciphers, Config, des_dhe_rsa).
%%--------------------------------------------------------------------
@@ -2529,14 +2646,14 @@ default_reject_anonymous(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options,
- [{ciphers,[CipherSuite]} |
- ClientOpts]}]),
+ {host, Hostname},
+ {from, self()},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
ssl_test_lib:check_result(Server, {error, {tls_alert, "insufficient security"}},
- Client, {error, {tls_alert, "insufficient security"}}).
+ Client, {error, {tls_alert, "insufficient security"}}).
%%--------------------------------------------------------------------
ciphers_ecdsa_signed_certs() ->
@@ -2869,6 +2986,36 @@ client_secure_renegotiate(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+client_secure_renegotiate_fallback() ->
+ [{doc,"Test that we can set secure_renegotiate to false that is "
+ "fallback option, we however do not have a insecure server to test against!"}].
+client_secure_renegotiate_fallback(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{secure_renegotiate, 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, [Data]}},
+ {options, [{reuse_sessions, false},
+ {secure_renegotiate, false}| ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
server_renegotiate() ->
@@ -3038,10 +3185,10 @@ der_input(Config) when is_list(Config) ->
Size = ets:info(CADb, size),
- SeverVerifyOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ SeverVerifyOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
{ServerCert, ServerKey, ServerCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
SeverVerifyOpts]),
- ClientVerifyOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ClientVerifyOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientCert, ClientKey, ClientCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
ClientVerifyOpts]),
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true},
@@ -3124,7 +3271,7 @@ no_reuses_session_server_restart_new_cert(Config) when is_list(Config) ->
ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
{from, self()},
{mfa, {ssl_test_lib, no_result, []}},
- {options, DsaServerOpts}]),
+ {options, [{reuseaddr, true} | DsaServerOpts]}]),
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
@@ -3185,7 +3332,7 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
{from, self()},
{mfa, {ssl_test_lib, no_result, []}},
- {options, NewServerOpts1}]),
+ {options, [{reuseaddr, true} | NewServerOpts1]}]),
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
@@ -3202,18 +3349,25 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
defaults(Config) when is_list(Config)->
- [_,
- {supported, Supported},
- {available, Available}]
- = ssl:versions(),
- true = lists:member(sslv3, Available),
- false = lists:member(sslv3, Supported),
+ Versions = ssl:versions(),
+ true = lists:member(sslv3, proplists:get_value(available, Versions)),
+ false = lists:member(sslv3, proplists:get_value(supported, Versions)),
+ true = lists:member('tlsv1', proplists:get_value(available, Versions)),
+ true = lists:member('tlsv1', proplists:get_value(supported, Versions)),
+ true = lists:member('tlsv1.1', proplists:get_value(available, Versions)),
+ true = lists:member('tlsv1.1', proplists:get_value(supported, Versions)),
+ true = lists:member('tlsv1.2', proplists:get_value(available, Versions)),
+ true = lists:member('tlsv1.2', proplists:get_value(supported, Versions)),
false = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites()),
true = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites(all)),
false = lists:member({rsa,des_cbc,sha}, ssl:cipher_suites()),
true = lists:member({rsa,des_cbc,sha}, ssl:cipher_suites(all)),
false = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites()),
- true = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites(all)).
+ true = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites(all)),
+ true = lists:member('dtlsv1.2', proplists:get_value(available_dtls, Versions)),
+ true = lists:member('dtlsv1', proplists:get_value(available_dtls, Versions)),
+ true = lists:member('dtlsv1.2', proplists:get_value(supported_dtls, Versions)),
+ true = lists:member('dtlsv1', proplists:get_value(supported_dtls, Versions)).
%%--------------------------------------------------------------------
reuseaddr() ->
@@ -3299,16 +3453,50 @@ tls_tcp_reuseaddr(Config) when is_list(Config) ->
honor_server_cipher_order() ->
[{doc,"Test API honor server cipher order."}].
honor_server_cipher_order(Config) when is_list(Config) ->
- ClientCiphers = [{rsa, aes_128_cbc, sha}, {rsa, aes_256_cbc, sha}],
- ServerCiphers = [{rsa, aes_256_cbc, sha}, {rsa, aes_128_cbc, sha}],
-honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, {rsa, aes_256_cbc, sha}).
+ ClientCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac => sha,
+ prf => default_prf}],
+ ServerCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac =>sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}],
+ honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac => sha,
+ prf => default_prf}).
honor_client_cipher_order() ->
[{doc,"Test API honor server cipher order."}].
honor_client_cipher_order(Config) when is_list(Config) ->
- ClientCiphers = [{rsa, aes_128_cbc, sha}, {rsa, aes_256_cbc, sha}],
- ServerCiphers = [{rsa, aes_256_cbc, sha}, {rsa, aes_128_cbc, sha}],
-honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, {rsa, aes_128_cbc, sha}).
+ ClientCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac => sha,
+ prf => default_prf}],
+ ServerCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac =>sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}],
+honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}).
honor_cipher_order(Config, Honor, ServerCiphers, ClientCiphers, Expected) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
@@ -3364,7 +3552,7 @@ tls_ciphersuite_vs_version(Config) when is_list(Config) ->
>>),
{ok, <<22, RecMajor:8, RecMinor:8, _RecLen:16, 2, HelloLen:24>>} = gen_tcp:recv(Socket, 9, 10000),
{ok, <<HelloBin:HelloLen/binary>>} = gen_tcp:recv(Socket, HelloLen, 5000),
- ServerHello = tls_handshake:decode_handshake({RecMajor, RecMinor}, 2, HelloBin, false),
+ ServerHello = tls_handshake:decode_handshake({RecMajor, RecMinor}, 2, HelloBin),
case ServerHello of
#server_hello{server_version = {3,0}, cipher_suite = <<0,57>>} ->
ok;
@@ -3418,14 +3606,14 @@ no_common_signature_algs(Config) when is_list(Config) ->
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, [{signature_algs, [{sha384, rsa}]}
- | ClientOpts]}]),
+ {host, Hostname},
+ {from, self()},
+ {options, [{signature_algs, [{sha384, rsa}]}
+ | ClientOpts]}]),
ssl_test_lib:check_result(Server, {error, {tls_alert, "insufficient security"}},
- Client, {error, {tls_alert, "insufficient security"}}).
-
+ Client, {error, {tls_alert, "insufficient security"}}).
+
%%--------------------------------------------------------------------
tls_dont_crash_on_handshake_garbage() ->
@@ -3487,7 +3675,7 @@ hibernate(Config) ->
{mfa, {ssl_test_lib, send_recv_result_active, []}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
- {Client, #sslsocket{pid=Pid}} = ssl_test_lib:start_client([return_socket,
+ {Client, #sslsocket{pid=[Pid|_]}} = ssl_test_lib:start_client([return_socket,
{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -3530,7 +3718,7 @@ hibernate_right_away(Config) ->
Server1 = ssl_test_lib:start_server(StartServerOpts),
Port1 = ssl_test_lib:inet_port(Server1),
- {Client1, #sslsocket{pid = Pid1}} = ssl_test_lib:start_client(StartClientOpts ++
+ {Client1, #sslsocket{pid = [Pid1|_]}} = ssl_test_lib:start_client(StartClientOpts ++
[{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]),
ssl_test_lib:check_result(Server1, ok, Client1, ok),
@@ -3542,7 +3730,7 @@ hibernate_right_away(Config) ->
Server2 = ssl_test_lib:start_server(StartServerOpts),
Port2 = ssl_test_lib:inet_port(Server2),
- {Client2, #sslsocket{pid = Pid2}} = ssl_test_lib:start_client(StartClientOpts ++
+ {Client2, #sslsocket{pid = [Pid2|_]}} = ssl_test_lib:start_client(StartClientOpts ++
[{port, Port2}, {options, [{hibernate_after, 1}|ClientOpts]}]),
ssl_test_lib:check_result(Server2, ok, Client2, ok),
@@ -3778,13 +3966,13 @@ tls_tcp_error_propagation_in_active_mode(Config) when is_list(Config) ->
{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}]),
-
+ {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),
@@ -3817,6 +4005,86 @@ recv_error_handling(Config) when is_list(Config) ->
ssl:close(SslSocket),
ssl_test_lib:check_result(Server, ok).
+
+
+%%--------------------------------------------------------------------
+call_in_error_state() ->
+ [{doc,"Special case of call error handling"}].
+call_in_error_state(Config) when is_list(Config) ->
+ ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
+ Pid = spawn_link(?MODULE, run_error_server, [[self() | ServerOpts]]),
+ receive
+ {Pid, Port} ->
+ spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
+ end,
+ receive
+ {error, closed} ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end.
+
+run_client_error([Port, Opts]) ->
+ ssl:connect("localhost", Port, Opts).
+
+run_error_server([ Pid | Opts]) ->
+ {ok, Listen} = ssl:listen(0, Opts),
+ {ok,{_, Port}} = ssl:sockname(Listen),
+ Pid ! {self(), Port},
+ {ok, Socket} = ssl:transport_accept(Listen),
+ Pid ! ssl:controlling_process(Socket, self()).
+
+%%--------------------------------------------------------------------
+
+close_in_error_state() ->
+ [{doc,"Special case of closing socket in error state"}].
+close_in_error_state(Config) when is_list(Config) ->
+ ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+ ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ _ = spawn_link(?MODULE, run_error_server_close, [[self() | ServerOpts]]),
+ receive
+ {_Pid, Port} ->
+ spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
+ end,
+ receive
+ ok ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end.
+%%--------------------------------------------------------------------
+abuse_transport_accept_socket() ->
+ [{doc,"Only ssl:handshake is allowed for transport_accept:sockets"}].
+abuse_transport_accept_socket(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_transport_abuse_socket([{node, ServerNode},
+ {port, 0},
+ {from, self()},
+ {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, no_result, []}},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+run_error_server_close([Pid | Opts]) ->
+ {ok, Listen} = ssl:listen(0, Opts),
+ {ok,{_, Port}} = ssl:sockname(Listen),
+ Pid ! {self(), Port},
+ {ok, Socket} = ssl:transport_accept(Listen),
+ Pid ! ssl:close(Socket).
+
%%--------------------------------------------------------------------
rizzo() ->
@@ -4045,6 +4313,7 @@ unordered_protocol_versions_server(Config) when is_list(Config) ->
{from, self()},
{mfa, {?MODULE, protocol_info_result, []}},
{options, ClientOpts}]),
+
ServerMsg = ClientMsg = {ok,'tlsv1.2'},
ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
@@ -4069,6 +4338,7 @@ unordered_protocol_versions_client(Config) when is_list(Config) ->
{from, self()},
{mfa, {?MODULE, protocol_info_result, []}},
{options, [{versions, ['tlsv1.1', 'tlsv1.2']} | ClientOpts]}]),
+
ServerMsg = ClientMsg = {ok, 'tlsv1.2'},
ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
@@ -4398,6 +4668,7 @@ renegotiate_rejected(Socket) ->
ok;
%% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast
{ssl, Socket, "H"} ->
+
receive
{ssl, Socket, "ello world"} ->
ok
@@ -4785,19 +5056,24 @@ run_suites(Ciphers, Config, Type) ->
[{ciphers, Ciphers} |
ssl_test_lib:ssl_options(server_ecdsa_opts, Config)]}
end,
- ct:pal("ssl_test_lib:filter_suites(~p ~p) -> ~p ", [Ciphers, Version, ssl_test_lib:filter_suites(Ciphers, Version)]),
- Result = lists:map(fun(Cipher) ->
- cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end,
- ssl_test_lib:filter_suites(Ciphers, Version)),
- case lists:flatten(Result) of
- [] ->
- ok;
- Error ->
- ct:log("Cipher suite errors: ~p~n", [Error]),
- ct:fail(cipher_suite_failed_see_test_case_log)
- end.
+ Suites = ssl_test_lib:filter_suites(Ciphers, Version),
+ ct:pal("ssl_test_lib:filter_suites(~p ~p) -> ~p ", [Ciphers, Version, Suites]),
+ Results0 = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end,
+ ssl_test_lib:filter_suites(Ciphers, Version)),
+ Results = lists:flatten(Results0),
+ true = length(Results) == length(Suites),
+ check_cipher_result(Results).
+
+check_cipher_result([]) ->
+ ok;
+check_cipher_result([ok | Rest]) ->
+ check_cipher_result(Rest);
+check_cipher_result([_ |_] = Error) ->
+ ct:fail(Error).
+
erlang_cipher_suite(Suite) when is_list(Suite)->
- ssl_cipher:erl_suite_definition(ssl_cipher:openssl_suite(Suite));
+ ssl_cipher_format:suite_definition(ssl_cipher_format:openssl_suite(Suite));
erlang_cipher_suite(Suite) ->
Suite.
@@ -4832,7 +5108,7 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
case Result of
ok ->
- [];
+ [ok];
Error ->
[{ErlangCipherSuite, Error}]
end.
@@ -4849,8 +5125,8 @@ connection_information_result(Socket) ->
end.
connection_info_result(Socket) ->
- {ok, Info} = ssl:connection_information(Socket, [protocol, cipher_suite]),
- {ok, {proplists:get_value(protocol, Info), proplists:get_value(cipher_suite, Info)}}.
+ {ok, Info} = ssl:connection_information(Socket, [protocol, selected_cipher_suite]),
+ {ok, {proplists:get_value(protocol, Info), proplists:get_value(selected_cipher_suite, Info)}}.
protocol_info_result(Socket) ->
{ok, [{protocol, PVersion}]} = ssl:connection_information(Socket, [protocol]),
@@ -4898,8 +5174,14 @@ tls_downgrade_result(Socket) ->
tls_close(Socket) ->
ok = ssl_test_lib:send_recv_result(Socket),
- ok = ssl:close(Socket, 5000).
-
+ case ssl:close(Socket, 5000) of
+ ok ->
+ ok;
+ {error, closed} ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end.
%% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast
treashold(N, {3,0}) ->
@@ -4978,6 +5260,7 @@ try_recv_active_once(Socket) ->
{error, einval} = ssl:recv(Socket, 11),
ok.
+
wait_for_send(Socket) ->
%% Make sure TLS process processed send message event
_ = ssl:connection_information(Socket).
diff --git a/lib/ssl/test/ssl_bench.spec b/lib/ssl/test/ssl_bench.spec
index d2f75b4203..8b746c5ca9 100644
--- a/lib/ssl/test/ssl_bench.spec
+++ b/lib/ssl/test/ssl_bench.spec
@@ -1 +1 @@
-{suites,"../ssl_test",[ssl_bench_SUITE]}.
+{suites,"../ssl_test",[ssl_bench_SUITE, ssl_dist_bench_SUITE]}.
diff --git a/lib/ssl/test/ssl_bench_SUITE.erl b/lib/ssl/test/ssl_bench_SUITE.erl
index ae2928b1c3..13097b08b6 100644
--- a/lib/ssl/test/ssl_bench_SUITE.erl
+++ b/lib/ssl/test/ssl_bench_SUITE.erl
@@ -40,11 +40,12 @@ end_per_group(_GroupName, _Config) ->
ok.
init_per_suite(Config) ->
- try
- Server = setup(ssl, node()),
- [{server_node, Server}|Config]
- catch _:_ ->
- {skipped, "Benchmark machines only"}
+ case node() of
+ nonode@nohost ->
+ {skipped, "Node not distributed"};
+ _ ->
+ ssl_test_lib:clean_start(),
+ [{server_node, ssl_bench_test_lib:setup(perf_server)}|Config]
end.
end_per_suite(_Config) ->
@@ -132,10 +133,10 @@ bypass_pem_cache(_Config) ->
ssl() ->
- test(ssl, ?COUNT, node()).
+ test(ssl, ?COUNT).
-test(Type, Count, Host) ->
- Server = setup(Type, Host),
+test(Type, Count) ->
+ Server = ssl_bench_test_lib:setup(perf_server),
(do_test(Type, setup_connection, Count * 20, 1, Server)),
(do_test(Type, setup_connection, Count, 100, Server)),
(do_test(Type, payload, Count*300, 10, Server)),
@@ -294,47 +295,6 @@ msg() ->
"asdlkjsafsdfoierwlejsdlkfjsdf">>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-setup(_Type, nonode@nohost) ->
- exit(dist_not_enabled);
-setup(Type, _This) ->
- Host = case os:getenv(?remote_host) of
- false ->
- {ok, This} = inet:gethostname(),
- This;
- RemHost ->
- RemHost
- end,
- Node = list_to_atom("perf_server@" ++ Host),
- SlaveArgs = case init:get_argument(pa) of
- {ok, PaPaths} ->
- lists:append([" -pa " ++ P || [P] <- PaPaths]);
- _ -> []
- end,
- %% io:format("Slave args: ~p~n",[SlaveArgs]),
- Prog =
- case os:find_executable("erl") of
- false -> "erl";
- P -> P
- end,
- io:format("Prog = ~p~n", [Prog]),
-
- case net_adm:ping(Node) of
- pong -> ok;
- pang ->
- {ok, Node} = slave:start(Host, perf_server, SlaveArgs, no_link, Prog)
- end,
- Path = code:get_path(),
- true = rpc:call(Node, code, set_path, [Path]),
- ok = rpc:call(Node, ?MODULE, setup_server, [Type, node()]),
- io:format("Client (~p) using ~s~n",[node(), code:which(ssl)]),
- (Node =:= node()) andalso restrict_schedulers(client),
- Node.
-
-setup_server(_Type, ClientNode) ->
- (ClientNode =:= node()) andalso restrict_schedulers(server),
- io:format("Server (~p) using ~s~n",[node(), code:which(ssl)]),
- ok.
-
ensure_all_started(App, Ack) ->
case application:start(App) of
@@ -358,13 +318,6 @@ setup_server_init(Type, Tc, Loop, PC) ->
unlink(Pid),
Res.
-restrict_schedulers(Type) ->
- %% We expect this to run on 8 core machine
- Extra0 = 1,
- Extra = if (Type =:= server) -> -Extra0; true -> Extra0 end,
- Scheds = erlang:system_info(schedulers),
- erlang:system_flag(schedulers_online, (Scheds div 2) + Extra).
-
tc(Fun, Mod, Line) ->
case timer:tc(Fun) of
{_,{'EXIT',Reason}} ->
diff --git a/lib/ssl/test/ssl_bench_test_lib.erl b/lib/ssl/test/ssl_bench_test_lib.erl
new file mode 100644
index 0000000000..e5cbb911bd
--- /dev/null
+++ b/lib/ssl/test/ssl_bench_test_lib.erl
@@ -0,0 +1,75 @@
+%%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssl_bench_test_lib).
+
+%% API
+-export([setup/1]).
+
+%% Internal exports
+-export([setup_server/1]).
+
+-define(remote_host, "NETMARKS_REMOTE_HOST").
+
+setup(Name) ->
+ Host = case os:getenv(?remote_host) of
+ false ->
+ {ok, This} = inet:gethostname(),
+ This;
+ RemHost ->
+ RemHost
+ end,
+ Node = list_to_atom(atom_to_list(Name) ++ "@" ++ Host),
+ SlaveArgs = case init:get_argument(pa) of
+ {ok, PaPaths} ->
+ lists:append([" -pa " ++ P || [P] <- PaPaths]);
+ _ -> []
+ end,
+ %% io:format("Slave args: ~p~n",[SlaveArgs]),
+ Prog =
+ case os:find_executable("erl") of
+ false -> "erl";
+ P -> P
+ end,
+ io:format("Prog = ~p~n", [Prog]),
+
+ case net_adm:ping(Node) of
+ pong -> ok;
+ pang ->
+ {ok, Node} =
+ slave:start(Host, Name, SlaveArgs, no_link, Prog)
+ end,
+ Path = code:get_path(),
+ true = rpc:call(Node, code, set_path, [Path]),
+ ok = rpc:call(Node, ?MODULE, setup_server, [node()]),
+ io:format("Client (~p) using ~s~n",[node(), code:which(ssl)]),
+ (Node =:= node()) andalso restrict_schedulers(client),
+ Node.
+
+setup_server(ClientNode) ->
+ (ClientNode =:= node()) andalso restrict_schedulers(server),
+ io:format("Server (~p) using ~s~n",[node(), code:which(ssl)]),
+ ok.
+
+restrict_schedulers(Type) ->
+ %% We expect this to run on 8 core machine
+ Extra0 = 1,
+ Extra = if (Type =:= server) -> -Extra0; true -> Extra0 end,
+ Scheds = erlang:system_info(schedulers),
+ erlang:system_flag(schedulers_online, (Scheds div 2) + Extra).
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 1de4c89d7f..588ca153a9 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -87,7 +87,10 @@ tests() ->
extended_key_usage_verify_server,
critical_extension_verify_client,
critical_extension_verify_server,
- critical_extension_verify_none].
+ critical_extension_verify_none,
+ customize_hostname_check,
+ incomplete_chain
+ ].
error_handling_tests()->
[client_with_cert_cipher_suites_handshake,
@@ -617,8 +620,8 @@ cert_expired(Config) when is_list(Config) ->
{from, self()},
{options, [{verify, verify_peer}, {active, Active} | ClientOpts]}]),
- tcp_delivery_workaround(Server, {error, {tls_alert, "certificate expired"}},
- Client, {error, {tls_alert, "certificate expired"}}).
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "certificate expired"}},
+ Client, {error, {tls_alert, "certificate expired"}}).
two_digits_str(N) when N < 10 ->
lists:flatten(io_lib:format("0~p", [N]));
@@ -726,8 +729,8 @@ critical_extension_verify_server(Config) when is_list(Config) ->
%% This certificate has a critical extension that we don't
%% understand. Therefore, verification should fail.
- tcp_delivery_workaround(Server, {error, {tls_alert, "unsupported certificate"}},
- Client, {error, {tls_alert, "unsupported certificate"}}),
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "unsupported certificate"}},
+ Client, {error, {tls_alert, "unsupported certificate"}}),
ssl_test_lib:close(Server).
%%--------------------------------------------------------------------
@@ -906,8 +909,8 @@ invalid_signature_server(Config) when is_list(Config) ->
{from, self()},
{options, [{verify, verify_peer} | ClientOpts]}]),
- tcp_delivery_workaround(Server, {error, {tls_alert, "unknown ca"}},
- Client, {error, {tls_alert, "unknown ca"}}).
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "unknown ca"}},
+ Client, {error, {tls_alert, "unknown ca"}}).
%%--------------------------------------------------------------------
@@ -943,8 +946,8 @@ invalid_signature_client(Config) when is_list(Config) ->
{from, self()},
{options, NewClientOpts}]),
- tcp_delivery_workaround(Server, {error, {tls_alert, "unknown ca"}},
- Client, {error, {tls_alert, "unknown ca"}}).
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "unknown ca"}},
+ Client, {error, {tls_alert, "unknown ca"}}).
%%--------------------------------------------------------------------
@@ -1145,44 +1148,91 @@ unknown_server_ca_accept_backwardscompatibility(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+
+customize_hostname_check() ->
+ [{doc,"Test option customize_hostname_check."}].
+customize_hostname_check(Config) when is_list(Config) ->
+ Ext = [#'Extension'{extnID = ?'id-ce-subjectAltName',
+ extnValue = [{dNSName, "*.example.org"}],
+ critical = false}
+ ],
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],
+ [],
+ [{extensions, Ext}]
+ ]}],
+ Config, "https_hostname_convention"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, 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, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ CustomFun = public_key:pkix_verify_hostname_match_fun(https),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options,
+ [{server_name_indication, "other.example.org"},
+ {customize_hostname_check,
+ [{match_fun, CustomFun}]} | ClientOpts]
+ }]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+
+ Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}
+ ]),
+ ssl_test_lib:check_result(Client1, {error, {tls_alert, "handshake failure"}},
+ Server, {error, {tls_alert, "handshake failure"}}),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+incomplete_chain() ->
+ [{doc,"Test option verify_peer"}].
+incomplete_chain(Config) when is_list(Config) ->
+ DefConf = ssl_test_lib:default_cert_chain_conf(),
+ CertChainConf = ssl_test_lib:gen_conf(rsa, rsa, DefConf, DefConf),
+ #{server_config := ServerConf,
+ client_config := ClientConf} = public_key:pkix_test_data(CertChainConf),
+ [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},
+ {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 ------------------------------------------------
%%--------------------------------------------------------------------
-tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) ->
- receive
- {Server, ServerMsg} ->
- client_msg(Client, ClientMsg);
- {Client, ClientMsg} ->
- server_msg(Server, ServerMsg);
- {Client, {error,closed}} ->
- server_msg(Server, ServerMsg);
- {Server, {error,closed}} ->
- client_msg(Client, ClientMsg)
- end.
-
-client_msg(Client, ClientMsg) ->
- receive
- {Client, ClientMsg} ->
- ok;
- {Client, {error,closed}} ->
- ct:log("client got close"),
- ok;
- {Client, {error, Reason}} ->
- ct:log("client got econnaborted: ~p", [Reason]),
- ok;
- Unexpected ->
- ct:fail(Unexpected)
- end.
-server_msg(Server, ServerMsg) ->
- receive
- {Server, ServerMsg} ->
- ok;
- {Server, {error,closed}} ->
- ct:log("server got close"),
- ok;
- {Server, {error, Reason}} ->
- ct:log("server got econnaborted: ~p", [Reason]),
- ok;
- Unexpected ->
- ct:fail(Unexpected)
- end.
diff --git a/lib/ssl/test/ssl_crl_SUITE.erl b/lib/ssl/test/ssl_crl_SUITE.erl
index 668c76e38d..23c5eaf84d 100644
--- a/lib/ssl/test/ssl_crl_SUITE.erl
+++ b/lib/ssl/test/ssl_crl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 8740e8c8f0..003e1fc448 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,20 +22,21 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include("ssl_dist_test_lib.hrl").
%% Note: This directive should only be used in test suites.
--compile(export_all).
+-compile([export_all, nowarn_export_all]).
-define(DEFAULT_TIMETRAP_SECS, 240).
-define(AWAIT_SSL_NODE_UP_TIMEOUT, 30000).
--record(node_handle,
- {connection_handler,
- socket,
- name,
- nodename}
- ).
+-import(ssl_dist_test_lib,
+ [tstsrvr_format/2, send_to_tstcntrl/1,
+ apply_on_ssl_node/4, apply_on_ssl_node/2,
+ stop_ssl_node/1]).
+start_ssl_node_name(Name, Args) ->
+ ssl_dist_test_lib:start_ssl_node(Name, Args).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
@@ -140,11 +141,14 @@ basic_test(NH1, NH2, _) ->
apply_on_ssl_node(
NH1,
fun () ->
- tstsrvr_format("Hi from ~p!~n", [node()]),
- send_to_tstcntrl({Ref, self()}),
+ tstsrvr_format(
+ "Hi from ~p!~n", [node()]),
+ send_to_tstcntrl(
+ {Ref, self()}),
receive
{From, ping} ->
- tstsrvr_format("Received ping ~p!~n", [node()]),
+ tstsrvr_format(
+ "Received ping ~p!~n", [node()]),
From ! {self(), pong}
end
end)
@@ -154,7 +158,8 @@ basic_test(NH1, NH2, _) ->
ok = apply_on_ssl_node(
NH2,
fun () ->
- tstsrvr_format("Hi from ~p!~n", [node()]),
+ tstsrvr_format(
+ "Hi from ~p!~n", [node()]),
SslPid ! {self(), ping},
receive
{SslPid, pong} ->
@@ -183,7 +188,8 @@ payload_test(NH1, NH2, _) ->
apply_on_ssl_node(
NH1,
fun () ->
- send_to_tstcntrl({Ref, self()}),
+ send_to_tstcntrl(
+ {Ref, self()}),
receive
{From, Msg} ->
From ! {self(), Msg}
@@ -616,12 +622,6 @@ gen_dist_test(Test, Config) ->
%% ssl_node side api
%%
-tstsrvr_format(Fmt, ArgList) ->
- send_to_tstsrvr({format, Fmt, ArgList}).
-
-send_to_tstcntrl(Message) ->
- send_to_tstsrvr({message, Message}).
-
try_setting_priority(TestFun, Config) ->
Prio = 1,
case gen_udp:open(0, [{priority,Prio}]) of
@@ -653,44 +653,6 @@ inet_ports() ->
%% test_server side api
%%
-apply_on_ssl_node(Node, M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
- Ref = make_ref(),
- send_to_ssl_node(Node, {apply, self(), Ref, M, F, A}),
- receive
- {Ref, Result} ->
- Result
- end.
-
-apply_on_ssl_node(Node, Fun) when is_function(Fun, 0) ->
- Ref = make_ref(),
- send_to_ssl_node(Node, {apply, self(), Ref, Fun}),
- receive
- {Ref, Result} ->
- Result
- end.
-
-stop_ssl_node(#node_handle{connection_handler = Handler,
- socket = Socket,
- name = Name}) ->
- ?t:format("Trying to stop ssl node ~s.~n", [Name]),
- Mon = erlang:monitor(process, Handler),
- unlink(Handler),
- case gen_tcp:send(Socket, term_to_binary(stop)) of
- ok ->
- receive
- {'DOWN', Mon, process, Handler, Reason} ->
- case Reason of
- normal ->
- ok;
- _ ->
- ct:pal("Down ~p ~n", [Reason])
- end
- end;
- Error ->
- erlang:demonitor(Mon, [flush]),
- ct:pal("Warning ~p ~n", [Error])
- end.
-
start_ssl_node(Config) ->
start_ssl_node(Config, "").
@@ -698,29 +660,8 @@ start_ssl_node(Config, XArgs) ->
Name = mk_node_name(Config),
SSL = proplists:get_value(ssl_opts, Config),
SSLDistOpts = setup_dist_opts(Config),
- start_ssl_node_raw(Name, SSL ++ " " ++ SSLDistOpts ++ XArgs).
-
-start_ssl_node_raw(Name, Args) ->
- {ok, LSock} = gen_tcp:listen(0,
- [binary, {packet, 4}, {active, false}]),
- {ok, ListenPort} = inet:port(LSock),
- CmdLine = mk_node_cmdline(ListenPort, Name, Args),
- ?t:format("Attempting to start ssl node ~ts: ~ts~n", [Name, CmdLine]),
- case open_port({spawn, CmdLine}, []) of
- Port when is_port(Port) ->
- unlink(Port),
- erlang:port_close(Port),
- case await_ssl_node_up(Name, LSock) of
- #node_handle{} = NodeHandle ->
- ?t:format("Ssl node ~s started.~n", [Name]),
- NodeName = list_to_atom(Name ++ "@" ++ host_name()),
- NodeHandle#node_handle{nodename = NodeName};
- Error ->
- exit({failed_to_start_node, Name, Error})
- end;
- Error ->
- exit({failed_to_start_node, Name, Error})
- end.
+ start_ssl_node_name(
+ Name, SSL ++ " " ++ SSLDistOpts ++ XArgs).
cache_crls_on_ssl_nodes(PrivDir, CANames, NHs) ->
[begin
@@ -739,11 +680,6 @@ cache_crls_on_ssl_nodes(PrivDir, CANames, NHs) ->
%% command line creation
%%
-host_name() ->
- [$@ | Host] = lists:dropwhile(fun ($@) -> false; (_) -> true end,
- atom_to_list(node())),
- Host.
-
mk_node_name(Config) ->
N = erlang:unique_integer([positive]),
Case = proplists:get_value(testcase, Config),
@@ -753,225 +689,6 @@ mk_node_name(Config) ->
++ "_"
++ integer_to_list(N).
-mk_node_cmdline(ListenPort, Name, Args) ->
- Static = "-detached -noinput",
- Pa = filename:dirname(code:which(?MODULE)),
- Prog = case catch init:get_argument(progname) of
- {ok,[[P]]} -> P;
- _ -> exit(no_progname_argument_found)
- end,
- NameSw = case net_kernel:longnames() of
- false -> "-sname ";
- _ -> "-name "
- end,
- {ok, Pwd} = file:get_cwd(),
- "\"" ++ Prog ++ "\" "
- ++ Static ++ " "
- ++ NameSw ++ " " ++ Name ++ " "
- ++ "-pa " ++ Pa ++ " "
- ++ "-run application start crypto -run application start public_key "
- ++ "-eval 'net_kernel:verbose(1)' "
- ++ "-run " ++ atom_to_list(?MODULE) ++ " cnct2tstsrvr "
- ++ host_name() ++ " "
- ++ integer_to_list(ListenPort) ++ " "
- ++ Args ++ " "
- ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ Name ++ " "
- ++ "-kernel error_logger \"{file,\\\"" ++ Pwd ++ "/error_log." ++ Name ++ "\\\"}\" "
- ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
-
-%%
-%% Connection handler test_server side
-%%
-
-await_ssl_node_up(Name, LSock) ->
- case gen_tcp:accept(LSock, ?AWAIT_SSL_NODE_UP_TIMEOUT) of
- timeout ->
- gen_tcp:close(LSock),
- ?t:format("Timeout waiting for ssl node ~s to come up~n",
- [Name]),
- timeout;
- {ok, Socket} ->
- gen_tcp:close(LSock),
- case gen_tcp:recv(Socket, 0) of
- {ok, Bin} ->
- check_ssl_node_up(Socket, Name, Bin);
- {error, closed} ->
- gen_tcp:close(Socket),
- exit({lost_connection_with_ssl_node_before_up, Name})
- end;
- {error, Error} ->
- gen_tcp:close(LSock),
- exit({accept_failed, Error})
- end.
-
-check_ssl_node_up(Socket, Name, Bin) ->
- case catch binary_to_term(Bin) of
- {'EXIT', _} ->
- gen_tcp:close(Socket),
- exit({bad_data_received_from_ssl_node, Name, Bin});
- {ssl_node_up, NodeName} ->
- case list_to_atom(Name++"@"++host_name()) of
- NodeName ->
- Parent = self(),
- Go = make_ref(),
- %% Spawn connection handler on test server side
- Pid = spawn_link(
- fun () ->
- receive Go -> ok end,
- tstsrvr_con_loop(Name, Socket, Parent)
- end),
- ok = gen_tcp:controlling_process(Socket, Pid),
- Pid ! Go,
- #node_handle{connection_handler = Pid,
- socket = Socket,
- name = Name};
- _ ->
- exit({unexpected_ssl_node_connected, NodeName})
- end;
- Msg ->
- exit({unexpected_msg_instead_of_ssl_node_up, Name, Msg})
- end.
-
-send_to_ssl_node(#node_handle{connection_handler = Hndlr}, Term) ->
- Hndlr ! {relay_to_ssl_node, term_to_binary(Term)},
- ok.
-
-tstsrvr_con_loop(Name, Socket, Parent) ->
- inet:setopts(Socket,[{active,once}]),
- receive
- {relay_to_ssl_node, Data} when is_binary(Data) ->
- case gen_tcp:send(Socket, Data) of
- ok ->
- ok;
- _Error ->
- gen_tcp:close(Socket),
- exit({failed_to_relay_data_to_ssl_node, Name, Data})
- end;
- {tcp, Socket, Bin} ->
- case catch binary_to_term(Bin) of
- {'EXIT', _} ->
- gen_tcp:close(Socket),
- exit({bad_data_received_from_ssl_node, Name, Bin});
- {format, FmtStr, ArgList} ->
- ?t:format(FmtStr, ArgList);
- {message, Msg} ->
- ?t:format("Got message ~p", [Msg]),
- Parent ! Msg;
- {apply_res, To, Ref, Res} ->
- To ! {Ref, Res};
- bye ->
- ?t:format("Ssl node ~s stopped.~n", [Name]),
- gen_tcp:close(Socket),
- exit(normal);
- Unknown ->
- exit({unexpected_message_from_ssl_node, Name, Unknown})
- end;
- {tcp_closed, Socket} ->
- gen_tcp:close(Socket),
- exit({lost_connection_with_ssl_node, Name})
- end,
- tstsrvr_con_loop(Name, Socket, Parent).
-
-%%
-%% Connection handler ssl_node side
-%%
-
-% cnct2tstsrvr() is called via command line arg -run ...
-cnct2tstsrvr([Host, Port]) when is_list(Host), is_list(Port) ->
- %% Spawn connection handler on ssl node side
- ConnHandler
- = spawn(fun () ->
- case catch gen_tcp:connect(Host,
- list_to_integer(Port),
- [binary,
- {packet, 4},
- {active, false}]) of
- {ok, Socket} ->
- notify_ssl_node_up(Socket),
- ets:new(test_server_info,
- [set,
- public,
- named_table,
- {keypos, 1}]),
- ets:insert(test_server_info,
- {test_server_handler, self()}),
- ssl_node_con_loop(Socket);
- Error ->
- halt("Failed to connect to test server " ++
- lists:flatten(io_lib:format("Host:~p ~n Port:~p~n Error:~p~n",
- [Host, Port, Error])))
- end
- end),
- spawn(fun () ->
- Mon = erlang:monitor(process, ConnHandler),
- receive
- {'DOWN', Mon, process, ConnHandler, Reason} ->
- receive after 1000 -> ok end,
- halt("test server connection handler terminated: " ++
- lists:flatten(io_lib:format("~p", [Reason])))
- end
- end).
-
-notify_ssl_node_up(Socket) ->
- case catch gen_tcp:send(Socket,
- term_to_binary({ssl_node_up, node()})) of
- ok -> ok;
- _ -> halt("Failed to notify test server that I'm up")
- end.
-
-send_to_tstsrvr(Term) ->
- case catch ets:lookup_element(test_server_info, test_server_handler, 2) of
- Hndlr when is_pid(Hndlr) ->
- Hndlr ! {relay_to_test_server, term_to_binary(Term)}, ok;
- _ ->
- receive after 200 -> ok end,
- send_to_tstsrvr(Term)
- end.
-
-ssl_node_con_loop(Socket) ->
- inet:setopts(Socket,[{active,once}]),
- receive
- {relay_to_test_server, Data} when is_binary(Data) ->
- case gen_tcp:send(Socket, Data) of
- ok ->
- ok;
- _Error ->
- gen_tcp:close(Socket),
- halt("Failed to relay data to test server")
- end;
- {tcp, Socket, Bin} ->
- case catch binary_to_term(Bin) of
- {'EXIT', _} ->
- gen_tcp:close(Socket),
- halt("test server sent me bad data");
- {apply, From, Ref, M, F, A} ->
- spawn_link(
- fun () ->
- send_to_tstsrvr({apply_res,
- From,
- Ref,
- (catch apply(M, F, A))})
- end);
- {apply, From, Ref, Fun} ->
- spawn_link(fun () ->
- send_to_tstsrvr({apply_res,
- From,
- Ref,
- (catch Fun())})
- end);
- stop ->
- gen_tcp:send(Socket, term_to_binary(bye)),
- gen_tcp:close(Socket),
- init:stop(),
- receive after infinity -> ok end;
- _Unknown ->
- halt("test server sent me an unexpected message")
- end;
- {tcp_closed, Socket} ->
- halt("Lost connection to test server")
- end,
- ssl_node_con_loop(Socket).
-
%%
%% Setup ssl dist info
%%
@@ -1007,7 +724,8 @@ setup_certs(Config) ->
ok = file:make_dir(NodeDir),
ok = file:make_dir(RGenDir),
make_randfile(RGenDir),
- {ok, _} = make_certs:all(RGenDir, NodeDir),
+ [Hostname|_] = string:split(net_adm:localhost(), ".", all),
+ {ok, _} = make_certs:all(RGenDir, NodeDir, [{hostname,Hostname}]),
SDir = filename:join([NodeDir, "server"]),
SC = filename:join([SDir, "cert.pem"]),
SK = filename:join([SDir, "key.pem"]),
diff --git a/lib/ssl/test/ssl_dist_bench_SUITE.erl b/lib/ssl/test/ssl_dist_bench_SUITE.erl
new file mode 100644
index 0000000000..3c7904cf24
--- /dev/null
+++ b/lib/ssl/test/ssl_dist_bench_SUITE.erl
@@ -0,0 +1,526 @@
+%%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssl_dist_bench_SUITE).
+
+-include_lib("common_test/include/ct_event.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%% CT meta
+-export([suite/0, all/0, groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2, end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export(
+ [setup/1,
+ roundtrip/1,
+ throughput_1024/1,
+ throughput_4096/1,
+ throughput_16384/1,
+ throughput_65536/1,
+ throughput_262144/1,
+ throughput_1048576/1]).
+
+%% Debug
+-export([payload/1]).
+
+%%%-------------------------------------------------------------------
+
+suite() -> [{ct_hooks, [{ts_install_cth, [{nodenames, 2}]}]}].
+
+all() -> [{group, ssl}, {group, plain}].
+
+groups() ->
+ [{ssl, all_groups()},
+ {plain, all_groups()},
+ %%
+ {setup, [{repeat, 1}], [setup]},
+ {roundtrip, [{repeat, 1}], [roundtrip]},
+ {throughput, [{repeat, 1}],
+ [throughput_1024,
+ throughput_4096,
+ throughput_16384,
+ throughput_65536,
+ throughput_262144,
+ throughput_1048576]}].
+
+all_groups() ->
+ [{group, setup},
+ {group, roundtrip},
+ {group, throughput}].
+
+init_per_suite(Config) ->
+ Digest = sha1,
+ ECCurve = secp521r1,
+ TLSVersion = 'tlsv1.2',
+ TLSCipher = {ecdhe_ecdsa,aes_128_cbc,sha256,sha256},
+ %%
+ Node = node(),
+ try
+ Node =/= nonode@nohost orelse
+ throw({skipped,"Node not distributed"}),
+ verify_node_src_addr(),
+ {supported, SSLVersions} =
+ lists:keyfind(supported, 1, ssl:versions()),
+ lists:member(TLSVersion, SSLVersions) orelse
+ throw(
+ {skipped,
+ "SSL does not support " ++ term_to_string(TLSVersion)}),
+ lists:member(ECCurve, ssl:eccs(TLSVersion)) orelse
+ throw(
+ {skipped,
+ "SSL does not support " ++ term_to_string(ECCurve)}),
+ lists:member(TLSCipher, ssl:cipher_suites()) orelse
+ throw(
+ {skipped,
+ "SSL does not support " ++ term_to_string(TLSCipher)})
+ of
+ _ ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ %%
+ [_, HostA] = split_node(Node),
+ NodeAName = ?MODULE_STRING ++ "_node_a",
+ NodeAString = NodeAName ++ "@" ++ HostA,
+ NodeAConfFile = filename:join(PrivDir, NodeAString ++ ".conf"),
+ NodeA = list_to_atom(NodeAString),
+ %%
+ ServerNode = ssl_bench_test_lib:setup(dist_server),
+ [_, HostB] = split_node(ServerNode),
+ NodeBName = ?MODULE_STRING ++ "_node_b",
+ NodeBString = NodeBName ++ "@" ++ HostB,
+ NodeBConfFile = filename:join(PrivDir, NodeBString ++ ".conf"),
+ NodeB = list_to_atom(NodeBString),
+ %%
+ CertOptions =
+ [{digest, Digest},
+ {key, {namedCurve, ECCurve}}],
+ RootCert =
+ public_key:pkix_test_root_cert(
+ ?MODULE_STRING ++ " ROOT CA", CertOptions),
+ SSLConf =
+ [{verify, verify_peer},
+ {versions, [TLSVersion]},
+ {ciphers, [TLSCipher]}],
+ ServerConf =
+ [{fail_if_no_peer_cert, true},
+ {verify_fun,
+ {fun inet_tls_dist:verify_client/3,[]}}
+ | SSLConf],
+ ClientConf = SSLConf,
+ %%
+ write_node_conf(
+ NodeAConfFile, NodeA, ServerConf, ClientConf,
+ CertOptions, RootCert),
+ write_node_conf(
+ NodeBConfFile, NodeB, ServerConf, ClientConf,
+ CertOptions, RootCert),
+ %%
+ [{node_a_name, NodeAName},
+ {node_a, NodeA},
+ {node_a_dist_args,
+ "-proto_dist inet_tls "
+ "-ssl_dist_optfile " ++ NodeAConfFile ++ " "},
+ {node_b_name, NodeBName},
+ {node_b, NodeB},
+ {node_b_dist_args,
+ "-proto_dist inet_tls "
+ "-ssl_dist_optfile " ++ NodeBConfFile ++ " "},
+ {server_node, ServerNode}
+ |Config]
+ catch
+ throw:Result ->
+ Result
+ end.
+
+end_per_suite(Config) ->
+ ServerNode = proplists:get_value(server_node, Config),
+ slave:stop(ServerNode).
+
+init_per_group(ssl, Config) ->
+ [{ssl_dist, true}, {ssl_dist_prefix, "SSL"}|Config];
+init_per_group(plain, Config) ->
+ [{ssl_dist, false}, {ssl_dist_prefix, "Plain"}|Config];
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+init_per_testcase(_Func, Conf) ->
+ Conf.
+
+end_per_testcase(_Func, _Conf) ->
+ ok.
+
+-define(COUNT, 400).
+
+%%%-------------------------------------------------------------------
+%%% CommonTest API helpers
+
+verify_node_src_addr() ->
+ Msg = "Hello, world!",
+ {ok,Host} = inet:gethostname(),
+ {ok,DstAddr} = inet:getaddr(Host, inet),
+ {ok,Socket} = gen_udp:open(0, [{active,false}]),
+ {ok,Port} = inet:port(Socket),
+ ok = gen_udp:send(Socket, DstAddr, Port, Msg),
+ case gen_udp:recv(Socket, length(Msg) + 1, 1000) of
+ {ok,{DstAddr,Port,Msg}} ->
+ ok;
+ {ok,{SrcAddr,Port,Msg}} ->
+ throw({skipped,
+ "Src and dst address mismatch: " ++
+ term_to_string(SrcAddr) ++ " =:= " ++
+ term_to_string(DstAddr)});
+ Weird ->
+ error(Weird)
+ end.
+
+write_node_conf(
+ ConfFile, Node, ServerConf, ClientConf, CertOptions, RootCert) ->
+ [Name,Host] = split_node(Node),
+ Conf =
+ public_key:pkix_test_data(
+ #{root => RootCert,
+ peer =>
+ [{extensions,
+ [
+ #'Extension'{
+ extnID = ?'id-ce-subjectAltName',
+ extnValue = [{dNSName, Host}],
+ critical = true},
+ #'Extension'{
+ extnID = ?'id-ce-subjectAltName',
+ extnValue =
+ [{directoryName,
+ {rdnSequence,
+ [[#'AttributeTypeAndValue'{
+ type = ?'id-at-commonName',
+ value =
+ {utf8String,
+ unicode:characters_to_binary(
+ Name, utf8)
+ }
+ }]]}}],
+ critical = true}
+ ]} | CertOptions]}),
+ NodeConf =
+ [{server, ServerConf ++ Conf}, {client, ClientConf ++ Conf}],
+ {ok, Fd} = file:open(ConfFile, [write]),
+ ok = file:change_mode(ConfFile, 8#400),
+ io:format(Fd, "~p.~n", [NodeConf]),
+ ok = file:close(Fd).
+
+split_node(Node) ->
+ string:split(atom_to_list(Node), "@").
+
+%%%-------------------------------------------------------------------
+%%% Test cases
+
+%%-----------------------
+%% Connection setup speed
+
+setup(Config) ->
+ run_nodepair_test(fun setup/5, Config).
+
+setup(A, B, Prefix, HA, HB) ->
+ Rounds = 50,
+ [] = ssl_apply(HA, erlang, nodes, []),
+ [] = ssl_apply(HB, erlang, nodes, []),
+ {SetupTime, CycleTime} =
+ ssl_apply(HA, fun () -> setup_runner(A, B, Rounds) end),
+ [] = ssl_apply(HA, erlang, nodes, []),
+ [] = ssl_apply(HB, erlang, nodes, []),
+ SetupSpeed = round((Rounds*1000000*1000) / SetupTime),
+ CycleSpeed = round((Rounds*1000000*1000) / CycleTime),
+ _ = report(Prefix++" Setup", SetupSpeed, "setups/1000s"),
+ report(Prefix++" Setup Cycle", CycleSpeed, "cycles/1000s").
+
+%% Runs on node A against rex in node B
+setup_runner(A, B, Rounds) ->
+ StartTime = start_time(),
+ SetupTime = setup_loop(A, B, 0, Rounds),
+ {microseconds(SetupTime), microseconds(elapsed_time(StartTime))}.
+
+setup_loop(_A, _B, T, 0) ->
+ T;
+setup_loop(A, B, T, N) ->
+ StartTime = start_time(),
+ [N,A] = [N|rpc:block_call(B, erlang, nodes, [])],
+ Time = elapsed_time(StartTime),
+ [N,B] = [N|erlang:nodes()],
+ Mref = erlang:monitor(process, {rex,B}),
+ true = net_kernel:disconnect(B),
+ receive
+ {'DOWN',Mref,process,_,_} ->
+ [] = erlang:nodes(),
+ setup_loop(A, B, Time + T, N - 1)
+ end.
+
+
+%%----------------
+%% Roundtrip speed
+
+roundtrip(Config) ->
+ run_nodepair_test(fun roundtrip/5, Config).
+
+roundtrip(A, B, Prefix, HA, HB) ->
+ Rounds = 40000,
+ [] = ssl_apply(HA, erlang, nodes, []),
+ [] = ssl_apply(HB, erlang, nodes, []),
+ ok = ssl_apply(HA, net_kernel, allow, [[B]]),
+ ok = ssl_apply(HB, net_kernel, allow, [[A]]),
+ Time = ssl_apply(HA, fun () -> roundtrip_runner(A, B, Rounds) end),
+ [B] = ssl_apply(HA, erlang, nodes, []),
+ [A] = ssl_apply(HB, erlang, nodes, []),
+ Speed = round((Rounds*1000000) / Time),
+ report(Prefix++" Roundtrip", Speed, "pings/s").
+
+%% Runs on node A and spawns a server on node B
+roundtrip_runner(A, B, Rounds) ->
+ ClientPid = self(),
+ [A] = rpc:call(B, erlang, nodes, []),
+ ServerPid =
+ erlang:spawn(
+ B,
+ fun () -> roundtrip_server(ClientPid, Rounds) end),
+ ServerMon = erlang:monitor(process, ServerPid),
+ microseconds(
+ roundtrip_client(ServerPid, ServerMon, start_time(), Rounds)).
+
+roundtrip_server(_Pid, 0) ->
+ ok;
+roundtrip_server(Pid, N) ->
+ receive
+ N ->
+ Pid ! N,
+ roundtrip_server(Pid, N-1)
+ end.
+
+roundtrip_client(_Pid, Mon, StartTime, 0) ->
+ Time = elapsed_time(StartTime),
+ receive
+ {'DOWN', Mon, _, _, normal} ->
+ Time;
+ {'DOWN', Mon, _, _, Other} ->
+ exit(Other)
+ end;
+roundtrip_client(Pid, Mon, StartTime, N) ->
+ Pid ! N,
+ receive
+ N ->
+ roundtrip_client(Pid, Mon, StartTime, N - 1)
+ end.
+
+
+%%-----------------
+%% Throughput speed
+
+throughput_1024(Config) ->
+ run_nodepair_test(
+ fun (A, B, Prefix, HA, HB) ->
+ throughput(A, B, Prefix, HA, HB, 100000, 1024)
+ end, Config).
+
+throughput_4096(Config) ->
+ run_nodepair_test(
+ fun (A, B, Prefix, HA, HB) ->
+ throughput(A, B, Prefix, HA, HB, 50000, 4096)
+ end, Config).
+
+throughput_16384(Config) ->
+ run_nodepair_test(
+ fun (A, B, Prefix, HA, HB) ->
+ throughput(A, B, Prefix, HA, HB, 10000, 16384)
+ end, Config).
+
+throughput_65536(Config) ->
+ run_nodepair_test(
+ fun (A, B, Prefix, HA, HB) ->
+ throughput(A, B, Prefix, HA, HB, 2000, 65536)
+ end, Config).
+
+throughput_262144(Config) ->
+ run_nodepair_test(
+ fun (A, B, Prefix, HA, HB) ->
+ throughput(A, B, Prefix, HA, HB, 500, 262144)
+ end, Config).
+
+throughput_1048576(Config) ->
+ run_nodepair_test(
+ fun (A, B, Prefix, HA, HB) ->
+ throughput(A, B, Prefix, HA, HB, 200, 1048576)
+ end, Config).
+
+throughput(A, B, Prefix, HA, HB, Packets, Size) ->
+ [] = ssl_apply(HA, erlang, nodes, []),
+ [] = ssl_apply(HB, erlang, nodes, []),
+ Time =
+ ssl_apply(HA, fun () -> throughput_runner(A, B, Packets, Size) end),
+ [B] = ssl_apply(HA, erlang, nodes, []),
+ [A] = ssl_apply(HB, erlang, nodes, []),
+ Speed = round((Packets*Size*1000000) / (1024*Time)),
+ report(Prefix++" Throughput_"++integer_to_list(Size), Speed, "kB/s").
+
+%% Runs on node A and spawns a server on node B
+throughput_runner(A, B, Rounds, Size) ->
+ Payload = payload(Size),
+ ClientPid = self(),
+ [A] = rpc:call(B, erlang, nodes, []),
+ ServerPid =
+ erlang:spawn(
+ B,
+ fun () -> throughput_server(ClientPid, Rounds) end),
+ ServerMon = erlang:monitor(process, ServerPid),
+ microseconds(
+ throughput_client(
+ ServerPid, ServerMon, Payload, start_time(), Rounds)).
+
+throughput_server(_Pid, 0) ->
+ ok;
+throughput_server(Pid, N) ->
+ receive
+ [N|_] ->
+ throughput_server(Pid, N-1)
+ end.
+
+throughput_client(_Pid, Mon, _Payload, StartTime, 0) ->
+ receive
+ {'DOWN', Mon, _, _, normal} ->
+ elapsed_time(StartTime);
+ {'DOWN', Mon, _, _, Other} ->
+ exit(Other)
+ end;
+throughput_client(Pid, Mon, Payload, StartTime, N) ->
+ Pid ! [N|Payload],
+ throughput_client(Pid, Mon, Payload, StartTime, N - 1).
+
+%%%-------------------------------------------------------------------
+%%% Test cases helpers
+
+run_nodepair_test(TestFun, Config) ->
+ A = proplists:get_value(node_a, Config),
+ B = proplists:get_value(node_b, Config),
+ Prefix = proplists:get_value(ssl_dist_prefix, Config),
+ HA = start_ssl_node_a(Config),
+ HB = start_ssl_node_b(Config),
+ try TestFun(A, B, Prefix, HA, HB)
+ after
+ stop_ssl_node_a(HA),
+ stop_ssl_node_b(HB, Config),
+ ok
+ end.
+
+ssl_apply(Handle, M, F, Args) ->
+ case ssl_dist_test_lib:apply_on_ssl_node(Handle, M, F, Args) of
+ {'EXIT',Reason} ->
+ error(Reason);
+ Result ->
+ Result
+ end.
+
+ssl_apply(Handle, Fun) ->
+ case ssl_dist_test_lib:apply_on_ssl_node(Handle, Fun) of
+ {'EXIT',Reason} ->
+ error(Reason);
+ Result ->
+ Result
+ end.
+
+start_ssl_node_a(Config) ->
+ Name = proplists:get_value(node_a_name, Config),
+ Args = get_node_args(node_a_dist_args, Config),
+ ssl_dist_test_lib:start_ssl_node(Name, Args).
+
+start_ssl_node_b(Config) ->
+ Name = proplists:get_value(node_b_name, Config),
+ Args = get_node_args(node_b_dist_args, Config),
+ ServerNode = proplists:get_value(server_node, Config),
+ rpc:call(
+ ServerNode, ssl_dist_test_lib, start_ssl_node, [Name, Args]).
+
+stop_ssl_node_a(HA) ->
+ ssl_dist_test_lib:stop_ssl_node(HA).
+
+stop_ssl_node_b(HB, Config) ->
+ ServerNode = proplists:get_value(server_node, Config),
+ rpc:call(ServerNode, ssl_dist_test_lib, stop_ssl_node, [HB]).
+
+get_node_args(Tag, Config) ->
+ case proplists:get_value(ssl_dist, Config) of
+ true ->
+ proplists:get_value(Tag, Config);
+ false ->
+ ""
+ end.
+
+
+
+payload(Size) ->
+ iolist_to_binary(
+ [case Size bsr 8 of
+ 0 ->
+ [];
+ Blocks ->
+ payload(Blocks, create_binary(256))
+ end | create_binary(Size band 255)]).
+%%
+payload(0, _) ->
+ [];
+payload(Blocks, Block) ->
+ Half = payload(Blocks bsr 1, Block),
+ [Half, Half |
+ if
+ Blocks band 1 =:= 1 ->
+ Block;
+ true ->
+ []
+ end].
+
+create_binary(Size) ->
+ create_binary(Size, <<>>).
+%%
+create_binary(0, Bin) ->
+ Bin;
+create_binary(Size, Bin) ->
+ NextSize = Size - 1,
+ create_binary(NextSize, <<Bin/binary, NextSize>>).
+
+start_time() ->
+ erlang:system_time().
+
+elapsed_time(StartTime) ->
+ erlang:system_time() - StartTime.
+
+microseconds(Time) ->
+ erlang:convert_time_unit(Time, native, microsecond).
+
+report(Name, Value, Unit) ->
+ ct:pal("~s: ~w ~s", [Name, Value, Unit]),
+ ct_event:notify(
+ #event{
+ name = benchmark_data,
+ data = [{value, Value}, {suite, "ssl_dist"}, {name, Name}]}),
+ {comment, term_to_string(Value) ++ " " ++ Unit}.
+
+term_to_string(Term) ->
+ unicode:characters_to_list(
+ io_lib:write(Term, [{encoding, unicode}])).
diff --git a/lib/ssl/test/ssl_dist_test_lib.erl b/lib/ssl/test/ssl_dist_test_lib.erl
new file mode 100644
index 0000000000..1b9c853fc4
--- /dev/null
+++ b/lib/ssl/test/ssl_dist_test_lib.erl
@@ -0,0 +1,343 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ssl_dist_test_lib).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+-include("ssl_dist_test_lib.hrl").
+
+-export([tstsrvr_format/2, send_to_tstcntrl/1]).
+-export([apply_on_ssl_node/4, apply_on_ssl_node/2]).
+-export([stop_ssl_node/1, start_ssl_node/2]).
+%%
+-export([cnct2tstsrvr/1]).
+
+-define(AWAIT_SSL_NODE_UP_TIMEOUT, 30000).
+
+
+
+%% ssl_node side api
+%%
+
+tstsrvr_format(Fmt, ArgList) ->
+ send_to_tstsrvr({format, Fmt, ArgList}).
+
+send_to_tstcntrl(Message) ->
+ send_to_tstsrvr({message, Message}).
+
+
+%%
+%% test_server side api
+%%
+
+apply_on_ssl_node(
+ #node_handle{connection_handler = Hndlr} = Node,
+ M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
+ Ref = erlang:monitor(process, Hndlr),
+ apply_on_ssl_node(Node, Ref, {apply, self(), Ref, M, F, A}).
+
+apply_on_ssl_node(
+ #node_handle{connection_handler = Hndlr} = Node,
+ Fun) when is_function(Fun, 0) ->
+ Ref = erlang:monitor(process, Hndlr),
+ apply_on_ssl_node(Node, Ref, {apply, self(), Ref, Fun}).
+
+apply_on_ssl_node(Node, Ref, Msg) ->
+ send_to_ssl_node(Node, Msg),
+ receive
+ {'DOWN', Ref, process, Hndlr, Reason} ->
+ exit({handler_died, Hndlr, Reason});
+ {Ref, Result} ->
+ Result
+ end.
+
+stop_ssl_node(#node_handle{connection_handler = Handler,
+ socket = Socket,
+ name = Name}) ->
+ ?t:format("Trying to stop ssl node ~s.~n", [Name]),
+ Mon = erlang:monitor(process, Handler),
+ unlink(Handler),
+ case gen_tcp:send(Socket, term_to_binary(stop)) of
+ ok ->
+ receive
+ {'DOWN', Mon, process, Handler, Reason} ->
+ case Reason of
+ normal ->
+ ok;
+ _ ->
+ ct:pal(
+ "stop_ssl_node/1 ~s Down ~p ~n",
+ [Name,Reason])
+ end
+ end;
+ Error ->
+ erlang:demonitor(Mon, [flush]),
+ ct:pal("stop_ssl_node/1 ~s Warning ~p ~n", [Name,Error])
+ end.
+
+start_ssl_node(Name, Args) ->
+ {ok, LSock} = gen_tcp:listen(0,
+ [binary, {packet, 4}, {active, false}]),
+ {ok, ListenPort} = inet:port(LSock),
+ CmdLine = mk_node_cmdline(ListenPort, Name, Args),
+ ?t:format("Attempting to start ssl node ~ts: ~ts~n", [Name, CmdLine]),
+ case open_port({spawn, CmdLine}, []) of
+ Port when is_port(Port) ->
+ unlink(Port),
+ erlang:port_close(Port),
+ case await_ssl_node_up(Name, LSock) of
+ #node_handle{} = NodeHandle ->
+ ?t:format("Ssl node ~s started.~n", [Name]),
+ NodeName = list_to_atom(Name ++ "@" ++ host_name()),
+ NodeHandle#node_handle{nodename = NodeName};
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end;
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end.
+
+host_name() ->
+ [_, Host] = string:split(atom_to_list(node()), "@"),
+ %% [$@ | Host] = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ %% atom_to_list(node())),
+ Host.
+
+mk_node_cmdline(ListenPort, Name, Args) ->
+ Static = "-detached -noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ _ -> "-name "
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ "\"" ++ Prog ++ "\" "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ Name ++ " "
+ ++ "-pa " ++ Pa ++ " "
+ ++ "-run application start crypto -run application start public_key "
+ ++ "-eval 'net_kernel:verbose(1)' "
+ ++ "-run " ++ atom_to_list(?MODULE) ++ " cnct2tstsrvr "
+ ++ host_name() ++ " "
+ ++ integer_to_list(ListenPort) ++ " "
+ ++ Args ++ " "
+ ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ Name ++ " "
+ ++ "-kernel error_logger \"{file,\\\"" ++ Pwd ++ "/error_log." ++ Name ++ "\\\"}\" "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
+
+%%
+%% Connection handler test_server side
+%%
+
+await_ssl_node_up(Name, LSock) ->
+ case gen_tcp:accept(LSock, ?AWAIT_SSL_NODE_UP_TIMEOUT) of
+ {ok, Socket} ->
+ gen_tcp:close(LSock),
+ case gen_tcp:recv(Socket, 0) of
+ {ok, Bin} ->
+ check_ssl_node_up(Socket, Name, Bin);
+ {error, closed} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node_before_up, Name})
+ end;
+ {error, Error} ->
+ gen_tcp:close(LSock),
+ ?t:format("Accept failed for ssl node ~s: ~p~n", [Name,Error]),
+ exit({accept_failed, Error})
+ end.
+
+check_ssl_node_up(Socket, Name, Bin) ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {ssl_node_up, NodeName} ->
+ case list_to_atom(Name++"@"++host_name()) of
+ NodeName ->
+ Parent = self(),
+ Go = make_ref(),
+ %% Spawn connection handler on test server side
+ Pid = spawn_link(
+ fun () ->
+ receive Go -> ok end,
+ process_flag(trap_exit, true),
+ tstsrvr_con_loop(Name, Socket, Parent)
+ end),
+ ok = gen_tcp:controlling_process(Socket, Pid),
+ Pid ! Go,
+ #node_handle{connection_handler = Pid,
+ socket = Socket,
+ name = Name};
+ _ ->
+ exit({unexpected_ssl_node_connected, NodeName})
+ end;
+ Msg ->
+ exit({unexpected_msg_instead_of_ssl_node_up, Name, Msg})
+ end.
+
+send_to_ssl_node(#node_handle{connection_handler = Hndlr}, Term) ->
+ Hndlr ! {relay_to_ssl_node, term_to_binary(Term)},
+ ok.
+
+tstsrvr_con_loop(Name, Socket, Parent) ->
+ ok = inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_ssl_node, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ exit({failed_to_relay_data_to_ssl_node, Name, Data})
+ end;
+ {tcp, Socket, Bin} ->
+ try binary_to_term(Bin) of
+ {format, FmtStr, ArgList} ->
+ ?t:format(FmtStr, ArgList);
+ {message, Msg} ->
+ ?t:format("Got message ~p", [Msg]),
+ Parent ! Msg;
+ {apply_res, To, Ref, Res} ->
+ To ! {Ref, Res};
+ bye ->
+ {error, closed} = gen_tcp:recv(Socket, 0),
+ ?t:format("Ssl node ~s stopped.~n", [Name]),
+ gen_tcp:close(Socket),
+ exit(normal);
+ Unknown ->
+ exit({unexpected_message_from_ssl_node, Name, Unknown})
+ catch
+ error : _ ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin})
+ end;
+ {tcp_closed, Socket} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node, Name});
+ {'EXIT', Parent, Reason} ->
+ exit({'EXIT', parent, Reason});
+ Unknown ->
+ exit({unknown, Unknown})
+ end,
+ tstsrvr_con_loop(Name, Socket, Parent).
+
+%%
+%% Connection handler ssl_node side
+%%
+
+% cnct2tstsrvr() is called via command line arg -run ...
+cnct2tstsrvr([Host, Port]) when is_list(Host), is_list(Port) ->
+ %% Spawn connection handler on ssl node side
+ ConnHandler
+ = spawn(fun () ->
+ case catch gen_tcp:connect(Host,
+ list_to_integer(Port),
+ [binary,
+ {packet, 4},
+ {active, false}]) of
+ {ok, Socket} ->
+ notify_ssl_node_up(Socket),
+ ets:new(test_server_info,
+ [set,
+ public,
+ named_table,
+ {keypos, 1}]),
+ ets:insert(test_server_info,
+ {test_server_handler, self()}),
+ ssl_node_con_loop(Socket);
+ Error ->
+ halt("Failed to connect to test server " ++
+ lists:flatten(io_lib:format("Host:~p ~n Port:~p~n Error:~p~n",
+ [Host, Port, Error])))
+ end
+ end),
+ spawn(fun () ->
+ Mon = erlang:monitor(process, ConnHandler),
+ receive
+ {'DOWN', Mon, process, ConnHandler, Reason} ->
+ receive after 1000 -> ok end,
+ halt("test server connection handler terminated: " ++
+ lists:flatten(io_lib:format("~p", [Reason])))
+ end
+ end).
+
+notify_ssl_node_up(Socket) ->
+ case catch gen_tcp:send(Socket,
+ term_to_binary({ssl_node_up, node()})) of
+ ok -> ok;
+ _ -> halt("Failed to notify test server that I'm up")
+ end.
+
+send_to_tstsrvr(Term) ->
+ case catch ets:lookup_element(test_server_info, test_server_handler, 2) of
+ Hndlr when is_pid(Hndlr) ->
+ Hndlr ! {relay_to_test_server, term_to_binary(Term)}, ok;
+ _ ->
+ receive after 200 -> ok end,
+ send_to_tstsrvr(Term)
+ end.
+
+ssl_node_con_loop(Socket) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_test_server, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ halt("Failed to relay data to test server")
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ halt("test server sent me bad data");
+ {apply, From, Ref, M, F, A} ->
+ spawn_link(
+ fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch apply(M, F, A))})
+ end);
+ {apply, From, Ref, Fun} ->
+ spawn_link(fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch Fun())})
+ end);
+ stop ->
+ gen_tcp:send(Socket, term_to_binary(bye)),
+ init:stop(),
+ receive after infinity -> ok end;
+ _Unknown ->
+ halt("test server sent me an unexpected message")
+ end;
+ {tcp_closed, Socket} ->
+ halt("Lost connection to test server")
+ end,
+ ssl_node_con_loop(Socket).
diff --git a/lib/ssl/test/ssl_dist_test_lib.hrl b/lib/ssl/test/ssl_dist_test_lib.hrl
new file mode 100644
index 0000000000..86b9b37026
--- /dev/null
+++ b/lib/ssl/test/ssl_dist_test_lib.hrl
@@ -0,0 +1,26 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-record(node_handle,
+ {connection_handler,
+ socket,
+ name,
+ nodename}
+ ).
diff --git a/lib/ssl/test/ssl_engine_SUITE.erl b/lib/ssl/test/ssl_engine_SUITE.erl
index 8025e4e0ed..1423c99dc2 100644
--- a/lib/ssl/test/ssl_engine_SUITE.erl
+++ b/lib/ssl/test/ssl_engine_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2017-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2017-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index c492c54066..b8b9989d30 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() -> [decode_hello_handshake,
- decode_hello_handshake_version_confusion,
decode_single_hello_extension_correctly,
decode_supported_elliptic_curves_hello_extension_correctly,
decode_unknown_hello_extension_correctly,
@@ -41,7 +40,8 @@ all() -> [decode_hello_handshake,
decode_single_hello_sni_extension_correctly,
decode_empty_server_sni_correctly,
select_proper_tls_1_2_rsa_default_hashsign,
- ignore_hassign_extension_pre_tls_1_2].
+ ignore_hassign_extension_pre_tls_1_2,
+ unorded_chain].
%%--------------------------------------------------------------------
init_per_suite(Config) ->
@@ -101,20 +101,13 @@ decode_hello_handshake(_Config) ->
Version = {3, 0},
{Records, _Buffer} = tls_handshake:get_tls_handshake(Version, HelloPacket, <<>>,
- #ssl_options{v2_hello_compatible = false}),
+ #ssl_options{}),
{Hello, _Data} = hd(Records),
#renegotiation_info{renegotiated_connection = <<0>>}
= (Hello#server_hello.extensions)#hello_extensions.renegotiation_info.
-decode_hello_handshake_version_confusion(_) ->
- HelloPacket = <<3,3,0,0,0,0,0,63,210,235,149,6,244,140,108,13,177,74,16,218,33,108,219,41,73,228,3,82,132,123,73,144,118,100,0,0,32,192,4,0,10,192,45,192,38,0,47,192,18,0,163,0,22,0,165,192,29,192,18,192,30,0,103,0,57,192,48,0,47,1,0>>,
- Version = {3,3},
- ClientHello = 1,
- Hello = tls_handshake:decode_handshake({3,3}, ClientHello, HelloPacket, false),
- Hello = tls_handshake:decode_handshake({3,3}, ClientHello, HelloPacket, true).
-
decode_single_hello_extension_correctly(_Config) ->
Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>,
Extensions = ssl_handshake:decode_hello_extensions(Renegotiation),
@@ -181,6 +174,29 @@ ignore_hassign_extension_pre_tls_1_2(Config) ->
{md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,2}), {3,2}),
{md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,0}), {3,0}).
+unorded_chain(Config) when is_list(Config) ->
+ DefConf = ssl_test_lib:default_cert_chain_conf(),
+ CertChainConf = ssl_test_lib:gen_conf(rsa, rsa, DefConf, DefConf),
+ #{server_config := ServerConf,
+ client_config := _ClientConf} = public_key:pkix_test_data(CertChainConf),
+ PeerCert = proplists:get_value(cert, ServerConf),
+ CaCerts = [_, C1, C2] = proplists:get_value(cacerts, ServerConf),
+ {ok, ExtractedCerts} = ssl_pkix_db:extract_trusted_certs({der, CaCerts}),
+ UnordedChain = case public_key:pkix_is_self_signed(C1) of
+ true ->
+ [C1, C2];
+ false ->
+ [C2, C1]
+ end,
+ OrderedChain = [PeerCert | lists:reverse(UnordedChain)],
+ {ok, _, OrderedChain} =
+ ssl_certificate:certificate_chain(PeerCert, ets:new(foo, []), ExtractedCerts, UnordedChain).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
is_supported(Hash) ->
Algos = crypto:supports(),
Hashs = proplists:get_value(hashs, Algos),
diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
index 6bf2aa2786..1c7d6b5f9f 100644
--- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index 3261244ace..ebf8ddbfac 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -141,6 +141,7 @@ socket_active_packet_tests() ->
packet_4_active_some_big,
packet_wait_active,
packet_size_active,
+ packet_switch,
%% inet header option should be deprecated!
header_decode_one_byte_active,
header_decode_two_bytes_active,
@@ -702,6 +703,34 @@ packet_size_passive(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_switch() ->
+ [{doc,"Test packet option {packet, 2} followd by {packet, 4}"}].
+
+packet_switch(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_switch_packet ,["Hello World", 4]}},
+ {options, [{nodelay, true},{packet, 2} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, recv_switch_packet, ["Hello World", 4]}},
+ {options, [{nodelay, true}, {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
%%--------------------------------------------------------------------
packet_cdr_decode() ->
[{doc,"Test setting the packet option {packet, cdr}, {mode, binary}"}].
@@ -2286,3 +2315,26 @@ client_reject_packet_opt(Config, PacketOpt) ->
ClientOpts]}]),
ssl_test_lib:check_result(Client, {error, {options, {not_supported, PacketOpt}}}).
+
+
+send_switch_packet(SslSocket, Data, NextPacket) ->
+ ssl:send(SslSocket, Data),
+ receive
+ {ssl, SslSocket, "Hello World"} ->
+ ssl:setopts(SslSocket, [{packet, NextPacket}]),
+ ssl:send(SslSocket, Data),
+ receive
+ {ssl, SslSocket, "Hello World"} ->
+ ok
+ end
+ end.
+recv_switch_packet(SslSocket, Data, NextPacket) ->
+ receive
+ {ssl, SslSocket, "Hello World"} ->
+ ssl:send(SslSocket, Data),
+ ssl:setopts(SslSocket, [{packet, NextPacket}]),
+ receive
+ {ssl, SslSocket, "Hello World"} ->
+ ssl:send(SslSocket, Data)
+ end
+ end.
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
index ef05241759..5939800001 100644
--- a/lib/ssl/test/ssl_payload_SUITE.erl
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl
index 96b15d9b51..25d2cb300d 100644
--- a/lib/ssl/test/ssl_pem_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() ->
- [pem_cleanup].
+ [pem_cleanup, invalid_insert].
groups() ->
[].
@@ -68,6 +68,10 @@ init_per_testcase(pem_cleanup = Case, Config) ->
application:set_env(ssl, ssl_pem_cache_clean, ?CLEANUP_INTERVAL),
ssl:start(),
ct:timetrap({minutes, 1}),
+ Config;
+init_per_testcase(_, Config) ->
+ ssl:start(),
+ ct:timetrap({seconds, 5}),
Config.
end_per_testcase(_TestCase, Config) ->
@@ -108,7 +112,34 @@ pem_cleanup(Config)when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client),
false = Size == Size1.
-
+
+invalid_insert() ->
+ [{doc, "Test that insert of invalid pem does not cause empty cache entry"}].
+invalid_insert(Config)when is_list(Config) ->
+ process_flag(trap_exit, true),
+
+ ClientOpts = proplists:get_value(client_verification_opts, Config),
+ ServerOpts = proplists:get_value(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ BadClientOpts = [{cacertfile, "tmp/does_not_exist.pem"} | proplists:delete(cacertfile, ClientOpts)],
+ 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),
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()}, {options, BadClientOpts}]),
+ ssl_test_lib:close(Server),
+ 1 = ssl_pkix_db:db_size(get_fileref_db()).
+
+
+
+%%--------------------------------------------------------------------
+%% Internal funcations
+%%--------------------------------------------------------------------
+
get_pem_cache() ->
{status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
[_, _,_, _, Prop] = StatusInfo,
@@ -120,6 +151,16 @@ get_pem_cache() ->
undefined
end.
+get_fileref_db() ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ case element(6, State) of
+ [_CertDb, {FileRefDb,_} | _] ->
+ FileRefDb;
+ _ ->
+ undefined
+ end.
later()->
DateTime = calendar:now_to_local_time(os:timestamp()),
Gregorian = calendar:datetime_to_gregorian_seconds(DateTime),
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index 9862b3ce64..a0fab58b9d 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -487,8 +487,8 @@ test_copts(_, 0, ClientOpts) ->
ClientOpts;
test_copts(max_table_size, N, ClientOpts) ->
Version = tls_record:highest_protocol_version([]),
- CipherSuites = %%lists:map(fun(X) -> ssl_cipher:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))),
-[ Y|| Y = {Alg,_, _, _} <- lists:map(fun(X) -> ssl_cipher:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))), Alg =/= ecdhe_ecdsa, Alg =/= ecdh_ecdsa, Alg =/= ecdh_rsa, Alg =/= ecdhe_rsa, Alg =/= dhe_dss, Alg =/= dss],
+ CipherSuites = %%lists:map(fun(X) -> ssl_cipher_format:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))),
+[ Y|| Y = {Alg,_, _, _} <- lists:map(fun(X) -> ssl_cipher_format:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))), Alg =/= ecdhe_ecdsa, Alg =/= ecdh_ecdsa, Alg =/= ecdh_rsa, Alg =/= ecdhe_rsa, Alg =/= dhe_dss, Alg =/= dss],
case length(CipherSuites) of
M when M >= N ->
Cipher = lists:nth(N, CipherSuites),
diff --git a/lib/ssl/test/ssl_sni_SUITE.erl b/lib/ssl/test/ssl_sni_SUITE.erl
index 7e78c41444..251b6a2639 100644
--- a/lib/ssl/test/ssl_sni_SUITE.erl
+++ b/lib/ssl/test/ssl_sni_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 3e6c5e8b8a..0ab845c4d1 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -79,17 +79,21 @@ run_server(ListenSocket, Opts, N) ->
Pid ! {accepter, N, Server},
run_server(ListenSocket, Opts, N-1).
-do_run_server(_, {error, timeout} = Result, Opts) ->
+do_run_server(_, {error, _} = Result, Opts) ->
+ ct:log("Server error result ~p~n", [Result]),
+ Pid = proplists:get_value(from, Opts),
+ Pid ! {self(), Result};
+do_run_server(_, ok = Result, Opts) ->
+ ct:log("Server cancel result ~p~n", [Result]),
Pid = proplists:get_value(from, Opts),
Pid ! {self(), Result};
-
do_run_server(ListenSocket, AcceptSocket, Opts) ->
Node = proplists:get_value(node, Opts),
Pid = proplists:get_value(from, Opts),
Transport = proplists:get_value(transport, Opts, ssl),
{Module, Function, Args} = proplists:get_value(mfa, Opts),
ct:log("~p:~p~nServer: apply(~p,~p,~p)~n",
- [?MODULE,?LINE, Module, Function, [AcceptSocket | Args]]),
+ [?MODULE,?LINE, Module, Function, [AcceptSocket | Args]]),
case rpc:call(Node, Module, Function, [AcceptSocket | Args]) of
no_result_msg ->
ok;
@@ -117,7 +121,8 @@ connect(#sslsocket{} = ListenSocket, Opts) ->
ReconnectTimes = proplists:get_value(reconnect_times, Opts, 0),
Timeout = proplists:get_value(timeout, Opts, infinity),
SslOpts = proplists:get_value(ssl_extra_opts, Opts, []),
- AcceptSocket = connect(ListenSocket, Node, 1 + ReconnectTimes, dummy, Timeout, SslOpts),
+ ContOpts = proplists:get_value(continue_options, Opts, []),
+ AcceptSocket = connect(ListenSocket, Node, 1 + ReconnectTimes, dummy, Timeout, SslOpts, ContOpts),
case ReconnectTimes of
0 ->
AcceptSocket;
@@ -132,10 +137,45 @@ connect(ListenSocket, Opts) ->
[ListenSocket]),
AcceptSocket.
-connect(_, _, 0, AcceptSocket, _, _) ->
+connect(_, _, 0, AcceptSocket, _, _, _) ->
AcceptSocket;
-
-connect(ListenSocket, Node, N, _, Timeout, []) ->
+connect(ListenSocket, Node, _N, _, Timeout, SslOpts, cancel) ->
+ ct:log("ssl:transport_accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
+ [ListenSocket]),
+ ct:log("~p:~p~nssl:handshake(~p,~p,~p)~n", [?MODULE,?LINE, AcceptSocket, SslOpts,Timeout]),
+
+ case rpc:call(Node, ssl, handshake, [AcceptSocket, SslOpts, Timeout]) of
+ {ok, Socket0, Ext} ->
+ ct:log("Ext ~p:~n", [Ext]),
+ ct:log("~p:~p~nssl:handshake_cancel(~p)~n", [?MODULE,?LINE, Socket0]),
+ rpc:call(Node, ssl, handshake_cancel, [Socket0]);
+ Result ->
+ ct:log("~p:~p~nssl:handshake@~p ret ~p",[?MODULE,?LINE, Node,Result]),
+ Result
+ end;
+connect(ListenSocket, Node, N, _, Timeout, SslOpts, [_|_] =ContOpts) ->
+ ct:log("ssl:transport_accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
+ [ListenSocket]),
+ ct:log("~p:~p~nssl:handshake(~p,~p,~p)~n", [?MODULE,?LINE, AcceptSocket, SslOpts,Timeout]),
+
+ case rpc:call(Node, ssl, handshake, [AcceptSocket, SslOpts, Timeout]) of
+ {ok, Socket0, Ext} ->
+ ct:log("Ext ~p:~n", [Ext]),
+ ct:log("~p:~p~nssl:handshake_continue(~p,~p,~p)~n", [?MODULE,?LINE, Socket0, ContOpts,Timeout]),
+ case rpc:call(Node, ssl, handshake_continue, [Socket0, ContOpts, Timeout]) of
+ {ok, Socket} ->
+ connect(ListenSocket, Node, N-1, Socket, Timeout, SslOpts, ContOpts);
+ Error ->
+ ct:log("~p:~p~nssl:handshake_continue@~p ret ~p",[?MODULE,?LINE, Node,Error]),
+ Error
+ end;
+ Result ->
+ ct:log("~p:~p~nssl:handshake@~p ret ~p",[?MODULE,?LINE, Node,Result]),
+ Result
+ end;
+connect(ListenSocket, Node, N, _, Timeout, [], ContOpts) ->
ct:log("ssl:transport_accept(~p)~n", [ListenSocket]),
{ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
[ListenSocket]),
@@ -143,12 +183,12 @@ connect(ListenSocket, Node, N, _, Timeout, []) ->
case rpc:call(Node, ssl, ssl_accept, [AcceptSocket, Timeout]) of
ok ->
- connect(ListenSocket, Node, N-1, AcceptSocket, Timeout, []);
+ connect(ListenSocket, Node, N-1, AcceptSocket, Timeout, [], ContOpts);
Result ->
ct:log("~p:~p~nssl:ssl_accept@~p ret ~p",[?MODULE,?LINE, Node,Result]),
Result
end;
-connect(ListenSocket, Node, _, _, Timeout, Opts) ->
+connect(ListenSocket, Node, _, _, Timeout, Opts, _) ->
ct:log("ssl:transport_accept(~p)~n", [ListenSocket]),
{ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
[ListenSocket]),
@@ -156,6 +196,30 @@ connect(ListenSocket, Node, _, _, Timeout, Opts) ->
rpc:call(Node, ssl, ssl_accept, [AcceptSocket, Opts, Timeout]),
AcceptSocket.
+
+start_server_transport_abuse_socket(Args) ->
+ Result = spawn_link(?MODULE, transport_accept_abuse, [Args]),
+ receive
+ {listen, up} ->
+ Result
+ end.
+
+transport_accept_abuse(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Transport = proplists:get_value(transport, Opts, ssl),
+ ct:log("~p:~p~nssl:listen(~p, ~p)~n", [?MODULE,?LINE, Port, Options]),
+ {ok, ListenSocket} = rpc:call(Node, Transport, listen, [Port, Options]),
+ Pid ! {listen, up},
+ send_selected_port(Pid, Port, ListenSocket),
+ {ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
+ [ListenSocket]),
+ {error, _} = rpc:call(Node, ssl, connection_information, [AcceptSocket]),
+ _ = rpc:call(Node, ssl, handshake, [AcceptSocket, infinity]),
+ Pid ! {self(), ok}.
+
remove_close_msg(0) ->
ok;
remove_close_msg(ReconnectTimes) ->
@@ -187,8 +251,17 @@ run_client(Opts) ->
Pid = proplists:get_value(from, Opts),
Transport = proplists:get_value(transport, Opts, ssl),
Options = proplists:get_value(options, Opts),
+ ContOpts = proplists:get_value(continue_options, Opts, []),
ct:log("~p:~p~n~p:connect(~p, ~p)@~p~n", [?MODULE,?LINE, Transport, Host, Port, Node]),
ct:log("SSLOpts: ~p", [Options]),
+ case ContOpts of
+ [] ->
+ client_loop(Node, Host, Port, Pid, Transport, Options, Opts);
+ _ ->
+ client_cont_loop(Node, Host, Port, Pid, Transport, Options, ContOpts, Opts)
+ end.
+
+client_loop(Node, Host, Port, Pid, Transport, Options, Opts) ->
case rpc:call(Node, Transport, connect, [Host, Port, Options]) of
{ok, Socket} ->
Pid ! {connected, Socket},
@@ -245,6 +318,40 @@ run_client(Opts) ->
Pid ! {connect_failed, {badrpc,BadRPC}}
end.
+client_cont_loop(Node, Host, Port, Pid, Transport, Options, cancel, _Opts) ->
+ case rpc:call(Node, Transport, connect, [Host, Port, Options]) of
+ {ok, Socket, _} ->
+ Result = rpc:call(Node, Transport, handshake_cancel, [Socket]),
+ ct:log("~p:~p~nClient: Cancel: ~p ~n", [?MODULE,?LINE, Result]),
+ Pid ! {connect_failed, Result};
+ {error, Reason} ->
+ ct:log("~p:~p~nClient: connection failed: ~p ~n", [?MODULE,?LINE, Reason]),
+ Pid ! {connect_failed, Reason}
+ end;
+
+client_cont_loop(Node, Host, Port, Pid, Transport, Options, ContOpts, Opts) ->
+ case rpc:call(Node, Transport, connect, [Host, Port, Options]) of
+ {ok, Socket0, _} ->
+ ct:log("~p:~p~nClient: handshake_continue(~p, ~p, infinity) ~n", [?MODULE, ?LINE, Socket0, ContOpts]),
+ case rpc:call(Node, Transport, handshake_continue, [Socket0, ContOpts]) of
+ {ok, Socket} ->
+ Pid ! {connected, Socket},
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ ct:log("~p:~p~nClient: apply(~p,~p,~p)~n",
+ [?MODULE,?LINE, Module, Function, [Socket | Args]]),
+ case rpc:call(Node, Module, Function, [Socket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ ct:log("~p:~p~nClient Msg: ~p ~n", [?MODULE,?LINE, Msg]),
+ Pid ! {self(), Msg}
+ end
+ end;
+ {error, Reason} ->
+ ct:log("~p:~p~nClient: connection failed: ~p ~n", [?MODULE,?LINE, Reason]),
+ Pid ! {connect_failed, Reason}
+ end.
+
close(Pid) ->
ct:log("~p:~p~nClose ~p ~n", [?MODULE,?LINE, Pid]),
Monitor = erlang:monitor(process, Pid),
@@ -898,6 +1005,8 @@ accepters(Acc, N) ->
{accepter, _, Server} ->
accepters([Server| Acc], N-1)
end.
+
+
basic_test(COpts, SOpts, Config) ->
SType = proplists:get_value(server_type, Config),
CType = proplists:get_value(client_type, Config),
@@ -918,7 +1027,6 @@ ecc_test_error(COpts, SOpts, CECCOpts, SECCOpts, Config) ->
Error = {error, {tls_alert, "insufficient security"}},
check_result(Server, Error, Client, Error).
-
start_client(openssl, Port, ClientOpts, Config) ->
Cert = proplists:get_value(certfile, ClientOpts),
Key = proplists:get_value(keyfile, ClientOpts),
@@ -1120,13 +1228,13 @@ rsa_suites(CounterPart) ->
lists:member(cipher_atom(Cipher), Ciphers);
({ecdhe_rsa, Cipher, _}) when ECC == true ->
lists:member(cipher_atom(Cipher), Ciphers);
+ ({ecdhe_rsa, Cipher, _,_}) when ECC == true ->
+ lists:member(cipher_atom(Cipher), Ciphers);
({rsa, Cipher, _, _}) ->
lists:member(cipher_atom(Cipher), Ciphers);
({dhe_rsa, Cipher, _,_}) ->
lists:member(cipher_atom(Cipher), Ciphers);
- ({ecdhe_rsa, Cipher, _,_}) when ECC == true ->
- lists:member(cipher_atom(Cipher), Ciphers);
- (_) ->
+ (_) ->
false
end,
common_ciphers(CounterPart)).
@@ -1136,13 +1244,13 @@ common_ciphers(crypto) ->
common_ciphers(openssl) ->
OpenSslSuites =
string:tokens(string:strip(os:cmd("openssl ciphers"), right, $\n), ":"),
- [ssl_cipher:erl_suite_definition(S)
+ [ssl_cipher_format:suite_definition(S)
|| S <- ssl_cipher:suites(tls_record:highest_protocol_version([])),
- lists:member(ssl_cipher:openssl_suite_name(S), OpenSslSuites)
+ lists:member(ssl_cipher_format:openssl_suite_name(S), OpenSslSuites)
].
available_suites(Version) ->
- [ssl_cipher:erl_suite_definition(Suite) ||
+ [ssl_cipher_format:suite_definition(Suite) ||
Suite <- ssl_cipher:filter_suites(ssl_cipher:suites(Version))].
@@ -1215,7 +1323,7 @@ string_regex_filter(_Str, _Search) ->
false.
ecdh_dh_anonymous_suites(Version) ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <- ssl_cipher:anonymous_suites(Version)],
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:anonymous_suites(Version)],
[{key_exchange,
fun(dh_anon) ->
true;
@@ -1224,22 +1332,42 @@ ecdh_dh_anonymous_suites(Version) ->
(_) ->
false
end}]).
+psk_suites({3,_} = Version) ->
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:psk_suites(Version)], []);
psk_suites(Version) ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <- ssl_cipher:psk_suites(Version)], []).
+ ssl:filter_cipher_suites(psk_suites(dtls_v1:corresponding_tls_version(Version)),
+ [{cipher,
+ fun(rc4_128) ->
+ false;
+ (_) ->
+ true
+ end}]).
-psk_anon_suites(Version) ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <- ssl_cipher:psk_suites_anon(Version)],
+psk_anon_suites({3,_} = Version) ->
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:psk_suites_anon(Version)],
[{key_exchange,
fun(psk) ->
true;
- (psk_dhe) ->
+ (dhe_psk) ->
+ true;
+ (ecdhe_psk) ->
true;
(_) ->
false
+ end}]);
+
+psk_anon_suites(Version) ->
+ ssl:filter_cipher_suites(psk_anon_suites(dtls_v1:corresponding_tls_version(Version)),
+ [{cipher,
+ fun(rc4_128) ->
+ false;
+ (_) ->
+ true
end}]).
+
srp_suites() ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <- ssl_cipher:srp_suites()],
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:srp_suites()],
[{key_exchange,
fun(srp_rsa) ->
true;
@@ -1247,21 +1375,25 @@ srp_suites() ->
false
end}]).
srp_anon_suites() ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <- ssl_cipher:srp_suites_anon()],
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:srp_suites_anon()],
[]).
srp_dss_suites() ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <- ssl_cipher:srp_suites()],
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:srp_suites()],
[{key_exchange,
fun(srp_dss) ->
true;
(_) ->
false
end}]).
+chacha_suites(Version) ->
+ [ssl_cipher_format:suite_definition(S) || S <- ssl_cipher:filter_suites(ssl_cipher:chacha_suites(Version))].
+
+
rc4_suites(Version) ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <-ssl_cipher:rc4_suites(Version)], []).
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <-ssl_cipher:rc4_suites(Version)], []).
des_suites(Version) ->
- ssl:filter_cipher_suites([ssl_cipher:suite_definition(S) || S <-ssl_cipher:des_suites(Version)], []).
+ ssl:filter_cipher_suites([ssl_cipher_format:suite_definition(S) || S <-ssl_cipher:des_suites(Version)], []).
tuple_to_map({Kex, Cipher, Mac}) ->
#{key_exchange => Kex,
@@ -1284,7 +1416,7 @@ der_to_pem(File, Entries) ->
cipher_result(Socket, Result) ->
{ok, Info} = ssl:connection_information(Socket),
- Result = {ok, {proplists:get_value(protocol, Info), proplists:get_value(cipher_suite, Info)}},
+ Result = {ok, {proplists:get_value(protocol, Info), proplists:get_value(selected_cipher_suite, Info)}},
ct:log("~p:~p~nSuccessfull connect: ~p~n", [?MODULE,?LINE, Result]),
%% Importante to send two packets here
%% to properly test "cipher state" handling
@@ -1479,7 +1611,7 @@ is_sane_ecc(crypto) ->
true
end;
is_sane_ecc(_) ->
- true.
+ sufficient_crypto_support(cipher_ec).
is_fips(openssl) ->
VersionStr = os:cmd("openssl version"),
@@ -1535,6 +1667,8 @@ openssl_dsa_support() ->
true;
"LibreSSL" ++ _ ->
false;
+ "OpenSSL 1.1" ++ Rest ->
+ false;
"OpenSSL 1.0.1" ++ Rest ->
hd(Rest) >= s;
_ ->
@@ -1550,9 +1684,7 @@ openssl_sane_dtls() ->
false;
"OpenSSL 1.0.2k-freebsd" ++ _ ->
false;
- "OpenSSL 1.0.2d" ++ _ ->
- false;
- "OpenSSL 1.0.2n" ++ _ ->
+ "OpenSSL 1.0.2" ++ _ ->
false;
"OpenSSL 1.0.0" ++ _ ->
false;
@@ -1657,10 +1789,10 @@ version_flag('dtlsv1') ->
"-dtls1".
filter_suites([Cipher | _] = Ciphers, AtomVersion) when is_list(Cipher)->
- filter_suites([ssl_cipher:openssl_suite(S) || S <- Ciphers],
+ filter_suites([ssl_cipher_format:openssl_suite(S) || S <- Ciphers],
AtomVersion);
filter_suites([Cipher | _] = Ciphers, AtomVersion) when is_binary(Cipher)->
- filter_suites([ssl_cipher:erl_suite_definition(S) || S <- Ciphers],
+ filter_suites([ssl_cipher_format:suite_definition(S) || S <- Ciphers],
AtomVersion);
filter_suites(Ciphers0, AtomVersion) ->
Version = tls_version(AtomVersion),
@@ -1672,7 +1804,7 @@ filter_suites(Ciphers0, AtomVersion) ->
++ ssl_cipher:srp_suites_anon()
++ ssl_cipher:rc4_suites(Version),
Supported1 = ssl_cipher:filter_suites(Supported0),
- Supported2 = [ssl_cipher:erl_suite_definition(S) || S <- Supported1],
+ Supported2 = [ssl_cipher_format:suite_definition(S) || S <- Supported1],
[Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported2)].
-define(OPENSSL_QUIT, "Q\n").
@@ -1725,8 +1857,13 @@ supports_ssl_tls_version(sslv2 = Version) ->
VersionFlag = version_flag(Version),
Exe = "openssl",
Args = ["s_client", VersionFlag],
+ [{trap_exit, Trap}] = process_info(self(), [trap_exit]),
+ process_flag(trap_exit, true),
Port = ssl_test_lib:portable_open_port(Exe, Args),
- do_supports_ssl_tls_version(Port, "")
+ Bool = do_supports_ssl_tls_version(Port, ""),
+ consume_port_exit(Port),
+ process_flag(trap_exit, Trap),
+ Bool
end;
supports_ssl_tls_version(Version) ->
@@ -1742,13 +1879,11 @@ do_supports_ssl_tls_version(Port, Acc) ->
case Acc ++ Data of
"unknown option" ++ _ ->
false;
- Error when length(Error) >= 11 ->
- case lists:member("error", string:tokens(Data, ":")) of
- true ->
- false;
- false ->
- do_supports_ssl_tls_version(Port, Error)
- end;
+ "s_client: Option unknown" ++ _->
+ false;
+ Info when length(Info) >= 24 ->
+ ct:pal("~p", [Info]),
+ true;
_ ->
do_supports_ssl_tls_version(Port, Acc ++ Data)
end
@@ -1818,10 +1953,14 @@ is_psk_anon_suite({psk, _,_}) ->
true;
is_psk_anon_suite({dhe_psk,_,_}) ->
true;
+is_psk_anon_suite({ecdhe_psk,_,_}) ->
+ true;
is_psk_anon_suite({psk, _,_,_}) ->
true;
is_psk_anon_suite({dhe_psk, _,_,_}) ->
true;
+is_psk_anon_suite({ecdhe_psk, _,_,_}) ->
+ true;
is_psk_anon_suite(_) ->
false.
@@ -1840,6 +1979,12 @@ tls_version('dtlsv1.2' = Atom) ->
tls_version(Atom) ->
tls_record:protocol_version(Atom).
+consume_port_exit(OpenSSLPort) ->
+ receive
+ {'EXIT', OpenSSLPort, _} ->
+ ok
+ end.
+
hardcode_rsa_key(1) ->
#'RSAPrivateKey'{
version = 'two-prime',
@@ -1938,3 +2083,41 @@ hardcode_dsa_key(3) ->
g = 20302424198893709525243209250470907105157816851043773596964076323184805650258390738340248469444700378962907756890306095615785481696522324901068493502141775433048117442554163252381401915027666416630898618301033737438756165023568220631119672502120011809327566543827706483229480417066316015458225612363927682579,
y = 48598545580251057979126570873881530215432219542526130654707948736559463436274835406081281466091739849794036308281564299754438126857606949027748889019480936572605967021944405048011118039171039273602705998112739400664375208228641666852589396502386172780433510070337359132965412405544709871654840859752776060358,
x = 1457508827177594730669011716588605181448418352823}.
+
+tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ client_msg(Client, ClientMsg);
+ {Client, ClientMsg} ->
+ server_msg(Server, ServerMsg);
+ {Client, {error,closed}} ->
+ server_msg(Server, ServerMsg);
+ {Server, {error,closed}} ->
+ client_msg(Client, ClientMsg)
+ end.
+client_msg(Client, ClientMsg) ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ {Client, {error,closed}} ->
+ ct:log("client got close"),
+ ok;
+ {Client, {error, Reason}} ->
+ ct:log("client got econnaborted: ~p", [Reason]),
+ ok;
+ Unexpected ->
+ ct:fail(Unexpected)
+ end.
+server_msg(Server, ServerMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ {Server, {error,closed}} ->
+ ct:log("server got close"),
+ ok;
+ {Server, {error, Reason}} ->
+ ct:log("server got econnaborted: ~p", [Reason]),
+ ok;
+ Unexpected ->
+ ct:fail(Unexpected)
+ end.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index 9b0ae94ef2..5a38f5f9c1 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -73,12 +73,11 @@ groups() ->
{'sslv3', [], all_versions_tests()}
]
end.
-
+
basic_tests() ->
[basic_erlang_client_openssl_server,
basic_erlang_server_openssl_client,
- expired_session,
- ssl2_erlang_server_openssl_client_comp
+ expired_session
].
all_versions_tests() ->
@@ -165,13 +164,13 @@ sni_server_tests() ->
init_per_suite(Config0) ->
case os:find_executable("openssl") of
- false ->
- {skip, "Openssl not found"};
- _ ->
- ct:pal("Version: ~p", [os:cmd("openssl version")]),
- catch crypto:stop(),
- try crypto:start() of
- ok ->
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
ssl_test_lib:clean_start(),
Config =
case ssl_test_lib:openssl_dsa_support() of
@@ -182,9 +181,9 @@ init_per_suite(Config0) ->
ssl_test_lib:make_rsa_cert(Config0)
end,
ssl_test_lib:cipher_restriction(Config)
- catch _:_ ->
- {skip, "Crypto did not start"}
- end
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
end.
end_per_suite(_Config) ->
@@ -192,39 +191,42 @@ end_per_suite(_Config) ->
application:stop(crypto).
init_per_group(basic, Config0) ->
- Config = ssl_test_lib:clean_tls_version(Config0),
- case ssl_test_lib:supports_ssl_tls_version(sslv2) of
- true ->
- [{v2_hello_compatible, true} | Config];
- false ->
- [{v2_hello_compatible, false} | Config]
+ case ssl_test_lib:supports_ssl_tls_version('tlsv1.2')
+ orelse ssl_test_lib:supports_ssl_tls_version('tlsv1.1')
+ orelse ssl_test_lib:supports_ssl_tls_version('tlsv1')
+ of
+ true ->
+ ssl_test_lib:clean_tls_version(Config0);
+ false ->
+ {skip, "only sslv3 supported by OpenSSL"}
end;
+
init_per_group(GroupName, Config) ->
case ssl_test_lib:is_tls_version(GroupName) of
- true ->
+ true ->
case ssl_test_lib:supports_ssl_tls_version(GroupName) of
- true ->
+ true ->
case ssl_test_lib:check_sane_openssl_version(GroupName) of
- true ->
+ true ->
ssl_test_lib:init_tls_version(GroupName, Config);
- false ->
+ false ->
{skip, openssl_does_not_support_version}
end;
false ->
{skip, openssl_does_not_support_version}
end;
- _ ->
- ssl:start(),
- Config
+ _ ->
+ ssl:start(),
+ Config
end.
end_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- ssl_test_lib:clean_tls_version(Config);
- false ->
- Config
- end.
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
init_per_testcase(expired_session, Config) ->
ct:timetrap(?EXPIRE * 1000 * 5),
@@ -232,19 +234,19 @@ init_per_testcase(expired_session, Config) ->
application:load(ssl),
application:set_env(ssl, session_lifetime, ?EXPIRE),
ssl:start(),
- Config;
+ Config;
init_per_testcase(TestCase, Config) when
TestCase == ciphers_dsa_signed_certs;
TestCase == erlang_client_openssl_server_dsa_cert;
TestCase == erlang_server_openssl_client_dsa_cert;
- TestCase == erlang_client_openssl_server_dsa_cert;
+ TestCase == erlang_client_openssl_server_dsa_cert;
TestCase == erlang_server_openssl_client_dsa_cert ->
case ssl_test_lib:openssl_dsa_support() of
true ->
special_init(TestCase, Config);
false ->
- {skip, "DSA not supported by OpenSSL"}
+ {skip, "DSA not supported by OpenSSL"}
end;
init_per_testcase(TestCase, Config) ->
ct:timetrap({seconds, 35}),
@@ -257,70 +259,69 @@ special_init(TestCase, Config) when
Config;
special_init(TestCase, Config)
when TestCase == erlang_client_openssl_server_renegotiate;
- TestCase == erlang_client_openssl_server_nowrap_seqnum;
+ TestCase == erlang_client_openssl_server_nowrap_seqnum;
TestCase == erlang_server_openssl_client_nowrap_seqnum
- ->
+ ->
{ok, Version} = application:get_env(ssl, protocol_version),
check_sane_openssl_renegotaite(Config, Version);
-special_init(Case, Config) when Case == ssl2_erlang_server_openssl_client;
- Case == ssl2_erlang_server_openssl_client_comp ->
+special_init(ssl2_erlang_server_openssl_client, Config) ->
case ssl_test_lib:supports_ssl_tls_version(sslv2) of
- true ->
- Config;
- false ->
- {skip, "sslv2 not supported by openssl"}
- end;
+ true ->
+ Config;
+ false ->
+ {skip, "sslv2 not supported by openssl"}
+ end;
special_init(TestCase, Config)
- when TestCase == erlang_client_alpn_openssl_server_alpn;
- TestCase == erlang_server_alpn_openssl_client_alpn;
- TestCase == erlang_client_alpn_openssl_server;
- TestCase == erlang_client_openssl_server_alpn;
- TestCase == erlang_server_alpn_openssl_client;
- TestCase == erlang_server_openssl_client_alpn ->
+ when TestCase == erlang_client_alpn_openssl_server_alpn;
+ TestCase == erlang_server_alpn_openssl_client_alpn;
+ TestCase == erlang_client_alpn_openssl_server;
+ TestCase == erlang_client_openssl_server_alpn;
+ TestCase == erlang_server_alpn_openssl_client;
+ TestCase == erlang_server_openssl_client_alpn ->
check_openssl_alpn_support(Config);
special_init(TestCase, Config)
- when TestCase == erlang_client_alpn_openssl_server_alpn_renegotiate;
- TestCase == erlang_server_alpn_openssl_client_alpn_renegotiate ->
- {ok, Version} = application:get_env(ssl, protocol_version),
- case check_sane_openssl_renegotaite(Config, Version) of
- {skip, _} = Skip ->
- Skip;
- _ ->
- check_openssl_alpn_support(Config)
- end;
+ when TestCase == erlang_client_alpn_openssl_server_alpn_renegotiate;
+ TestCase == erlang_server_alpn_openssl_client_alpn_renegotiate ->
+ {ok, Version} = application:get_env(ssl, protocol_version),
+ case check_sane_openssl_renegotaite(Config, Version) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ check_openssl_alpn_support(Config)
+ end;
special_init(TestCase, Config)
- when TestCase == erlang_client_alpn_npn_openssl_server_alpn_npn;
- TestCase == erlang_server_alpn_npn_openssl_client_alpn_npn ->
+ when TestCase == erlang_client_alpn_npn_openssl_server_alpn_npn;
+ TestCase == erlang_server_alpn_npn_openssl_client_alpn_npn ->
case check_openssl_alpn_support(Config) of
{skip, _} = Skip ->
Skip;
_ ->
- check_openssl_npn_support(Config)
+ check_openssl_npn_support(Config)
end;
special_init(TestCase, Config)
- when TestCase == erlang_client_openssl_server_npn;
- TestCase == erlang_server_openssl_client_npn;
- TestCase == erlang_server_openssl_client_npn_only_server;
- TestCase == erlang_server_openssl_client_npn_only_client;
- TestCase == erlang_client_openssl_server_npn_only_client;
- TestCase == erlang_client_openssl_server_npn_only_server ->
+ when TestCase == erlang_client_openssl_server_npn;
+ TestCase == erlang_server_openssl_client_npn;
+ TestCase == erlang_server_openssl_client_npn_only_server;
+ TestCase == erlang_server_openssl_client_npn_only_client;
+ TestCase == erlang_client_openssl_server_npn_only_client;
+ TestCase == erlang_client_openssl_server_npn_only_server ->
check_openssl_npn_support(Config);
special_init(TestCase, Config)
when TestCase == erlang_server_openssl_client_npn_renegotiate;
TestCase == erlang_client_openssl_server_npn_renegotiate ->
{ok, Version} = application:get_env(ssl, protocol_version),
- case check_sane_openssl_renegotaite(Config, Version) of
- {skip, _} = Skip ->
- Skip;
- _ ->
- check_openssl_npn_support(Config)
- end;
+ case check_sane_openssl_renegotaite(Config, Version) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ check_openssl_npn_support(Config)
+ end;
special_init(TestCase, Config0)
when TestCase == erlang_server_openssl_client_sni_match;
@@ -329,25 +330,25 @@ special_init(TestCase, Config0)
TestCase == erlang_server_openssl_client_sni_match_fun;
TestCase == erlang_server_openssl_client_sni_no_match_fun;
TestCase == erlang_server_openssl_client_sni_no_header_fun ->
- RsaOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config0),
+ RsaOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config0),
Config = [{sni_server_opts, [{sni_hosts,
[{"a.server", [
{certfile, proplists:get_value(certfile, RsaOpts)},
{keyfile, proplists:get_value(keyfile, RsaOpts)}
]},
{"b.server", [
- {certfile, proplists:get_value(certfile, RsaOpts)},
+ {certfile, proplists:get_value(certfile, RsaOpts)},
{keyfile, proplists:get_value(keyfile, RsaOpts)}
]}
]}]} | Config0],
check_openssl_sni_support(Config);
special_init(_, Config) ->
- Config.
+ Config.
end_per_testcase(reuse_session_expired, Config) ->
application:unset_env(ssl, session_lifetime),
- Config;
+ Config;
end_per_testcase(_, Config) ->
Config.
@@ -370,8 +371,8 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) ->
KeyFile = proplists:get_value(keyfile, ServerOpts),
Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- "-cert", CertFile, "-key", KeyFile],
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ "-cert", CertFile, "-key", KeyFile],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
@@ -379,15 +380,15 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) ->
ssl_test_lib:wait_for_openssl_server(Port, tls),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
true = port_command(OpensslPort, Data),
ssl_test_lib:check_result(Client, ok),
-
+
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
@@ -399,23 +400,28 @@ basic_erlang_server_openssl_client() ->
basic_erlang_server_openssl_client(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- V2Compat = proplists:get_value(v2_hello_compatible, Config),
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Data = "From openssl to erlang",
- ct:pal("v2_hello_compatible: ~p", [V2Compat]),
-
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options,[{v2_hello_compatible, V2Compat} | ServerOpts]}]),
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options,ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++
- ":" ++ integer_to_list(Port) | workaround_openssl_s_clinent()],
+ Args = case no_low_flag("-no_ssl2") of
+ [] ->
+ ["s_client", "-connect", hostname_format(Hostname) ++
+ ":" ++ integer_to_list(Port), no_low_flag("-no_ssl3")
+ | workaround_openssl_s_clinent()];
+ Flag ->
+ ["s_client", "-connect", hostname_format(Hostname) ++
+ ":" ++ integer_to_list(Port), no_low_flag("-no_ssl3"), Flag
+ | workaround_openssl_s_clinent()]
+ end,
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
@@ -445,19 +451,19 @@ erlang_client_openssl_server(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile],
-
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
true = port_command(OpensslPort, Data),
ssl_test_lib:check_result(Client, ok),
@@ -473,24 +479,24 @@ erlang_server_openssl_client() ->
erlang_server_openssl_client(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
Data = "From openssl to erlang",
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_client", "-connect", hostname_format(Hostname) ++":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version)],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+ ssl_test_lib:version_flag(Version)],
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
true = port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
@@ -507,8 +513,8 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_dsa_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_dsa_verify_opts, Config),
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
Data = "From openssl to erlang",
Port = ssl_test_lib:inet_port(node()),
@@ -518,27 +524,27 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-CAfile", CaCertFile,
- "-key", KeyFile, "-Verify", "2", "-msg"],
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-CAfile", CaCertFile,
+ "-key", KeyFile, "-Verify", "2", "-msg"],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Client, ok),
-
+ ssl_test_lib:check_result(Client, ok),
+
%% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false),
ok.
@@ -558,17 +564,17 @@ erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) ->
KeyFile = proplists:get_value(keyfile, ClientOpts),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile,
- "-CAfile", CaCertFile,
- "-key", KeyFile, "-msg"],
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,
+ "-CAfile", CaCertFile,
+ "-key", KeyFile, "-msg"],
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
@@ -580,11 +586,11 @@ erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) ->
ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false).
-%%--------------------------------------------------------------------
+ %%--------------------------------------------------------------------
erlang_client_openssl_server_anon() ->
- [{doc,"Test erlang client with openssl server, anonymous"}].
+ [{doc,"Test erlang client with openssl server, anonymous"}].
erlang_client_openssl_server_anon(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
+ process_flag(trap_exit, true),
%% OpenSSL expects a certificate and key, even if the cipher spec
%% is restructed to aNULL, so we use 'server_rsa_opts' here
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
@@ -592,113 +598,128 @@ erlang_client_openssl_server_anon(Config) when is_list(Config) ->
VersionTuple = ssl_test_lib:protocol_version(Config, tuple),
Ciphers = ssl_test_lib:ecdh_dh_anonymous_suites(VersionTuple),
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile,
- "-cipher", "aNULL", "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, [{ciphers, Ciphers} | ClientOpts]}]),
-
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
- ok.
+ case openssl_has_common_ciphers(Ciphers) of
+ false ->
+ {skip, not_supported_by_openssl};
+ true ->
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile,
+ "-cipher", "aNULL", "-msg"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, [{ciphers, Ciphers} | ClientOpts]}]),
+
+ true = port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false)
+ end.
%%--------------------------------------------------------------------
erlang_server_openssl_client_anon() ->
[{doc,"Test erlang server with openssl client, anonymous"}].
erlang_server_openssl_client_anon(Config) when is_list(Config) ->
+
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_anon_opts, Config),
VersionTuple = ssl_test_lib:protocol_version(Config, tuple),
Ciphers = ssl_test_lib:ecdh_dh_anonymous_suites(VersionTuple),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{ciphers, Ciphers} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cipher", "aNULL", "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
+ case openssl_has_common_ciphers(Ciphers) of
+ false ->
+ {skip, not_supported_by_openssl};
+ true ->
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{ciphers, Ciphers} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cipher", "aNULL", "-msg"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+ true = port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false)
+ end.
- %%--------------------------------------------------------------------
- erlang_server_openssl_client_anon_with_cert() ->
- [{doc,"Test erlang server with openssl client, anonymous (with cert)"}].
- erlang_server_openssl_client_anon_with_cert(Config) when is_list(Config) ->
+%%--------------------------------------------------------------------
+erlang_server_openssl_client_anon_with_cert() ->
+ [{doc,"Test erlang server with openssl client, anonymous (with cert)"}].
+erlang_server_openssl_client_anon_with_cert(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
VersionTuple = ssl_test_lib:protocol_version(Config, tuple),
Ciphers = ssl_test_lib:ecdh_dh_anonymous_suites(VersionTuple),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{ciphers, Ciphers} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cipher", "aNULL", "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
+ case openssl_has_common_ciphers(Ciphers) of
+ false ->
+ {skip, not_supported_by_openssl};
+ true ->
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{ciphers, Ciphers} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-cipher", "aNULL", "-msg"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+ true = port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false)
+ end.
+ %%--------------------------------------------------------------------
erlang_server_openssl_client_reuse_session() ->
[{doc, "Test erlang server with openssl client that reconnects with the"
- "same session id, to test reusing of sessions."}].
+ "same session id, to test reusing of sessions."}].
erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
@@ -708,18 +729,18 @@ erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
Data = "From openssl to erlang",
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {reconnect_times, 5},
- {options, ServerOpts}]),
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {reconnect_times, 5},
+ {options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Version = ssl_test_lib:protocol_version(Config),
-
+
Exe = "openssl",
Args = ["s_client", "-connect", hostname_format(Hostname)
++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-reconnect"],
+ ssl_test_lib:version_flag(Version),
+ "-reconnect"],
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
@@ -730,7 +751,7 @@ erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false),
+ process_flag(trap_exit, false),
ok.
%%--------------------------------------------------------------------
@@ -754,46 +775,46 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile, "-msg"],
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- delayed_send, [[ErlData, OpenSslData]]}},
- {options, ClientOpts}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ delayed_send, [[ErlData, OpenSslData]]}},
+ {options, ClientOpts}]),
true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
ct:sleep(?SLEEP),
true = port_command(OpensslPort, OpenSslData),
ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
+
+ %% Clean close down! Server needs to be closed first !!
ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
+ process_flag(trap_exit, false),
ok.
%%--------------------------------------------------------------------
erlang_client_openssl_server_nowrap_seqnum() ->
[{doc, "Test that erlang client will renegotiate session when",
- "max sequence number celing is about to be reached. Although"
- "in the testcase we use the test option renegotiate_at"
- " to lower treashold substantially."}].
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."}].
erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
+
ErlData = "From erlang to openssl\n",
N = 10,
@@ -803,21 +824,21 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile, "-msg"],
-
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
+
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- trigger_renegotiate, [[ErlData, N+2]]}},
- {options, [{reuse_sessions, false},
- {renegotiate_at, N} | ClientOpts]}]),
-
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[ErlData, N+2]]}},
+ {options, [{reuse_sessions, false},
+ {renegotiate_at, N} | ClientOpts]}]),
+
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
@@ -827,37 +848,37 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
erlang_server_openssl_client_nowrap_seqnum() ->
[{doc, "Test that erlang client will renegotiate session when",
- "max sequence number celing is about to be reached. Although"
- "in the testcase we use the test option renegotiate_at"
- " to lower treashold substantially."}].
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."}].
erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
+
Data = "From openssl to erlang",
-
+
N = 10,
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- trigger_renegotiate, [[Data, N+2]]}},
- {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]),
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[Data, N+2]]}},
+ {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_client","-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-msg"],
-
+ ssl_test_lib:version_flag(Version),
+ "-msg"],
+
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
-
+
ssl_test_lib:check_result(Server, ok),
-
+
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
ssl_test_lib:close_port(OpenSslPort),
@@ -867,15 +888,15 @@ erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
erlang_client_openssl_server_no_server_ca_cert() ->
[{doc, "Test erlang client when openssl server sends a cert chain not"
- "including the ca cert. Explicitly test this even if it is"
- "implicitly tested eleswhere."}].
+ "including the ca cert. Explicitly test this even if it is"
+ "implicitly tested eleswhere."}].
erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
+
Data = "From openssl to erlang",
Port = ssl_test_lib:inet_port(node()),
@@ -884,22 +905,22 @@ erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile, "-msg"],
-
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
+
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
+
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
true = port_command(OpensslPort, Data),
-
+
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
@@ -916,9 +937,9 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
+
Data = "From openssl to erlang",
-
+
Port = ssl_test_lib:inet_port(node()),
CertFile = proplists:get_value(certfile, ServerOpts),
CaCertFile = proplists:get_value(cacertfile, ServerOpts),
@@ -926,31 +947,30 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-CAfile", CaCertFile,
- "-key", KeyFile, "-Verify", "2"],
-
+ ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-CAfile", CaCertFile,
+ "-key", KeyFile, "-Verify", "2"],
+
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
true = port_command(OpensslPort, Data),
-
+
ssl_test_lib:check_result(Client, ok),
-
+
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
-
erlang_server_openssl_client_client_cert() ->
[{doc,"Test erlang server with openssl client when client sends cert"}].
erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
@@ -959,39 +979,38 @@ erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
+
Data = "From openssl to erlang",
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options,
- [{verify , verify_peer}
- | ServerOpts]}]),
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
-
+
CaCertFile = proplists:get_value(cacertfile, ClientOpts),
CertFile = proplists:get_value(certfile, ClientOpts),
KeyFile = proplists:get_value(keyfile, ClientOpts),
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_client", "-cert", CertFile,
- "-CAfile", CaCertFile,
- "-key", KeyFile,"-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version)],
+ "-CAfile", CaCertFile,
+ "-key", KeyFile,"-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version)],
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
-
+
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close_port(OpenSslPort),
ssl_test_lib:close(Server),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
-
erlang_server_erlang_client_client_cert() ->
[{doc,"Test erlang server with erlang client when client sends cert"}].
erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
@@ -1000,30 +1019,30 @@ erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
ClientOpts = proplists:get_value(client_rsa_verify_opts, Config),
Version = ssl_test_lib:protocol_version(Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
+
Data = "From erlang to erlang",
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive,
- %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast
- [Data]}},
- {options,
- [{verify , verify_peer}
- | ServerOpts]}]),
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive,
+ %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+ [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
-
+
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast
- {mfa, {ssl, send, [Data]}},
- {options,
- [{versions, [Version]} | ClientOpts]}]),
-
+ {host, Hostname},
+ {from, self()},
+ %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [Version]} | ClientOpts]}]),
+
ssl_test_lib:check_result(Server, ok, Client, ok),
-
+
ssl_test_lib:close(Server),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -1055,43 +1074,43 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
+
Port = ssl_test_lib:inet_port(node()),
CertFile = proplists:get_value(certfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile],
+ "-cert", CertFile, "-key", KeyFile],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
+
ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
+
Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, server_sent_garbage, []}},
- {options,
- [{versions, [Version]} | ClientOpts]}]),
-
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, server_sent_garbage, []}},
+ {options,
+ [{versions, [Version]} | ClientOpts]}]),
+
%% Send garbage
true = port_command(OpensslPort, ?OPENSSL_GARBAGE),
ct:sleep(?SLEEP),
Client0 ! server_sent_garbage,
-
+
ssl_test_lib:check_result(Client0, true),
-
+
ssl_test_lib:close(Client0),
-
+
%% Make sure openssl does not hang and leave zombie process
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result_msg, []}},
- {options,
- [{versions, [Version]} | ClientOpts]}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result_msg, []}},
+ {options,
+ [{versions, [Version]} | ClientOpts]}]),
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close_port(OpensslPort),
@@ -1116,38 +1135,38 @@ expired_session(Config) when is_list(Config) ->
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port),
- "-cert", CertFile,"-key", KeyFile],
-
+ "-cert", CertFile,"-key", KeyFile],
+
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
ssl_test_lib:wait_for_openssl_server(Port, tls),
-
+
Client0 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
-
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
ssl_test_lib:close(Client0),
%% Make sure session is registered
ct:sleep(?SLEEP),
Client1 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
-
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
ssl_test_lib:close(Client1),
%% Make sure session is unregistered due to expiration
ct:sleep((?EXPIRE+1) * 1000),
-
+
Client2 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close_port(OpensslPort),
@@ -1163,52 +1182,21 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- "-ssl2", "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
- consume_port_exit(OpenSslPort),
- ssl_test_lib:check_result(Server, {error, {tls_alert, "bad record mac"}}),
- process_flag(trap_exit, false).
-%%--------------------------------------------------------------------
-ssl2_erlang_server_openssl_client_comp() ->
- [{doc,"Test that ssl v2 clients are rejected"}].
-
-ssl2_erlang_server_openssl_client_comp(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- V2Compat = proplists:get_value(v2_hello_compatible, Config),
-
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, [{v2_hello_compatible, V2Compat} | ServerOpts]}]),
+ {from, self()},
+ {options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
-
+
Exe = "openssl",
Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- "-ssl2", "-msg"],
-
+ "-ssl2", "-msg"],
+
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- true = port_command(OpenSslPort, Data),
-
+
ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
- consume_port_exit(OpenSslPort),
- ssl_test_lib:check_result(Server, {error, {tls_alert, "protocol version"}}),
+ ssl_test_lib:consume_port_exit(OpenSslPort),
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "bad record mac"}}),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
@@ -2023,12 +2011,6 @@ openssl_client_args(true, Hostname, Port, ServerName) ->
["s_client", "-no_ssl2", "-connect", Hostname ++ ":" ++
integer_to_list(Port), "-servername", ServerName].
-consume_port_exit(OpenSSLPort) ->
- receive
- {'EXIT', OpenSSLPort, _} ->
- ok
- end.
-
hostname_format(Hostname) ->
case lists:member($., Hostname) of
true ->
@@ -2036,3 +2018,28 @@ hostname_format(Hostname) ->
false ->
"localhost"
end.
+
+no_low_flag("-no_ssl2" = Flag) ->
+ case ssl_test_lib:supports_ssl_tls_version(sslv2) of
+ true ->
+ Flag;
+ false ->
+ ""
+ end;
+no_low_flag(Flag) ->
+ Flag.
+
+
+openssl_has_common_ciphers(Ciphers) ->
+ OCiphers = ssl_test_lib:common_ciphers(openssl),
+ has_common_ciphers(Ciphers, OCiphers).
+
+has_common_ciphers([], OCiphers) ->
+ false;
+has_common_ciphers([Cipher | Rest], OCiphers) ->
+ case lists:member(Cipher, OCiphers) of
+ true ->
+ true;
+ _ ->
+ has_common_ciphers(Rest, OCiphers)
+ end.