diff options
author | Ingela Anderton Andin <[email protected]> | 2013-03-01 15:36:55 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2015-03-13 13:21:09 +0100 |
commit | 96d330814fd8195b0d33d1c33e0683e1fbf752ea (patch) | |
tree | 2d48ffa4ba50660a737a448e7c6d974c86490f2b | |
parent | fbe08ea2c744b7eaf47085c0ccda2f224cc2b5ba (diff) | |
download | otp-96d330814fd8195b0d33d1c33e0683e1fbf752ea.tar.gz otp-96d330814fd8195b0d33d1c33e0683e1fbf752ea.tar.bz2 otp-96d330814fd8195b0d33d1c33e0683e1fbf752ea.zip |
ssl: Check that negotiated version is a supported version.
Conflicts:
lib/ssl/src/ssl_handshake.erl
lib/ssl/test/ssl_basic_SUITE.erl
-rw-r--r-- | lib/ssl/doc/src/ssl.xml | 9 | ||||
-rw-r--r-- | lib/ssl/src/ssl.erl | 11 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 3 | ||||
-rw-r--r-- | lib/ssl/src/ssl_handshake.erl | 23 | ||||
-rw-r--r-- | lib/ssl/src/ssl_record.erl | 12 | ||||
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 43 |
6 files changed, 76 insertions, 25 deletions
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index f2c1062102..eaa0bff21e 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1999</year><year>2012</year> + <year>1999</year><year>2015</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -273,6 +273,13 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | <p> {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, {bad_cert, invalid_signature}, {bad_cert, unknown_ca},{bad_cert, selfsigned_peer}, {bad_cert, name_not_permitted}, {bad_cert, missing_basic_constraint}, {bad_cert, invalid_key_usage}</p> </item> + <tag>{versions, [protocol()]}</tag> + <item>TLS protocol versions that will be supported by started clients and servers. + This option overrides the application environment option <c>protocol_version</c>. If the + environment option is not set it defaults to all versions supported by the SSL application. See also + <seealso marker="ssl:ssl_app">ssl(6)</seealso> + </item> + <tag>{hibernate_after, integer()|undefined}</tag> <item>When an integer-value is specified, the <code>ssl_connection</code> will go into hibernation after the specified number of milliseconds diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index b52470b988..ac69ed847d 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2015. 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 @@ -572,8 +572,15 @@ handle_options(Opts0, _Role) -> CertFile = handle_option(certfile, Opts, <<>>), + Versions = case handle_option(versions, Opts, []) of + [] -> + ssl_record:supported_protocol_versions(); + Vsns -> + [ssl_record:protocol_version(Vsn) || Vsn <- Vsns] + end, + SSLOptions = #ssl_options{ - versions = handle_option(versions, Opts, []), + versions = Versions, verify = validate_option(verify, Verify), verify_fun = VerifyFun, fail_if_no_peer_cert = FailIfNoPeerCert, diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 73857bccbb..eb71212dcc 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -74,7 +74,6 @@ session_cache, % session_cache_cb, % negotiated_version, % tls_version() - supported_protocol_versions, % [atom()] client_certificate_requested = false, key_algorithm, % atom as defined by cipher_suite hashsign_algorithm, % atom as defined by cipher_suite diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index bb26302fff..c6eda03e71 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -61,11 +61,7 @@ client_hello(Host, Port, ConnectionStates, ciphers = UserSuites } = SslOpts, Cache, CacheCb, Renegotiation, OwnCert) -> - - Fun = fun(Version) -> - ssl_record:protocol_version(Version) - end, - Version = ssl_record:highest_protocol_version(lists:map(Fun, Versions)), + Version = ssl_record:highest_protocol_version(Versions), Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, Ciphers = available_suites(UserSuites, Version), @@ -124,10 +120,11 @@ hello(#server_hello{cipher_suite = CipherSuite, server_version = Version, compression_method = Compression, random = Random, session_id = SessionId, renegotiation_info = Info, hash_signs = _HashSigns}, - #ssl_options{secure_renegotiate = SecureRenegotation}, + #ssl_options{secure_renegotiate = SecureRenegotation, + versions = SupportedVersions}, ConnectionStates0, Renegotiation) -> -%%TODO: select hash and signature algorigthm - case ssl_record:is_acceptable_version(Version) of + %%TODO: select hash and signature algorigthm + case ssl_record:is_acceptable_version(Version, SupportedVersions) of true -> case handle_renegotiation_info(client, Info, ConnectionStates0, Renegotiation, SecureRenegotation, []) of @@ -152,7 +149,7 @@ hello(#client_hello{client_version = ClientVersion, random = Random, {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) -> %% TODO: select hash and signature algorithm Version = select_version(ClientVersion, Versions), - case ssl_record:is_acceptable_version(Version) of + case ssl_record:is_acceptable_version(Version, Versions) of true -> {Type, #session{cipher_suite = CipherSuite, compression_method = Compression} = Session} @@ -767,11 +764,7 @@ hello_security_parameters(server, Version, ConnectionState, CipherSuite, Random, }. select_version(ClientVersion, Versions) -> - Fun = fun(Version) -> - ssl_record:protocol_version(Version) - end, - ServerVersion = ssl_record:highest_protocol_version(lists:map(Fun, - Versions)), + ServerVersion = ssl_record:highest_protocol_version(Versions), ssl_record:lowest_protocol_version(ClientVersion, ServerVersion). select_cipher_suite([], _) -> diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index 8e93ce4634..9f764908a1 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -56,7 +56,7 @@ %% Misc. -export([protocol_version/1, lowest_protocol_version/2, highest_protocol_version/1, supported_protocol_versions/0, - is_acceptable_version/1]). + is_acceptable_version/1, is_acceptable_version/2]). -export([compressions/0]). @@ -476,8 +476,10 @@ supported_protocol_versions([_|_] = Vsns) -> %%-------------------------------------------------------------------- -spec is_acceptable_version(tls_version()) -> boolean(). +-spec is_acceptable_version(tls_version(), Supported :: [tls_version()]) -> boolean(). %% %% Description: ssl version 2 is not acceptable security risks are too big. +%% %%-------------------------------------------------------------------- is_acceptable_version({N,_}) when N >= ?LOWEST_MAJOR_SUPPORTED_VERSION -> @@ -485,6 +487,12 @@ is_acceptable_version({N,_}) is_acceptable_version(_) -> false. +is_acceptable_version({N,_} = Version, Versions) + when N >= ?LOWEST_MAJOR_SUPPORTED_VERSION -> + lists:member(Version, Versions); +is_acceptable_version(_,_) -> + false. + %%-------------------------------------------------------------------- -spec compressions() -> [binary()]. %% diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 112ed85ec5..8625871332 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -259,7 +259,8 @@ api_tests() -> shutdown_error, hibernate, ssl_accept_timeout, - ssl_recv_timeout + ssl_recv_timeout, + versions_option ]. certificate_verify_tests() -> @@ -4070,7 +4071,43 @@ client_server_opts({KeyAlgo,_,_}, Config) when KeyAlgo == dss orelse KeyAlgo == ?config(server_dsa_opts, Config)}. %%-------------------------------------------------------------------- -%%% Internal functions + +versions_option() -> + [{doc,"Test API versions option to connect/listen."}]. +versions_option(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + Supported = proplists:get_value(supported, ssl:versions()), + Available = proplists:get_value(available, ssl:versions()), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [{versions, Supported} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, ClientOpts}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + Server ! listen, + + ErrClient = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {options, [{versions , Available -- Supported} | ClientOpts]}]), + receive + {Server, _} -> + ok + end, + + ssl_test_lib:check_result(ErrClient, {error, "protocol version"}). +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- send_recv_result(Socket) -> ssl:send(Socket, "Hello world"), |