diff options
author | Ben Murphy <benmmurphy@gmail.com> | 2011-12-11 18:10:55 +0000 |
---|---|---|
committer | Ingela Anderton Andin <ingela@erlang.org> | 2012-09-20 14:37:03 +0200 |
commit | a2ee149615fc551e82d7d7df5126962e96dcab74 (patch) | |
tree | 51c7042f9fb3afeedc905aa017bff988af71fd11 /lib/ssl/test/ssl_to_openssl_SUITE.erl | |
parent | b58ce62a0cf296ca8cd8cd77b053bc70ecf28758 (diff) | |
download | otp-a2ee149615fc551e82d7d7df5126962e96dcab74.tar.gz otp-a2ee149615fc551e82d7d7df5126962e96dcab74.tar.bz2 otp-a2ee149615fc551e82d7d7df5126962e96dcab74.zip |
ssl: Support for SSL Next Protocol Negotiation
* http://technotes.googlecode.com/git/nextprotoneg.html
Diffstat (limited to 'lib/ssl/test/ssl_to_openssl_SUITE.erl')
-rw-r--r-- | lib/ssl/test/ssl_to_openssl_SUITE.erl | 271 |
1 files changed, 269 insertions, 2 deletions
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index d446014f7b..cc3c6439ac 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -114,6 +114,17 @@ special_init(TestCase, Config) special_init(ssl2_erlang_server_openssl_client, Config) -> check_sane_openssl_sslv2(Config); +special_init(TestCase, Config) + when TestCase == erlang_client_openssl_server_npn_negotiation; + TestCase == erlang_server_openssl_client_npn_negotiation; + TestCase == erlang_server_openssl_client_npn_negotiation_and_renegotiate; + TestCase == erlang_client_openssl_server_npn_negotiation_and_renegotiate; + TestCase == erlang_server_openssl_client_npn_negotiate_only_on_server; + TestCase == erlang_server_openssl_client_npn_negotiate_only_on_client; + TestCase == erlang_client_openssl_server_npn_negotiate_only_on_client; + TestCase == erlang_client_openssl_server_npn_negotiate_only_on_server -> + check_openssl_npn_support(Config); + special_init(_, Config) -> Config. @@ -187,8 +198,16 @@ all_versions_tests() -> ciphers_rsa_signed_certs, ciphers_dsa_signed_certs, erlang_client_bad_openssl_server, - ssl2_erlang_server_openssl_client - ]. + expired_session, + ssl2_erlang_server_openssl_client, + erlang_client_openssl_server_npn_negotiation, + erlang_server_openssl_client_npn_negotiation, + erlang_server_openssl_client_npn_negotiation_and_renegotiate, + erlang_client_openssl_server_npn_negotiation_and_renegotiate, + erlang_server_openssl_client_npn_negotiate_only_on_client, + erlang_server_openssl_client_npn_negotiate_only_on_server, + erlang_client_openssl_server_npn_negotiate_only_on_client, + erlang_client_openssl_server_npn_negotiate_only_on_server]. init_per_group(GroupName, Config) -> case ssl_test_lib:is_tls_version(GroupName) of @@ -1069,6 +1088,245 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) -> ok. %%-------------------------------------------------------------------- +erlang_client_openssl_server_npn_negotiation(doc) -> + ["Test erlang client with openssl server doing npn negotiation"]; +erlang_client_openssl_server_npn_negotiation(suite) -> + []; +erlang_client_openssl_server_npn_negotiation(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, fun(Client, OpensslPort) -> + port_command(OpensslPort, Data), + + ssl_test_lib:check_result(Client, ok) + end), + + ok. + + +%%-------------------------------------------------------------------- +erlang_client_openssl_server_npn_negotiation_and_renegotiate(doc) -> + ["Test erlang client with openssl server doing npn negotiation and renegotiate"]; +erlang_client_openssl_server_npn_negotiation_and_renegotiate(suite) -> + []; +erlang_client_openssl_server_npn_negotiation_and_renegotiate(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, fun(Client, OpensslPort) -> + port_command(OpensslPort, ?OPENSSL_RENEGOTIATE), + test_server:sleep(?SLEEP), + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Client, ok) + end), + ok. + + +%%-------------------------------------------------------------------------- + + +erlang_server_openssl_client_npn_negotiation(doc) -> + ["Test erlang server with openssl client and npn negotiation"]; +erlang_server_openssl_client_npn_negotiation(suite) -> + []; +erlang_server_openssl_client_npn_negotiation(Config) when is_list(Config) -> + + Data = "From openssl to erlang", + start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, fun(Server, OpensslPort) -> + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Server, ok) + end), + ok. + +%%-------------------------------------------------------------------------- + +erlang_server_openssl_client_npn_negotiation_and_renegotiate(doc) -> + ["Test erlang server with openssl client and npn negotiation with renegotiation"]; +erlang_server_openssl_client_npn_negotiation_and_renegotiate(suite) -> + []; +erlang_server_openssl_client_npn_negotiation_and_renegotiate(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, fun(Server, OpensslPort) -> + port_command(OpensslPort, ?OPENSSL_RENEGOTIATE), + test_server:sleep(?SLEEP), + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Server, ok) + end), + ok. +%%-------------------------------------------------------------------------- + +erlang_client_openssl_server_npn_negotiate_only_on_server(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_client_and_openssl_server_with_opts(Config, [], "-nextprotoneg spdy/2", Data, fun(Server, OpensslPort) -> + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Server, ok) + end), + ok. + +%%-------------------------------------------------------------------------- + +erlang_client_openssl_server_npn_negotiate_only_on_client(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_client_and_openssl_server_with_opts(Config, [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"spdy/2">>]}}], "", Data, fun(Server, OpensslPort) -> + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Server, ok) + end), + ok. + +%%-------------------------------------------------------------------------- +erlang_server_openssl_client_npn_negotiate_only_on_server(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_server_and_openssl_client_with_opts(Config, [{next_protocols_advertised, [<<"spdy/2">>]}], "", Data, fun(Server, OpensslPort) -> + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Server, ok) + end), + ok. + +erlang_server_openssl_client_npn_negotiate_only_on_client(Config) when is_list(Config) -> + Data = "From openssl to erlang", + start_erlang_server_and_openssl_client_with_opts(Config, [], "-nextprotoneg spdy/2", Data, fun(Server, OpensslPort) -> + port_command(OpensslPort, Data), + ssl_test_lib:check_result(Server, ok) + end), + ok. + +%%-------------------------------------------------------------------------- + +start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, OpensslServerOpts, Data, Callback) -> + process_flag(trap_exit, true), + ServerOpts = ?config(server_opts, Config), + ClientOpts0 = ?config(client_opts, Config), + ClientOpts = ErlangClientOpts ++ ClientOpts0, + + {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 " ++ OpensslServerOpts ++ " -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, + erlang_ssl_receive, [Data]}}, + {options, ClientOpts}]), + + Callback(Client, OpensslPort), + + %% Clean close down! Server needs to be closed first !! + close_port(OpensslPort), + + ssl_test_lib:close(Client), + process_flag(trap_exit, false). + +start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callback) -> + process_flag(trap_exit, true), + ServerOpts = ?config(server_opts, Config), + ClientOpts0 = ?config(client_opts, Config), + ClientOpts = [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"spdy/2">>]}} | ClientOpts0], + + {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 -msg -nextprotoneg http/1.1,spdy/2 -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, + erlang_ssl_receive_and_assert_npn, [<<"spdy/2">>, Data]}}, + {options, ClientOpts}]), + + Callback(Client, OpensslPort), + + %% Clean close down! Server needs to be closed first !! + close_port(OpensslPort), + + ssl_test_lib:close(Client), + process_flag(trap_exit, false). + +start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callback) -> + process_flag(trap_exit, true), + ServerOpts0 = ?config(server_opts, Config), + ServerOpts = [{next_protocols_advertised, [<<"spdy/2">>]}, ServerOpts0], + + {_, ServerNode, _} = ssl_test_lib:run_where(Config), + + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, erlang_ssl_receive_and_assert_npn, [<<"spdy/2">>, Data]}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Cmd = "openssl s_client -nextprotoneg http/1.0,spdy/2 -msg -port " ++ integer_to_list(Port) ++ + " -host localhost", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + + Callback(Server, OpenSslPort), + + ssl_test_lib:close(Server), + + close_port(OpenSslPort), + process_flag(trap_exit, false). + +start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenSSLClientOpts, Data, Callback) -> + process_flag(trap_exit, true), + ServerOpts0 = ?config(server_opts, Config), + ServerOpts = ErlangServerOpts ++ ServerOpts0, + + {_, ServerNode, _} = ssl_test_lib:run_where(Config), + + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, erlang_ssl_receive, [Data]}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Cmd = "openssl s_client " ++ OpenSSLClientOpts ++ " -msg -port " ++ integer_to_list(Port) ++ + " -host localhost", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + + Callback(Server, OpenSslPort), + + ssl_test_lib:close(Server), + + close_port(OpenSslPort), + process_flag(trap_exit, false). + + +erlang_ssl_receive_and_assert_npn(Socket, Protocol, Data) -> + {ok, Protocol} = ssl:negotiated_next_protocol(Socket), + erlang_ssl_receive(Socket, Data), + {ok, Protocol} = ssl:negotiated_next_protocol(Socket), + ok. erlang_ssl_receive(Socket, Data) -> test_server:format("Connection info: ~p~n", @@ -1168,6 +1426,15 @@ version_flag('tlsv1.2') -> version_flag(sslv3) -> " -ssl3 ". +check_openssl_npn_support(Config) -> + HelpText = os:cmd("openssl s_client --help"), + case string:str(HelpText, "nextprotoneg") of + 0 -> + {skip, "Openssl not compiled with nextprotoneg support"}; + _ -> + Config + end. + check_sane_openssl_renegotaite(Config) -> case os:cmd("openssl version") of "OpenSSL 0.9.8" ++ _ -> |