From c5ae65889fc0dbaf12bbcabc93410245bbc11cc1 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Mon, 6 May 2013 08:49:20 +0200 Subject: ssl: Only send ECC-hello extension if ECC-cipher suites are advertised --- lib/ssl/src/ssl_cipher.erl | 5 ++++ lib/ssl/src/ssl_handshake.erl | 50 ++++++++++++++++++++++++++++-------- lib/ssl/test/ssl_npn_hello_SUITE.erl | 8 +++--- lib/ssl/test/ssl_test_lib.erl | 10 ++++++++ 4 files changed, 60 insertions(+), 13 deletions(-) (limited to 'lib/ssl') 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, <>}; + 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), <>. + +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}, -- cgit v1.2.3