From a2ee149615fc551e82d7d7df5126962e96dcab74 Mon Sep 17 00:00:00 2001 From: Ben Murphy Date: Sun, 11 Dec 2011 18:10:55 +0000 Subject: ssl: Support for SSL Next Protocol Negotiation * http://technotes.googlecode.com/git/nextprotoneg.html --- lib/ssl/test/Makefile | 2 + lib/ssl/test/make_certs.erl | 19 ++- lib/ssl/test/ssl_npn_handshake_SUITE.erl | 218 +++++++++++++++++++++++++ lib/ssl/test/ssl_npn_hello_SUITE.erl | 115 +++++++++++++ lib/ssl/test/ssl_to_openssl_SUITE.erl | 271 ++++++++++++++++++++++++++++++- 5 files changed, 620 insertions(+), 5 deletions(-) create mode 100644 lib/ssl/test/ssl_npn_handshake_SUITE.erl create mode 100644 lib/ssl/test/ssl_npn_hello_SUITE.erl (limited to 'lib/ssl/test') diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index 343157b22e..d36dcb588b 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -44,6 +44,8 @@ MODULES = \ ssl_to_openssl_SUITE \ ssl_session_cache_SUITE \ ssl_dist_SUITE \ + ssl_npn_hello_SUITE \ + ssl_npn_handshake_SUITE \ make_certs\ erl_make_certs diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl index 693289990c..4603a9f846 100644 --- a/lib/ssl/test/make_certs.erl +++ b/lib/ssl/test/make_certs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -121,7 +121,19 @@ create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) -> " -keyout ", KeyFile, " -out ", CertFile], Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env). + cmd(Cmd, Env), + fix_key_file(OpenSSLCmd, KeyFile). + +% openssl 1.0 generates key files in pkcs8 format by default and we don't handle this format +fix_key_file(OpenSSLCmd, KeyFile) -> + KeyFileTmp = KeyFile ++ ".tmp", + Cmd = [OpenSSLCmd, " rsa", + " -in ", + KeyFile, + " -out ", + KeyFileTmp], + cmd(Cmd, []), + ok = file:rename(KeyFileTmp, KeyFile). create_ca_dir(Root, CAName, Cnf) -> CARoot = filename:join([Root, CAName]), @@ -139,7 +151,8 @@ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) -> " -keyout ", KeyFile, " -out ", ReqFile], Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env). + cmd(Cmd, Env), + fix_key_file(OpenSSLCmd, KeyFile). sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) -> CACnfFile = filename:join([Root, CA, "ca.cnf"]), diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl new file mode 100644 index 0000000000..f2327756c3 --- /dev/null +++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl @@ -0,0 +1,218 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% 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% +%% + +%% +-module(ssl_npn_handshake_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). +-include_lib("common_test/include/ct.hrl"). + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +init_per_suite(Config) -> + try crypto:start() of + ok -> + application:start(public_key), + ssl:start(), + Result = + (catch make_certs:all(?config(data_dir, Config), + ?config(priv_dir, Config))), + test_server:format("Make certs ~p~n", [Result]), + ssl_test_lib:cert_options(Config) + catch _:_ -> + {skip, "Crypto did not start"} + end. + +end_per_suite(_Config) -> + ssl:stop(), + application:stop(crypto). + + +all() -> + [validate_empty_protocols_are_not_allowed_test, + validate_empty_advertisement_list_is_allowed_test, + validate_advertisement_must_be_a_binary_list_test, + validate_client_protocols_must_be_a_tuple_test, + perform_normal_npn_handshake_server_preference_test, + perform_normal_npn_handshake_client_preference_test, + perform_fallback_npn_handshake_test, + perform_fallback_npn_handshake_server_preference_test, + perform_client_tries_to_negotiate_but_server_does_not_support_test, + perform_client_does_not_try_to_negotiate_but_server_supports_npn_test, + perform_renegotiate_from_client_after_npn_handshake]. + +connection_info_result(Socket) -> + ssl:connection_info(Socket). + +validate_empty_protocols_are_not_allowed_test(_Config) -> + {error, {eoptions, {next_protocols_advertised, <<>>}}} = (catch ssl:listen(9443, [{next_protocols_advertised, [<<"foo/1">>, <<"">>]}])), + {error, {eoptions, {client_preferred_next_protocols, <<>>}}} = (catch ssl:connect({127,0,0,1}, 9443, [{client_preferred_next_protocols, {<<"foox/1">>, client, [<<"foo/1">>, <<"">>]}}], infinity)), + Option = {client_preferred_next_protocols, {<<"">>, client, [<<"foo/1">>, <<"blah/1">>]}}, + {error, {eoptions, Option}} = (catch ssl:connect({127,0,0,1}, 9443, [Option], infinity)). + +validate_empty_advertisement_list_is_allowed_test(_Config) -> + Option = {next_protocols_advertised, []}, + {ok, Socket} = ssl:listen(0, [Option]), + ssl:close(Socket). + +validate_advertisement_must_be_a_binary_list_test(_Config) -> + Option = {next_protocols_advertised, blah}, + {error, {eoptions, Option}} = (catch ssl:listen(9443, [Option])). + +validate_client_protocols_must_be_a_tuple_test(_Config) -> + Option = {client_preferred_next_protocols, [<<"foo/1">>]}, + {error, {eoptions, Option}} = (catch ssl:connect({127,0,0,1}, 9443, [Option])). + + + +perform_client_does_not_try_to_negotiate_but_server_supports_npn_test(Config) -> + run_npn_handshake_test(Config, + [], + [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], + {error, next_protocol_not_negotiated}). + +perform_client_tries_to_negotiate_but_server_does_not_support_test(Config) -> + run_npn_handshake_test(Config, + [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"spdy/2">>]}}], + [], + {error, next_protocol_not_negotiated}). + +perform_fallback_npn_handshake_test(Config) -> + run_npn_handshake_test(Config, + [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"spdy/2">>]}}], + [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.1">>}). + +perform_fallback_npn_handshake_server_preference_test(Config) -> + run_npn_handshake_test(Config, + [{client_preferred_next_protocols, {<<"http/1.1">>, server, [<<"spdy/2">>]}}], + [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.1">>}). + + +perform_normal_npn_handshake_client_preference_test(Config) -> + run_npn_handshake_test(Config, + [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"http/1.0">>, <<"http/1.1">>]}}], + [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.0">>}). + +perform_normal_npn_handshake_server_preference_test(Config) -> + run_npn_handshake_test(Config, + [{client_preferred_next_protocols, {<<"http/1.1">>, server, [<<"http/1.0">>, <<"http/1.1">>]}}], + [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.1">>}). + + +perform_renegotiate_from_client_after_npn_handshake(Config) -> + Data = "hello world", + + ClientOpts0 = ?config(client_opts, Config), + ClientOpts = [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"http/1.0">>]}}] ++ ClientOpts0, + ServerOpts0 = ?config(server_opts, Config), + ServerOpts = [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++ ServerOpts0, + ExpectedProtocol = {ok, <<"http/1.0">>}, + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, ssl_receive_and_assert_npn, [ExpectedProtocol, Data]}}, + {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, assert_npn_and_renegotiate_and_send_data, [ExpectedProtocol, Data]}}, + {options, ClientOpts}]), + + ssl_test_lib:check_result(Server, ok, Client, ok). + +%-------------------------------------------------------------------------------- + +run_npn_handshake_test(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) -> + Data = "hello world", + + ClientOpts0 = ?config(client_opts, Config), + ClientOpts = ClientExtraOpts ++ ClientOpts0, + ServerOpts0 = ?config(server_opts, Config), + ServerOpts = ServerExtraOpts ++ ServerOpts0, + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, ssl_receive_and_assert_npn, [ExpectedProtocol, Data]}}, + {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, ssl_send_and_assert_npn, [ExpectedProtocol, Data]}}, + {options, ClientOpts}]), + + ssl_test_lib:check_result(Server, ok, Client, ok). + +assert_npn(Socket, Protocol) -> + test_server:format("Negotiated Protocol ~p, Expecting: ~p ~n", [ssl:negotiated_next_protocol(Socket), Protocol]), + Protocol = ssl:negotiated_next_protocol(Socket). + +assert_npn_and_renegotiate_and_send_data(Socket, Protocol, Data) -> + assert_npn(Socket, Protocol), + test_server:format("Renegotiating ~n", []), + ok = ssl:renegotiate(Socket), + ssl:send(Socket, Data), + assert_npn(Socket, Protocol), + ok. + +ssl_send_and_assert_npn(Socket, Protocol, Data) -> + assert_npn(Socket, Protocol), + ssl_send(Socket, Data). + +ssl_receive_and_assert_npn(Socket, Protocol, Data) -> + assert_npn(Socket, Protocol), + ssl_receive(Socket, Data). + +ssl_send(Socket, Data) -> + test_server:format("Connection info: ~p~n", + [ssl:connection_info(Socket)]), + ssl:send(Socket, Data). + +ssl_receive(Socket, Data) -> + ssl_receive(Socket, Data, []). + +ssl_receive(Socket, Data, Buffer) -> + test_server:format("Connection info: ~p~n", + [ssl:connection_info(Socket)]), + receive + {ssl, Socket, MoreData} -> + test_server:format("Received ~p~n",[MoreData]), + NewBuffer = Buffer ++ MoreData, + case NewBuffer of + Data -> + ssl:send(Socket, "Got it"), + ok; + _ -> + ssl_receive(Socket, Data, NewBuffer) + end; + Other -> + test_server:fail({unexpected_message, Other}) + after 4000 -> + test_server:fail({did_not_get, Data}) + end. diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl new file mode 100644 index 0000000000..f177778178 --- /dev/null +++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl @@ -0,0 +1,115 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% 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% +%% + +%% + +-module(ssl_npn_hello_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). +-include("ssl_handshake.hrl"). +-include("ssl_record.hrl"). +-include_lib("common_test/include/ct.hrl"). + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [encode_and_decode_npn_client_hello_test, + encode_and_decode_npn_server_hello_test, + encode_and_decode_client_hello_test, + encode_and_decode_server_hello_test, + create_server_hello_with_advertised_protocols_test, + create_server_hello_with_no_advertised_protocols_test]. + + +create_client_handshake(Npn) -> + ssl_handshake:encode_handshake(#client_hello{ + client_version = {1, 2}, + random = <<1:256>>, + session_id = <<>>, + cipher_suites = "", + compression_methods = "", + next_protocol_negotiation = Npn, + renegotiation_info = #renegotiation_info{} + }, vsn). + + +encode_and_decode_client_hello_test(_Config) -> + HandShakeData = create_client_handshake(undefined), + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + {[{DecodedHandshakeMessage, _Raw}], _} = ssl_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), + NextProtocolNegotiation = DecodedHandshakeMessage#client_hello.next_protocol_negotiation, + NextProtocolNegotiation = undefined. + +encode_and_decode_npn_client_hello_test(_Config) -> + HandShakeData = create_client_handshake(#next_protocol_negotiation{extension_data = <<>>}), + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + {[{DecodedHandshakeMessage, _Raw}], _} = ssl_handshake:get_tls_handshake(Version¸ list_to_binary(HandShakeData), <<>>), + NextProtocolNegotiation = DecodedHandshakeMessage#client_hello.next_protocol_negotiation, + NextProtocolNegotiation = #next_protocol_negotiation{extension_data = <<>>}. + +create_server_handshake(Npn) -> + ssl_handshake:encode_handshake(#server_hello{ + server_version = {1, 2}, + random = <<1:256>>, + session_id = <<>>, + cipher_suite = <<1,2>>, + compression_method = 1, + next_protocol_negotiation = Npn, + renegotiation_info = #renegotiation_info{} + }, vsn). + +encode_and_decode_server_hello_test(_Config) -> + HandShakeData = create_server_handshake(undefined), + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + {[{DecodedHandshakeMessage, _Raw}], _} = + ssl_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), + NextProtocolNegotiation = DecodedHandshakeMessage#server_hello.next_protocol_negotiation, + NextProtocolNegotiation = undefined. + +encode_and_decode_npn_server_hello_test(_Config) -> + HandShakeData = create_server_handshake(#next_protocol_negotiation{extension_data = <<6, "spdy/2">>}), + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + {[{DecodedHandshakeMessage, _Raw}], _} = ssl_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), + NextProtocolNegotiation = DecodedHandshakeMessage#server_hello.next_protocol_negotiation, + ct:print("~p ~n", [NextProtocolNegotiation]), + NextProtocolNegotiation = #next_protocol_negotiation{extension_data = <<6, "spdy/2">>}. + +create_connection_states() -> + #connection_states{ + pending_read = #connection_state{ + security_parameters = #security_parameters{ + server_random = <<1:256>>, + compression_algorithm = 1, + cipher_suite = <<1, 2>> + } + }, + + current_read = #connection_state { + secure_renegotiation = false + } + }. + +create_server_hello_with_no_advertised_protocols_test(_Config) -> + Hello = ssl_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), false, undefined), + undefined = Hello#server_hello.next_protocol_negotiation. + +create_server_hello_with_advertised_protocols_test(_Config) -> + Hello = ssl_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), false, [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>]), + #next_protocol_negotiation{extension_data = <<6, "spdy/1", 8, "http/1.0", 8, "http/1.1">>} = Hello#server_hello.next_protocol_negotiation. 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" ++ _ -> -- cgit v1.2.3 From 1e0d466f198842cfed14f4fae906381c39bd2050 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 19 Sep 2012 12:14:20 +0200 Subject: ssl: Changed default behaviour of next protocol negotiation to make more "sense" (be true to the specification). --- lib/ssl/test/ssl_npn_handshake_SUITE.erl | 50 +++++++++++++++++++------------- lib/ssl/test/ssl_npn_hello_SUITE.erl | 2 +- lib/ssl/test/ssl_to_openssl_SUITE.erl | 31 +++++++++++--------- 3 files changed, 49 insertions(+), 34 deletions(-) (limited to 'lib/ssl/test') diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl index f2327756c3..8bef2d8d22 100644 --- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl +++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl @@ -28,16 +28,16 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. init_per_suite(Config) -> try crypto:start() of - ok -> - application:start(public_key), - ssl:start(), - Result = - (catch make_certs:all(?config(data_dir, Config), - ?config(priv_dir, Config))), - test_server:format("Make certs ~p~n", [Result]), - ssl_test_lib:cert_options(Config) + ok -> + application:start(public_key), + ssl:start(), + Result = + (catch make_certs:all(?config(data_dir, Config), + ?config(priv_dir, Config))), + test_server:format("Make certs ~p~n", [Result]), + ssl_test_lib:cert_options(Config) catch _:_ -> - {skip, "Crypto did not start"} + {skip, "Crypto did not start"} end. end_per_suite(_Config) -> @@ -62,9 +62,14 @@ connection_info_result(Socket) -> ssl:connection_info(Socket). validate_empty_protocols_are_not_allowed_test(_Config) -> - {error, {eoptions, {next_protocols_advertised, <<>>}}} = (catch ssl:listen(9443, [{next_protocols_advertised, [<<"foo/1">>, <<"">>]}])), - {error, {eoptions, {client_preferred_next_protocols, <<>>}}} = (catch ssl:connect({127,0,0,1}, 9443, [{client_preferred_next_protocols, {<<"foox/1">>, client, [<<"foo/1">>, <<"">>]}}], infinity)), - Option = {client_preferred_next_protocols, {<<"">>, client, [<<"foo/1">>, <<"blah/1">>]}}, + {error, {eoptions, {next_protocols_advertised, {invalid_protocol, <<>>}}}} + = (catch ssl:listen(9443, + [{next_protocols_advertised, [<<"foo/1">>, <<"">>]}])), + {error, {eoptions, {client_preferred_next_protocols, {invalid_protocol, <<>>}}}} + = (catch ssl:connect({127,0,0,1}, 9443, + [{client_preferred_next_protocols, + {client, [<<"foo/1">>, <<"">>], <<"foox/1">>}}], infinity)), + Option = {client_preferred_next_protocols, {invalid_protocol, <<"">>}}, {error, {eoptions, Option}} = (catch ssl:connect({127,0,0,1}, 9443, [Option], infinity)). validate_empty_advertisement_list_is_allowed_test(_Config) -> @@ -90,32 +95,34 @@ perform_client_does_not_try_to_negotiate_but_server_supports_npn_test(Config) -> perform_client_tries_to_negotiate_but_server_does_not_support_test(Config) -> run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"spdy/2">>]}}], + [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], [], {error, next_protocol_not_negotiated}). perform_fallback_npn_handshake_test(Config) -> run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"spdy/2">>]}}], + [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], {ok, <<"http/1.1">>}). perform_fallback_npn_handshake_server_preference_test(Config) -> run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {<<"http/1.1">>, server, [<<"spdy/2">>]}}], + [{client_preferred_next_protocols, {server, [<<"spdy/2">>], <<"http/1.1">>}}], [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], {ok, <<"http/1.1">>}). perform_normal_npn_handshake_client_preference_test(Config) -> run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"http/1.0">>, <<"http/1.1">>]}}], + [{client_preferred_next_protocols, + {client, [<<"http/1.0">>, <<"http/1.1">>], <<"http/1.1">>}}], [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], {ok, <<"http/1.0">>}). perform_normal_npn_handshake_server_preference_test(Config) -> run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {<<"http/1.1">>, server, [<<"http/1.0">>, <<"http/1.1">>]}}], + [{client_preferred_next_protocols, + {server, [<<"http/1.0">>, <<"http/1.1">>], <<"http/1.1">>}}], [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], {ok, <<"http/1.1">>}). @@ -124,9 +131,11 @@ perform_renegotiate_from_client_after_npn_handshake(Config) -> Data = "hello world", ClientOpts0 = ?config(client_opts, Config), - ClientOpts = [{client_preferred_next_protocols, {<<"http/1.1">>, client, [<<"http/1.0">>]}}] ++ ClientOpts0, + ClientOpts = [{client_preferred_next_protocols, + {client, [<<"http/1.0">>], <<"http/1.1">>}}] ++ ClientOpts0, ServerOpts0 = ?config(server_opts, Config), - ServerOpts = [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++ ServerOpts0, + ServerOpts = [{next_protocols_advertised, + [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++ ServerOpts0, ExpectedProtocol = {ok, <<"http/1.0">>}, {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -170,7 +179,8 @@ run_npn_handshake_test(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtoco ssl_test_lib:check_result(Server, ok, Client, ok). assert_npn(Socket, Protocol) -> - test_server:format("Negotiated Protocol ~p, Expecting: ~p ~n", [ssl:negotiated_next_protocol(Socket), Protocol]), + test_server:format("Negotiated Protocol ~p, Expecting: ~p ~n", + [ssl:negotiated_next_protocol(Socket), Protocol]), Protocol = ssl:negotiated_next_protocol(Socket). assert_npn_and_renegotiate_and_send_data(Socket, Protocol, Data) -> diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl index f177778178..0bca8bbeb4 100644 --- a/lib/ssl/test/ssl_npn_hello_SUITE.erl +++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl @@ -60,7 +60,7 @@ encode_and_decode_client_hello_test(_Config) -> encode_and_decode_npn_client_hello_test(_Config) -> HandShakeData = create_client_handshake(#next_protocol_negotiation{extension_data = <<>>}), Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), - {[{DecodedHandshakeMessage, _Raw}], _} = ssl_handshake:get_tls_handshake(Version¸ list_to_binary(HandShakeData), <<>>), + {[{DecodedHandshakeMessage, _Raw}], _} = ssl_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), NextProtocolNegotiation = DecodedHandshakeMessage#client_hello.next_protocol_negotiation, NextProtocolNegotiation = #next_protocol_negotiation{extension_data = <<>>}. diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index cc3c6439ac..30f8f60156 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -29,7 +29,7 @@ -define(TIMEOUT, 120000). -define(LONG_TIMEOUT, 600000). -define(SLEEP, 1000). --define(OPENSSL_RENEGOTIATE, "r\n"). +-define(OPENSSL_RENEGOTIATE, "R\n"). -define(OPENSSL_QUIT, "Q\n"). -define(OPENSSL_GARBAGE, "P\n"). -define(EXPIRE, 10). @@ -172,9 +172,9 @@ all() -> groups() -> [{basic, [], basic_tests()}, - {'tlsv1.2', [], all_versions_tests()}, - {'tlsv1.1', [], all_versions_tests()}, - {'tlsv1', [], all_versions_tests()}, + {'tlsv1.2', [], all_versions_tests() ++ npn_tests()}, + {'tlsv1.1', [], all_versions_tests() ++ npn_tests()}, + {'tlsv1', [], all_versions_tests()++ npn_tests()}, {'sslv3', [], all_versions_tests()}]. basic_tests() -> @@ -199,8 +199,10 @@ all_versions_tests() -> ciphers_dsa_signed_certs, erlang_client_bad_openssl_server, expired_session, - ssl2_erlang_server_openssl_client, - erlang_client_openssl_server_npn_negotiation, + ssl2_erlang_server_openssl_client]. + +npn_tests() -> + [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, @@ -1164,7 +1166,7 @@ erlang_client_openssl_server_npn_negotiate_only_on_server(Config) when is_list(C 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) -> + start_erlang_client_and_openssl_server_with_opts(Config, [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], "", Data, fun(Server, OpensslPort) -> port_command(OpensslPort, Data), ssl_test_lib:check_result(Server, ok) end), @@ -1202,9 +1204,11 @@ start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, Opens Port = ssl_test_lib:inet_port(node()), CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), - Cmd = "openssl s_server " ++ OpensslServerOpts ++ " -accept " ++ integer_to_list(Port) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile, + Cmd = "openssl s_server " ++ OpensslServerOpts ++ " -accept " ++ + integer_to_list(Port) ++ version_flag(Version) ++ + " -cert " ++ CertFile ++ " -key " ++ KeyFile, test_server:format("openssl cmd: ~p~n", [Cmd]), @@ -1231,7 +1235,7 @@ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callbac 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], + ClientOpts = [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}} | ClientOpts0], {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), @@ -1240,8 +1244,9 @@ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callbac Port = ssl_test_lib:inet_port(node()), CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), - Cmd = "openssl s_server -msg -nextprotoneg http/1.1,spdy/2 -accept " ++ integer_to_list(Port) ++ + Cmd = "openssl s_server -msg -nextprotoneg http/1.1,spdy/2 -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile, test_server:format("openssl cmd: ~p~n", [Cmd]), @@ -1278,8 +1283,8 @@ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callbac {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) ++ + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + Cmd = "openssl s_client -nextprotoneg http/1.0,spdy/2 -msg -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ " -host localhost", test_server:format("openssl cmd: ~p~n", [Cmd]), -- cgit v1.2.3 From c1fbf30d1fb4bcae9ddbc6e444447132af14030b Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 19 Sep 2012 16:47:53 +0200 Subject: ssl: Dialyzer fixes and code cleaning Types in a record where wrongly type specified, did not include undefined. Make them comments for now, maybe we will specify internal records with dialyzer types later, but as the other record fields are not specified at the moment, with dialyzer types, make the code consistent. --- lib/ssl/test/ssl_npn_handshake_SUITE.erl | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/ssl/test') diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl index 8bef2d8d22..eef09f42f2 100644 --- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl +++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl @@ -27,6 +27,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. init_per_suite(Config) -> + catch crypto:stop(), try crypto:start() of ok -> application:start(public_key), -- cgit v1.2.3 From 67989c3ad3fd6258ed766309fd67f9a2fa192b3f Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 21 Sep 2012 15:57:25 +0200 Subject: ssl: SSL 3.0 does not support next protocol negotiation Also shorten test cases names to workaround test framework problems on windows --- lib/ssl/test/ssl_npn_handshake_SUITE.erl | 187 ++++++++++++++++++++++--------- lib/ssl/test/ssl_npn_hello_SUITE.erl | 6 +- 2 files changed, 138 insertions(+), 55 deletions(-) (limited to 'lib/ssl/test') diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl index eef09f42f2..cfeb328e21 100644 --- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl +++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl @@ -26,6 +26,39 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. +all() -> + [{group, 'tlsv1.2'}, + {group, 'tlsv1.1'}, + {group, 'tlsv1'}, + {group, 'sslv3'}]. + +groups() -> + [ + {'tlsv1.2', [], next_protocol_tests()}, + {'tlsv1.1', [], next_protocol_tests()}, + {'tlsv1', [], next_protocol_tests()}, + {'sslv3', [], next_protocol_not_supported()} + ]. + +next_protocol_tests() -> + [validate_empty_protocols_are_not_allowed, + validate_empty_advertisement_list_is_allowed, + validate_advertisement_must_be_a_binary_list, + validate_client_protocols_must_be_a_tuple, + normal_npn_handshake_server_preference, + normal_npn_handshake_client_preference, + fallback_npn_handshake, + fallback_npn_handshake_server_preference, + client_tries_to_negotiate_but_server_does_not_support, + client_does_not_try_to_negotiate_but_server_supports_npn, + renegotiate_from_client_after_npn_handshake + ]. + +next_protocol_not_supported() -> + [npn_not_supported_client, + npn_not_supported_server + ]. + init_per_suite(Config) -> catch crypto:stop(), try crypto:start() of @@ -46,23 +79,30 @@ end_per_suite(_Config) -> application:stop(crypto). -all() -> - [validate_empty_protocols_are_not_allowed_test, - validate_empty_advertisement_list_is_allowed_test, - validate_advertisement_must_be_a_binary_list_test, - validate_client_protocols_must_be_a_tuple_test, - perform_normal_npn_handshake_server_preference_test, - perform_normal_npn_handshake_client_preference_test, - perform_fallback_npn_handshake_test, - perform_fallback_npn_handshake_server_preference_test, - perform_client_tries_to_negotiate_but_server_does_not_support_test, - perform_client_does_not_try_to_negotiate_but_server_supports_npn_test, - perform_renegotiate_from_client_after_npn_handshake]. +init_per_group(GroupName, Config) -> + case ssl_test_lib:is_tls_version(GroupName) of + true -> + case ssl_test_lib:sufficient_crypto_support(GroupName) of + true -> + ssl_test_lib:init_tls_version(GroupName), + Config; + false -> + {skip, "Missing crypto support"} + end; + _ -> + ssl:start(), + Config + end. -connection_info_result(Socket) -> - ssl:connection_info(Socket). -validate_empty_protocols_are_not_allowed_test(_Config) -> +end_per_group(_GroupName, Config) -> + Config. + + +%% Test cases starts here. +%%-------------------------------------------------------------------- + +validate_empty_protocols_are_not_allowed(Config) when is_list(Config) -> {error, {eoptions, {next_protocols_advertised, {invalid_protocol, <<>>}}}} = (catch ssl:listen(9443, [{next_protocols_advertised, [<<"foo/1">>, <<"">>]}])), @@ -73,64 +113,75 @@ validate_empty_protocols_are_not_allowed_test(_Config) -> Option = {client_preferred_next_protocols, {invalid_protocol, <<"">>}}, {error, {eoptions, Option}} = (catch ssl:connect({127,0,0,1}, 9443, [Option], infinity)). -validate_empty_advertisement_list_is_allowed_test(_Config) -> +%-------------------------------------------------------------------------------- + +validate_empty_advertisement_list_is_allowed(Config) when is_list(Config) -> Option = {next_protocols_advertised, []}, {ok, Socket} = ssl:listen(0, [Option]), ssl:close(Socket). +%-------------------------------------------------------------------------------- -validate_advertisement_must_be_a_binary_list_test(_Config) -> +validate_advertisement_must_be_a_binary_list(Config) when is_list(Config) -> Option = {next_protocols_advertised, blah}, {error, {eoptions, Option}} = (catch ssl:listen(9443, [Option])). +%-------------------------------------------------------------------------------- -validate_client_protocols_must_be_a_tuple_test(_Config) -> +validate_client_protocols_must_be_a_tuple(Config) when is_list(Config) -> Option = {client_preferred_next_protocols, [<<"foo/1">>]}, {error, {eoptions, Option}} = (catch ssl:connect({127,0,0,1}, 9443, [Option])). +%-------------------------------------------------------------------------------- +normal_npn_handshake_server_preference(Config) when is_list(Config) -> + run_npn_handshake(Config, + [{client_preferred_next_protocols, + {server, [<<"http/1.0">>, <<"http/1.1">>], <<"http/1.1">>}}], + [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.1">>}). +%-------------------------------------------------------------------------------- -perform_client_does_not_try_to_negotiate_but_server_supports_npn_test(Config) -> - run_npn_handshake_test(Config, - [], - [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], - {error, next_protocol_not_negotiated}). +normal_npn_handshake_client_preference(Config) when is_list(Config) -> + run_npn_handshake(Config, + [{client_preferred_next_protocols, + {client, [<<"http/1.0">>, <<"http/1.1">>], <<"http/1.1">>}}], + [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.0">>}). -perform_client_tries_to_negotiate_but_server_does_not_support_test(Config) -> - run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], - [], - {error, next_protocol_not_negotiated}). +%-------------------------------------------------------------------------------- -perform_fallback_npn_handshake_test(Config) -> - run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], - [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], - {ok, <<"http/1.1">>}). +fallback_npn_handshake(Config) when is_list(Config) -> + run_npn_handshake(Config, + [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], + [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.1">>}). +%-------------------------------------------------------------------------------- -perform_fallback_npn_handshake_server_preference_test(Config) -> - run_npn_handshake_test(Config, - [{client_preferred_next_protocols, {server, [<<"spdy/2">>], <<"http/1.1">>}}], - [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], - {ok, <<"http/1.1">>}). +fallback_npn_handshake_server_preference(Config) when is_list(Config) -> + run_npn_handshake(Config, + [{client_preferred_next_protocols, {server, [<<"spdy/2">>], <<"http/1.1">>}}], + [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], + {ok, <<"http/1.1">>}). +%-------------------------------------------------------------------------------- -perform_normal_npn_handshake_client_preference_test(Config) -> - run_npn_handshake_test(Config, - [{client_preferred_next_protocols, - {client, [<<"http/1.0">>, <<"http/1.1">>], <<"http/1.1">>}}], - [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], - {ok, <<"http/1.0">>}). +client_does_not_try_to_negotiate_but_server_supports_npn(Config) when is_list(Config) -> + run_npn_handshake(Config, + [], + [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], + {error, next_protocol_not_negotiated}). +%-------------------------------------------------------------------------------- -perform_normal_npn_handshake_server_preference_test(Config) -> - run_npn_handshake_test(Config, - [{client_preferred_next_protocols, - {server, [<<"http/1.0">>, <<"http/1.1">>], <<"http/1.1">>}}], - [{next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}], - {ok, <<"http/1.1">>}). +client_tries_to_negotiate_but_server_does_not_support(Config) when is_list(Config) -> + run_npn_handshake(Config, + [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], + [], + {error, next_protocol_not_negotiated}). -perform_renegotiate_from_client_after_npn_handshake(Config) -> +%-------------------------------------------------------------------------------- +renegotiate_from_client_after_npn_handshake(Config) when is_list(Config) -> Data = "hello world", - + ClientOpts0 = ?config(client_opts, Config), ClientOpts = [{client_preferred_next_protocols, {client, [<<"http/1.0">>], <<"http/1.1">>}}] ++ ClientOpts0, @@ -155,8 +206,33 @@ perform_renegotiate_from_client_after_npn_handshake(Config) -> ssl_test_lib:check_result(Server, ok, Client, ok). %-------------------------------------------------------------------------------- +npn_not_supported_client(Config) when is_list(Config) -> + ClientOpts0 = ?config(client_opts, Config), + PrefProtocols = {client_preferred_next_protocols, + {client, [<<"http/1.0">>], <<"http/1.1">>}}, + ClientOpts = [PrefProtocols] ++ ClientOpts0, + {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Client = ssl_test_lib:start_client_error([{node, ClientNode}, + {port, 8888}, {host, Hostname}, + {from, self()}, {options, ClientOpts}]), + + ssl_test_lib:check_result(Client, {error, + {eoptions, + {not_supported_in_sslv3, PrefProtocols}}}). + +%-------------------------------------------------------------------------------- +npn_not_supported_server(Config) when is_list(Config)-> + ServerOpts0 = ?config(server_opts, Config), + AdvProtocols = {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}, + ServerOpts = [AdvProtocols] ++ ServerOpts0, + + {error, {eoptions, {not_supported_in_sslv3, AdvProtocols}}} = ssl:listen(0, ServerOpts). -run_npn_handshake_test(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) -> +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- + +run_npn_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) -> Data = "hello world", ClientOpts0 = ?config(client_opts, Config), @@ -179,6 +255,7 @@ run_npn_handshake_test(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtoco ssl_test_lib:check_result(Server, ok, Client, ok). + assert_npn(Socket, Protocol) -> test_server:format("Negotiated Protocol ~p, Expecting: ~p ~n", [ssl:negotiated_next_protocol(Socket), Protocol]), @@ -227,3 +304,7 @@ ssl_receive(Socket, Data, Buffer) -> after 4000 -> test_server:fail({did_not_get, Data}) end. + + +connection_info_result(Socket) -> + ssl:connection_info(Socket). diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl index 0bca8bbeb4..5102c74e87 100644 --- a/lib/ssl/test/ssl_npn_hello_SUITE.erl +++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl @@ -111,5 +111,7 @@ create_server_hello_with_no_advertised_protocols_test(_Config) -> undefined = Hello#server_hello.next_protocol_negotiation. create_server_hello_with_advertised_protocols_test(_Config) -> - Hello = ssl_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), false, [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>]), - #next_protocol_negotiation{extension_data = <<6, "spdy/1", 8, "http/1.0", 8, "http/1.1">>} = Hello#server_hello.next_protocol_negotiation. + Hello = ssl_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), + false, [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>]), + #next_protocol_negotiation{extension_data = <<6, "spdy/1", 8, "http/1.0", 8, "http/1.1">>} = + Hello#server_hello.next_protocol_negotiation. -- cgit v1.2.3 From f421eabde4f5cbb0d4c718f2f07628626ab69c6a Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Mon, 24 Sep 2012 17:50:07 +0200 Subject: ssl: Shorten test case names to workaround ct shortcomings on windows --- lib/ssl/test/ssl_npn_handshake_SUITE.erl | 8 ++-- lib/ssl/test/ssl_to_openssl_SUITE.erl | 80 ++++++++++++++++---------------- 2 files changed, 44 insertions(+), 44 deletions(-) (limited to 'lib/ssl/test') diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl index cfeb328e21..8597aa6740 100644 --- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl +++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl @@ -49,8 +49,8 @@ next_protocol_tests() -> normal_npn_handshake_client_preference, fallback_npn_handshake, fallback_npn_handshake_server_preference, - client_tries_to_negotiate_but_server_does_not_support, - client_does_not_try_to_negotiate_but_server_supports_npn, + client_negotiate_server_does_not_support, + no_client_negotiate_but_server_supports_npn, renegotiate_from_client_after_npn_handshake ]. @@ -164,7 +164,7 @@ fallback_npn_handshake_server_preference(Config) when is_list(Config) -> %-------------------------------------------------------------------------------- -client_does_not_try_to_negotiate_but_server_supports_npn(Config) when is_list(Config) -> +no_client_negotiate_but_server_supports_npn(Config) when is_list(Config) -> run_npn_handshake(Config, [], [{next_protocols_advertised, [<<"spdy/1">>, <<"http/1.1">>, <<"http/1.0">>]}], @@ -172,7 +172,7 @@ client_does_not_try_to_negotiate_but_server_supports_npn(Config) when is_list(Co %-------------------------------------------------------------------------------- -client_tries_to_negotiate_but_server_does_not_support(Config) when is_list(Config) -> +client_negotiate_server_does_not_support(Config) when is_list(Config) -> run_npn_handshake(Config, [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], [], diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index 30f8f60156..21797bee08 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -115,14 +115,14 @@ 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 -> + when TestCase == erlang_client_openssl_server_npn; + TestCase == erlang_server_openssl_client_npn; + TestCase == erlang_server_openssl_client_npn_renegotiate; + TestCase == erlang_client_openssl_server_npn_renegotiate; + 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(_, Config) -> @@ -190,8 +190,8 @@ all_versions_tests() -> erlang_server_openssl_client_dsa_cert, 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_nowrap_seqnum, + erlang_server_openssl_client_nowrap_seqnum, erlang_client_openssl_server_no_server_ca_cert, erlang_client_openssl_server_client_cert, erlang_server_openssl_client_client_cert, @@ -202,14 +202,14 @@ all_versions_tests() -> ssl2_erlang_server_openssl_client]. npn_tests() -> - [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]. + [erlang_client_openssl_server_npn, + erlang_server_openssl_client_npn, + erlang_server_openssl_client_npn_renegotiate, + erlang_client_openssl_server_npn_renegotiate, + erlang_server_openssl_client_npn_only_client, + erlang_server_openssl_client_npn_only_server, + erlang_client_openssl_server_npn_only_client, + erlang_client_openssl_server_npn_only_server]. init_per_group(GroupName, Config) -> case ssl_test_lib:is_tls_version(GroupName) of @@ -565,14 +565,14 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) -> %%-------------------------------------------------------------------- -erlang_client_openssl_server_no_wrap_sequence_number(doc) -> +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."]; -erlang_client_openssl_server_no_wrap_sequence_number(suite) -> +erlang_client_openssl_server_nowrap_seqnum(suite) -> []; -erlang_client_openssl_server_no_wrap_sequence_number(Config) when is_list(Config) -> +erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) -> process_flag(trap_exit, true), ServerOpts = ?config(server_opts, Config), ClientOpts = ?config(client_opts, Config), @@ -611,15 +611,15 @@ erlang_client_openssl_server_no_wrap_sequence_number(Config) when is_list(Config process_flag(trap_exit, false), ok. %%-------------------------------------------------------------------- -erlang_server_openssl_client_no_wrap_sequence_number(doc) -> +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."]; -erlang_server_openssl_client_no_wrap_sequence_number(suite) -> +erlang_server_openssl_client_nowrap_seqnum(suite) -> []; -erlang_server_openssl_client_no_wrap_sequence_number(Config) when is_list(Config) -> +erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) -> process_flag(trap_exit, true), ServerOpts = ?config(server_opts, Config), @@ -1090,11 +1090,11 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) -> ok. %%-------------------------------------------------------------------- -erlang_client_openssl_server_npn_negotiation(doc) -> +erlang_client_openssl_server_npn(doc) -> ["Test erlang client with openssl server doing npn negotiation"]; -erlang_client_openssl_server_npn_negotiation(suite) -> +erlang_client_openssl_server_npn(suite) -> []; -erlang_client_openssl_server_npn_negotiation(Config) when is_list(Config) -> +erlang_client_openssl_server_npn(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), @@ -1106,11 +1106,11 @@ erlang_client_openssl_server_npn_negotiation(Config) when is_list(Config) -> %%-------------------------------------------------------------------- -erlang_client_openssl_server_npn_negotiation_and_renegotiate(doc) -> +erlang_client_openssl_server_npn_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_renegotiate(suite) -> []; -erlang_client_openssl_server_npn_negotiation_and_renegotiate(Config) when is_list(Config) -> +erlang_client_openssl_server_npn_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), @@ -1124,11 +1124,11 @@ erlang_client_openssl_server_npn_negotiation_and_renegotiate(Config) when is_lis %%-------------------------------------------------------------------------- -erlang_server_openssl_client_npn_negotiation(doc) -> +erlang_server_openssl_client_npn(doc) -> ["Test erlang server with openssl client and npn negotiation"]; -erlang_server_openssl_client_npn_negotiation(suite) -> +erlang_server_openssl_client_npn(suite) -> []; -erlang_server_openssl_client_npn_negotiation(Config) when is_list(Config) -> +erlang_server_openssl_client_npn(Config) when is_list(Config) -> Data = "From openssl to erlang", start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, fun(Server, OpensslPort) -> @@ -1139,11 +1139,11 @@ erlang_server_openssl_client_npn_negotiation(Config) when is_list(Config) -> %%-------------------------------------------------------------------------- -erlang_server_openssl_client_npn_negotiation_and_renegotiate(doc) -> +erlang_server_openssl_client_npn_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_renegotiate(suite) -> []; -erlang_server_openssl_client_npn_negotiation_and_renegotiate(Config) when is_list(Config) -> +erlang_server_openssl_client_npn_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), @@ -1154,7 +1154,7 @@ erlang_server_openssl_client_npn_negotiation_and_renegotiate(Config) when is_lis ok. %%-------------------------------------------------------------------------- -erlang_client_openssl_server_npn_negotiate_only_on_server(Config) when is_list(Config) -> +erlang_client_openssl_server_npn_only_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), @@ -1164,7 +1164,7 @@ erlang_client_openssl_server_npn_negotiate_only_on_server(Config) when is_list(C %%-------------------------------------------------------------------------- -erlang_client_openssl_server_npn_negotiate_only_on_client(Config) when is_list(Config) -> +erlang_client_openssl_server_npn_only_client(Config) when is_list(Config) -> Data = "From openssl to erlang", start_erlang_client_and_openssl_server_with_opts(Config, [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}}], "", Data, fun(Server, OpensslPort) -> port_command(OpensslPort, Data), @@ -1173,7 +1173,7 @@ erlang_client_openssl_server_npn_negotiate_only_on_client(Config) when is_list(C ok. %%-------------------------------------------------------------------------- -erlang_server_openssl_client_npn_negotiate_only_on_server(Config) when is_list(Config) -> +erlang_server_openssl_client_npn_only_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), @@ -1181,7 +1181,7 @@ erlang_server_openssl_client_npn_negotiate_only_on_server(Config) when is_list(C end), ok. -erlang_server_openssl_client_npn_negotiate_only_on_client(Config) when is_list(Config) -> +erlang_server_openssl_client_npn_only_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), -- cgit v1.2.3