aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2013-05-06 08:49:20 +0200
committerIngela Anderton Andin <[email protected]>2013-05-08 10:39:22 +0200
commitc5ae65889fc0dbaf12bbcabc93410245bbc11cc1 (patch)
tree5934590f200e7c2fa72586a91b6bc054bd9c3ff6 /lib/ssl
parent01f5de8764b200bdd0d5e4ff69fba4523b3c2c7c (diff)
downloadotp-c5ae65889fc0dbaf12bbcabc93410245bbc11cc1.tar.gz
otp-c5ae65889fc0dbaf12bbcabc93410245bbc11cc1.tar.bz2
otp-c5ae65889fc0dbaf12bbcabc93410245bbc11cc1.zip
ssl: Only send ECC-hello extension if ECC-cipher suites are advertised
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/src/ssl_cipher.erl5
-rw-r--r--lib/ssl/src/ssl_handshake.erl50
-rw-r--r--lib/ssl/test/ssl_npn_hello_SUITE.erl8
-rw-r--r--lib/ssl/test/ssl_test_lib.erl10
4 files changed, 60 insertions, 13 deletions
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index accea63344..dc413d6dfc 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -278,6 +278,11 @@ srp_suites() ->
%% TLS v1.1 suites
suite_definition(?TLS_NULL_WITH_NULL_NULL) ->
{null, null, null, null};
+%% RFC 5746 - Not a real cipher suite used to signal empty "renegotiation_info" extension
+%% to avoid handshake failure from old servers that do not ignore
+%% hello extension data as they should.
+suite_definition(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV) ->
+ {null, null, null, null};
%% suite_definition(?TLS_RSA_WITH_NULL_MD5) ->
%% {rsa, null, md5, default_prf};
%% suite_definition(?TLS_RSA_WITH_NULL_SHA) ->
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 1cca644956..e358cbe9bb 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1368,8 +1368,8 @@ enc_hs(#client_hello{client_version = {Major, Minor},
BinCipherSuites = list_to_binary(CipherSuites),
CsLength = byte_size(BinCipherSuites),
Extensions0 = hello_extensions(RenegotiationInfo, SRP, NextProtocolNegotiation)
- ++ hello_extensions(EcPointFormats)
- ++ hello_extensions(EllipticCurves),
+ ++ ec_hello_extensions(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites), EcPointFormats)
+ ++ ec_hello_extensions(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites), EllipticCurves),
Extensions1 = if
Major == 3, Minor >=3 -> Extensions0 ++ hello_extensions(HashSigns);
true -> Extensions0
@@ -1384,20 +1384,21 @@ enc_hs(#client_hello{client_version = {Major, Minor},
enc_hs(#server_hello{server_version = {Major, Minor},
random = Random,
session_id = Session_ID,
- cipher_suite = Cipher_suite,
+ cipher_suite = CipherSuite,
compression_method = Comp_method,
renegotiation_info = RenegotiationInfo,
ec_point_formats = EcPointFormats,
elliptic_curves = EllipticCurves,
next_protocol_negotiation = NextProtocolNegotiation}, _Version) ->
SID_length = byte_size(Session_ID),
+ CipherSuites = [ssl_cipher:suite_definition(CipherSuite)],
Extensions = hello_extensions(RenegotiationInfo, NextProtocolNegotiation)
- ++ hello_extensions(EcPointFormats)
- ++ hello_extensions(EllipticCurves),
+ ++ ec_hello_extensions(CipherSuites, EcPointFormats)
+ ++ ec_hello_extensions(CipherSuites, EllipticCurves),
ExtensionsBin = enc_hello_extensions(Extensions),
{?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID/binary,
- Cipher_suite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>};
+ CipherSuite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>};
enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version) ->
ASN1Certs = certs_from_list(ASN1CertList),
ACLen = erlang:iolist_size(ASN1Certs),
@@ -1519,6 +1520,24 @@ enc_sign(_HashSign, Sign, _Version) ->
SignLen = byte_size(Sign),
<<?UINT16(SignLen), Sign/binary>>.
+
+ec_hello_extensions(CipherSuites, #elliptic_curves{} = Info) ->
+ case advertises_ec_ciphers(CipherSuites) of
+ true ->
+ [Info];
+ false ->
+ []
+ end;
+ec_hello_extensions(CipherSuites, #ec_point_formats{} = Info) ->
+ case advertises_ec_ciphers(CipherSuites) of
+ true ->
+ [Info];
+ false ->
+ []
+ end;
+ec_hello_extensions(_, undefined) ->
+ [].
+
hello_extensions(RenegotiationInfo, NextProtocolNegotiation) ->
hello_extensions(RenegotiationInfo) ++ next_protocol_extension(NextProtocolNegotiation).
@@ -1527,15 +1546,26 @@ hello_extensions(RenegotiationInfo, SRP, NextProtocolNegotiation) ->
++ hello_extensions(SRP)
++ next_protocol_extension(NextProtocolNegotiation).
+advertises_ec_ciphers([]) ->
+ false;
+advertises_ec_ciphers([{ecdh_ecdsa, _,_,_} | _]) ->
+ true;
+advertises_ec_ciphers([{ecdhe_ecdsa, _,_,_} | _]) ->
+ true;
+advertises_ec_ciphers([{ecdh_rsa, _,_,_} | _]) ->
+ true;
+advertises_ec_ciphers([{ecdhe_rsa, _,_,_} | _]) ->
+ true;
+advertises_ec_ciphers([{ecdh_anon, _,_,_} | _]) ->
+ true;
+advertises_ec_ciphers([_| Rest]) ->
+ advertises_ec_ciphers(Rest).
+
%% Renegotiation info
hello_extensions(#renegotiation_info{renegotiated_connection = undefined}) ->
[];
hello_extensions(#renegotiation_info{} = Info) ->
[Info];
-hello_extensions(#elliptic_curves{} = Info) ->
- [Info];
-hello_extensions(#ec_point_formats{} = Info) ->
- [Info];
hello_extensions(#srp{} = Info) ->
[Info];
hello_extensions(#hash_sign_algos{} = Info) ->
diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl
index 0bcc0b1fc2..43fa72ea28 100644
--- a/lib/ssl/test/ssl_npn_hello_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl
@@ -25,6 +25,8 @@
-compile(export_all).
-include("ssl_handshake.hrl").
-include("ssl_record.hrl").
+-include("ssl_cipher.hrl").
+-include("ssl_internal.hrl").
-include_lib("common_test/include/ct.hrl").
%%--------------------------------------------------------------------
@@ -98,7 +100,7 @@ create_client_handshake(Npn) ->
client_version = {1, 2},
random = <<1:256>>,
session_id = <<>>,
- cipher_suites = "",
+ cipher_suites = [?TLS_DHE_DSS_WITH_DES_CBC_SHA],
compression_methods = "",
next_protocol_negotiation = Npn,
renegotiation_info = #renegotiation_info{}
@@ -109,7 +111,7 @@ create_server_handshake(Npn) ->
server_version = {1, 2},
random = <<1:256>>,
session_id = <<>>,
- cipher_suite = <<1,2>>,
+ cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA,
compression_method = 1,
next_protocol_negotiation = Npn,
renegotiation_info = #renegotiation_info{}
@@ -121,7 +123,7 @@ create_connection_states() ->
security_parameters = #security_parameters{
server_random = <<1:256>>,
compression_algorithm = 1,
- cipher_suite = <<1, 2>>
+ cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA
}
},
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 6b082b4eec..a8ff5187b6 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -827,6 +827,16 @@ psk_suites() ->
{rsa_psk, aes_256_cbc, sha}],
ssl_cipher:filter_suites(Suites).
+psk_anon_suites() ->
+ [{psk, rc4_128, sha},
+ {psk, '3des_ede_cbc', sha},
+ {psk, aes_128_cbc, sha},
+ {psk, aes_256_cbc, sha},
+ {dhe_psk, rc4_128, sha},
+ {dhe_psk, '3des_ede_cbc', sha},
+ {dhe_psk, aes_128_cbc, sha},
+ {dhe_psk, aes_256_cbc, sha}].
+
srp_suites() ->
Suites =
[{srp_anon, '3des_ede_cbc', sha},