aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/test/ssl_to_openssl_SUITE.erl
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2010-04-20 12:00:00 +0200
committerBjörn Gustavsson <[email protected]>2010-08-20 08:50:41 +0200
commitf0dbde23b539999add8754ec84541698419fc8b5 (patch)
treec2924c60a51335f1b25ef6493b8013fb6de52c7a /lib/ssl/test/ssl_to_openssl_SUITE.erl
parentb792ebc90dca5c9ba3d75d7f3c56e2295ae5d6f3 (diff)
downloadotp-f0dbde23b539999add8754ec84541698419fc8b5.tar.gz
otp-f0dbde23b539999add8754ec84541698419fc8b5.tar.bz2
otp-f0dbde23b539999add8754ec84541698419fc8b5.zip
public_key, ssl: Patch 1112
OTP-7046 Support for Diffie-Hellman. ssl-3.11 requires public_key-0.6. OTP-8553 Moved extended key usage test for ssl values to ssl. OTP-8557 Fixes handling of the option fail_if_no_peer_cert and some undocumented options. Thanks to Rory Byrne. OTP-7046 Support for Diffie-Hellman. ssl-3.11 requires public_key-0.6. OTP-8517 New ssl now properly handles ssl renegotiation, and initiates a renegotiation if ssl/ltls-sequence numbers comes close to the max value. However RFC-5746 is not yet supported, but will be in an upcoming release. OTP-8545 When gen_tcp is configured with the {packet,http} option, it automatically switches to expect HTTP Headers after a HTTP Request/Response line has been received. This update fixes ssl to behave in the same way. Thanks to Rory Byrne. OTP-8554 Ssl now correctly verifies the extended_key_usage extension and also allows the user to verify application specific extensions by supplying an appropriate fun. OTP-8560 Fixed ssl:transport_accept/2 to return properly when socket is closed. Thanks to Rory Byrne.
Diffstat (limited to 'lib/ssl/test/ssl_to_openssl_SUITE.erl')
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl362
1 files changed, 330 insertions, 32 deletions
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index c079e12b83..cbf0447bf0 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -30,6 +30,9 @@
-define(TIMEOUT, 120000).
-define(SLEEP, 1000).
+-define(OPENSSL_RENEGOTIATE, "r\n").
+-define(OPENSSL_QUIT, "Q\n").
+-define(OPENSSL_GARBAGE, "P\n").
%% Test server callback functions
%%--------------------------------------------------------------------
@@ -114,6 +117,11 @@ all(doc) ->
all(suite) ->
[erlang_client_openssl_server,
erlang_server_openssl_client,
+ erlang_server_openssl_client_reuse_session,
+ erlang_client_openssl_server_renegotiate,
+ erlang_client_openssl_server_no_wrap_sequence_number,
+ erlang_server_openssl_client_no_wrap_sequence_number,
+ erlang_client_openssl_server_no_server_ca_cert,
ssl3_erlang_client_openssl_server,
ssl3_erlang_server_openssl_client,
ssl3_erlang_client_openssl_server_client_cert,
@@ -124,7 +132,8 @@ all(suite) ->
tls1_erlang_client_openssl_server_client_cert,
tls1_erlang_server_openssl_client_client_cert,
tls1_erlang_server_erlang_client_client_cert,
- ciphers
+ ciphers,
+ erlang_client_bad_openssl_server
].
%% Test cases starts here.
@@ -148,13 +157,13 @@ erlang_client_openssl_server(Config) when is_list(Config) ->
KeyFile = proplists:get_value(keyfile, ServerOpts),
Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile,
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile,
test_server:format("openssl cmd: ~p~n", [Cmd]),
OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- test_server:sleep(?SLEEP),
+ wait_for_openssl_server(),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -193,14 +202,199 @@ erlang_server_openssl_client(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+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."];
+erlang_server_openssl_client_reuse_session(suite) ->
+ [];
+erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = 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]}},
+ {reconnect_times, 5},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -reconnect",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_renegotiate(doc) ->
+ ["Test erlang client when openssl server issuses a renegotiate"];
+erlang_client_openssl_server_renegotiate(suite) ->
+ [];
+erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl",
+ OpenSslData = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ delayed_send, [[ErlData, OpenSslData]]}},
+ {options, ClientOpts}]),
+
+ port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
test_server:sleep(?SLEEP),
+ port_command(OpensslPort, OpenSslData),
+
+ %%ssl_test_lib:check_result(Client, ok),
+ %% Currently allow test case to not fail
+ %% if server requires secure renegotiation from RFC-5746
+ %% This should be removed as soon as we have implemented it.
+ ssl_test_lib:check_result_ignore_renegotiation_reject(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_no_wrap_sequence_number(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."];
+erlang_client_openssl_server_no_wrap_sequence_number(suite) ->
+ [];
+erlang_client_openssl_server_no_wrap_sequence_number(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl\n",
+ N = 10,
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ 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]}]),
+
+ %%ssl_test_lib:check_result(Client, ok),
+ %% Currently allow test case to not fail
+ %% if server requires secure renegotiation from RFC-5746
+ %% This should be removed as soon as we have implemented it.
+ ssl_test_lib:check_result_ignore_renegotiation_reject(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+erlang_server_openssl_client_no_wrap_sequence_number(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."];
+
+erlang_server_openssl_client_no_wrap_sequence_number(suite) ->
+ [];
+erlang_server_openssl_client_no_wrap_sequence_number(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = 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} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
- " -host localhost",
+ " -host localhost -msg",
test_server:format("openssl cmd: ~p~n", [Cmd]),
OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
port_command(OpenSslPort, Data),
ssl_test_lib:check_result(Server, ok),
@@ -210,6 +404,53 @@ erlang_server_openssl_client(Config) when is_list(Config) ->
close_port(OpenSslPort),
process_flag(trap_exit, false),
ok.
+%%--------------------------------------------------------------------
+
+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."];
+erlang_client_openssl_server_no_server_ca_cert(suite) ->
+ [];
+erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_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),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
%%--------------------------------------------------------------------
ssl3_erlang_client_openssl_server(doc) ->
@@ -233,7 +474,7 @@ ssl3_erlang_client_openssl_server(Config) when is_list(Config) ->
OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- test_server:sleep(?SLEEP),
+ wait_for_openssl_server(),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -268,8 +509,6 @@ ssl3_erlang_server_openssl_client(Config) when is_list(Config) ->
{options,
[{versions, [sslv3]} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
-
- test_server:sleep(?SLEEP),
Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
" -host localhost -ssl3",
@@ -300,8 +539,8 @@ ssl3_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
Data = "From openssl to erlang",
Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
CertFile = proplists:get_value(certfile, ServerOpts),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
KeyFile = proplists:get_value(keyfile, ServerOpts),
Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
@@ -312,7 +551,7 @@ ssl3_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- test_server:sleep(?SLEEP),
+ wait_for_openssl_server(),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -354,8 +593,6 @@ ssl3_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- test_server:sleep(?SLEEP),
-
CaCertFile = proplists:get_value(cacertfile, ClientOpts),
CertFile = proplists:get_value(certfile, ClientOpts),
KeyFile = proplists:get_value(keyfile, ClientOpts),
@@ -402,8 +639,6 @@ ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- test_server:sleep(?SLEEP),
-
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -439,14 +674,13 @@ tls1_erlang_client_openssl_server(Config) when is_list(Config) ->
KeyFile = proplists:get_value(keyfile, ServerOpts),
Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
- " -cert " ++ CertFile
- ++ " -key " ++ KeyFile ++ " -tls1",
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -tls1",
test_server:format("openssl cmd: ~p~n", [Cmd]),
OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- test_server:sleep(?SLEEP),
+ wait_for_openssl_server(),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -484,8 +718,6 @@ tls1_erlang_server_openssl_client(Config) when is_list(Config) ->
[{versions, [tlsv1]} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- test_server:sleep(?SLEEP),
-
Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
" -host localhost -tls1",
@@ -529,7 +761,7 @@ tls1_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- test_server:sleep(?SLEEP),
+ wait_for_openssl_server(),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -571,8 +803,6 @@ tls1_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- test_server:sleep(?SLEEP),
-
CaCertFile = proplists:get_value(cacertfile, ClientOpts),
CertFile = proplists:get_value(certfile, ClientOpts),
KeyFile = proplists:get_value(keyfile, ClientOpts),
@@ -617,8 +847,6 @@ tls1_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- test_server:sleep(?SLEEP),
-
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -668,14 +896,13 @@ cipher(CipherSuite, Version, Config) ->
KeyFile = proplists:get_value(keyfile, ServerOpts),
Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
- " -cert " ++ CertFile
- ++ " -key " ++ KeyFile ++ "",
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
test_server:format("openssl cmd: ~p~n", [Cmd]),
OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
- test_server:sleep(?SLEEP),
+ wait_for_openssl_server(),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -707,6 +934,52 @@ cipher(CipherSuite, Version, Config) ->
Return.
%%--------------------------------------------------------------------
+erlang_client_bad_openssl_server(doc) ->
+ [""];
+erlang_client_bad_openssl_server(suite) ->
+ [];
+erlang_client_bad_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_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),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, server_sent_garbage, []}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ %% Send garbage
+ port_command(OpensslPort, ?OPENSSL_GARBAGE),
+
+ test_server:sleep(?SLEEP),
+
+ Client ! server_sent_garbage,
+
+ ssl_test_lib:check_result(Client, true),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
erlang_ssl_receive(Socket, Data) ->
test_server:format("Connection info: ~p~n",
@@ -738,8 +1011,14 @@ connection_info(Socket, Version) ->
connection_info_result(Socket) ->
ssl:connection_info(Socket).
+
+delayed_send(Socket, [ErlData, OpenSslData]) ->
+ test_server:sleep(?SLEEP),
+ ssl:send(Socket, ErlData),
+ erlang_ssl_receive(Socket, OpenSslData).
+
close_port(Port) ->
- port_command(Port, "Q\n"),
+ port_command(Port, ?OPENSSL_QUIT),
%%catch port_command(Port, "quit\n"),
close_loop(Port, 500, false).
@@ -770,3 +1049,22 @@ close_loop(Port, Time, SentClose) ->
io:format("Timeout~n",[])
end
end.
+
+
+server_sent_garbage(Socket) ->
+ receive
+ server_sent_garbage ->
+ {error, closed} == ssl:send(Socket, "data")
+ end.
+
+wait_for_openssl_server() ->
+ receive
+ {Port, {data, Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ %% openssl has started make sure
+ %% it will be in accept. Parsing
+ %% output is too error prone. (Even
+ %% more so than sleep!)
+ test_server:sleep(?SLEEP)
+ end.
+