diff options
Diffstat (limited to 'lib/ssl')
39 files changed, 681 insertions, 707 deletions
diff --git a/lib/ssl/src/dtls_gen_connection.erl b/lib/ssl/src/dtls_gen_connection.erl index 10da52118a..453c46d879 100644 --- a/lib/ssl/src/dtls_gen_connection.erl +++ b/lib/ssl/src/dtls_gen_connection.erl @@ -545,10 +545,11 @@ handle_info({CloseTag, Socket}, StateName, %% with widespread implementation practice. case (Active == false) andalso (CTs =/= []) of false -> - case Version of - {254, N} when N =< 253 -> + %% the =< is a leaking implementation detail. + %% this means `Version={254, N} when N =< 253` + if (Version =< ?'DTLS-1.2') -> ok; - _ -> + true -> %% As invalidate_sessions here causes performance issues, %% we will conform to the widespread implementation %% practice and go against the spec diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl index a67c954883..0771612996 100644 --- a/lib/ssl/src/dtls_handshake.erl +++ b/lib/ssl/src/dtls_handshake.erl @@ -189,7 +189,7 @@ handle_client_hello(Version, TLSVersion = dtls_v1:corresponding_tls_version(Version), AvailableHashSigns = ssl_handshake:available_signature_algs( ClientHashSigns, SupportedHashSigns, TLSVersion), - ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, TLSVersion, ECCOrder), + ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, ECCOrder), {Type, #session{cipher_suite = CipherSuite, own_certificates = [OwnCert |_]} = Session1} = ssl_handshake:select_session(SugesstedId, CipherSuites, diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl index dadb16d250..e45a4405cd 100644 --- a/lib/ssl/src/dtls_record.erl +++ b/lib/ssl/src/dtls_record.erl @@ -141,12 +141,12 @@ set_connection_state_by_epoch(ReadState, Epoch, #{saved_read := #{epoch := Epoch %%-------------------------------------------------------------------- -spec init_connection_state_seq(ssl_record:ssl_version(), ssl_record:connection_states()) -> - ssl_record:connection_state(). + ssl_record:connection_state(). %% %% Description: Copy the read sequence number to the write sequence number %% This is only valid for DTLS in the first client_hello %%-------------------------------------------------------------------- -init_connection_state_seq({254, _}, +init_connection_state_seq(?'DTLS-1.X', #{current_read := #{epoch := 0, sequence_number := Seq}, current_write := #{epoch := 0} = Write} = ConnnectionStates0) -> ConnnectionStates0#{current_write => Write#{sequence_number => Seq}}; @@ -271,12 +271,12 @@ decode_cipher_text(#ssl_tls{epoch = Epoch} = CipherText, ConnnectionStates0) -> %% or vice versa. %%-------------------------------------------------------------------- protocol_version('dtlsv1.2') -> - {254, 253}; + ?'DTLS-1.2'; protocol_version(dtlsv1) -> - {254, 255}; -protocol_version({254, 253}) -> + ?'DTLS-1.0'; +protocol_version(?'DTLS-1.2') -> 'dtlsv1.2'; -protocol_version({254, 255}) -> +protocol_version(?'DTLS-1.0') -> dtlsv1. %%-------------------------------------------------------------------- -spec lowest_protocol_version(ssl_record:ssl_version(), ssl_record:ssl_version()) -> ssl_record:ssl_version(). @@ -298,10 +298,9 @@ lowest_protocol_version(_,Version) -> %% Description: Lowest protocol version present in a list %%-------------------------------------------------------------------- lowest_protocol_version([]) -> - lowest_protocol_version(); -lowest_protocol_version(Versions) -> - [Ver | Vers] = Versions, - lowest_list_protocol_version(Ver, Vers). + lowest_protocol_version(supported_protocol_versions()); +lowest_protocol_version([Ver | Vers]) -> + lists:foldl( fun lowest_protocol_version/2, Ver, Vers). %%-------------------------------------------------------------------- -spec highest_protocol_version([ssl_record:ssl_version()]) -> ssl_record:ssl_version(). @@ -309,23 +308,21 @@ lowest_protocol_version(Versions) -> %% Description: Highest protocol version present in a list %%-------------------------------------------------------------------- highest_protocol_version([]) -> - highest_protocol_version(); -highest_protocol_version(Versions) -> - [Ver | Vers] = Versions, - highest_list_protocol_version(Ver, Vers). + highest_protocol_version(supported_protocol_versions()); +highest_protocol_version([Ver | Vers]) -> + lists:foldl(fun highest_protocol_version/2, Ver, Vers). %%-------------------------------------------------------------------- -spec highest_protocol_version(ssl_record:ssl_version(), ssl_record:ssl_version()) -> ssl_record:ssl_version(). %% %% Description: Highest protocol version of two given versions %%-------------------------------------------------------------------- + highest_protocol_version(Version = {M, N}, {M, O}) when N < O -> Version; -highest_protocol_version({M, _}, - Version = {M, _}) -> +highest_protocol_version({M, _}, Version = {M, _}) -> Version; -highest_protocol_version(Version = {M,_}, - {N, _}) when M < N -> +highest_protocol_version(Version = {M,_}, {N, _}) when M < N -> Version; highest_protocol_version(_,Version) -> Version. @@ -397,7 +394,7 @@ is_acceptable_version(Version, Versions) -> -spec hello_version(ssl_record:ssl_version(), [ssl_record:ssl_version()]) -> ssl_record:ssl_version(). hello_version(Version, Versions) -> case dtls_v1:corresponding_tls_version(Version) of - TLSVersion when TLSVersion >= {3, 3} -> + TLSVersion when TLSVersion >= ?'TLS-1.2' -> Version; _ -> lowest_protocol_version(Versions) @@ -643,21 +640,6 @@ start_additional_data(Type, {MajVer, MinVer}, Epoch, SeqNo) -> %%-------------------------------------------------------------------- -lowest_list_protocol_version(Ver, []) -> - Ver; -lowest_list_protocol_version(Ver1, [Ver2 | Rest]) -> - lowest_list_protocol_version(lowest_protocol_version(Ver1, Ver2), Rest). - -highest_list_protocol_version(Ver, []) -> - Ver; -highest_list_protocol_version(Ver1, [Ver2 | Rest]) -> - highest_list_protocol_version(highest_protocol_version(Ver1, Ver2), Rest). - -highest_protocol_version() -> - highest_protocol_version(supported_protocol_versions()). - -lowest_protocol_version() -> - lowest_protocol_version(supported_protocol_versions()). sufficient_dtlsv1_2_crypto_support() -> CryptoSupport = crypto:supports(), diff --git a/lib/ssl/src/dtls_v1.erl b/lib/ssl/src/dtls_v1.erl index 3ac6d8226e..4e694d5379 100644 --- a/lib/ssl/src/dtls_v1.erl +++ b/lib/ssl/src/dtls_v1.erl @@ -20,6 +20,7 @@ -module(dtls_v1). -include("ssl_cipher.hrl"). +-include("ssl_record.hrl"). -export([suites/1, all_suites/1, @@ -35,13 +36,13 @@ -define(COOKIE_BASE_TIMEOUT, 30000). --spec suites(Minor:: 253|255) -> [ssl_cipher_format:cipher_suite()]. +-spec suites(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. -suites(Minor) -> +suites(Version) -> lists:filter(fun(Cipher) -> is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher)) end, - tls_v1:suites(corresponding_minor_tls_version(Minor))). + tls_v1:suites(corresponding_tls_version(Version))). all_suites(Version) -> lists:filter(fun(Cipher) -> is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher)) @@ -54,27 +55,30 @@ anonymous_suites(Version) -> end, ssl_cipher:anonymous_suites(corresponding_tls_version(Version))). -exclusive_suites(Minor) -> +exclusive_suites(Version) -> lists:filter(fun(Cipher) -> is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher)) end, - tls_v1:exclusive_suites(corresponding_minor_tls_version(Minor))). + tls_v1:exclusive_suites(corresponding_tls_version(Version))). -exclusive_anonymous_suites(Minor) -> +exclusive_anonymous_suites(Version) -> lists:filter(fun(Cipher) -> is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher)) end, - tls_v1:exclusive_anonymous_suites(corresponding_minor_tls_version(Minor))). + tls_v1:exclusive_anonymous_suites(corresponding_tls_version(Version))). hmac_hash(MacAlg, MacSecret, Value) -> tls_v1:hmac_hash(MacAlg, MacSecret, Value). -ecc_curves({_Major, Minor}) -> - tls_v1:ecc_curves(corresponding_minor_tls_version(Minor)). +ecc_curves(Version) -> + tls_v1:ecc_curves(corresponding_tls_version(Version)). -corresponding_tls_version({254, Minor}) -> - {3, corresponding_minor_tls_version(Minor)}. + +corresponding_tls_version(?'DTLS-1.0') -> + ?'TLS-1.1'; +corresponding_tls_version(?'DTLS-1.2') -> + ?'TLS-1.2'. cookie_secret() -> crypto:strong_rand_bytes(32). @@ -82,18 +86,12 @@ cookie_secret() -> cookie_timeout() -> %% Cookie will live for two timeouts periods round(rand:uniform() * ?COOKIE_BASE_TIMEOUT/2). - -corresponding_minor_tls_version(255) -> - 2; -corresponding_minor_tls_version(253) -> - 3. - -corresponding_dtls_version({3, Minor}) -> - {254, corresponding_minor_dtls_version(Minor)}. - -corresponding_minor_dtls_version(2) -> - 255; -corresponding_minor_dtls_version(3) -> - 253. + + +corresponding_dtls_version(?'TLS-1.1') -> + ?'DTLS-1.0'; +corresponding_dtls_version(?'TLS-1.2') -> + ?'DTLS-1.2'. + is_acceptable_cipher(Suite) -> not ssl_cipher:is_stream_ciphersuite(Suite). diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index e9cf2b0642..327b1cf678 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1143,14 +1143,14 @@ eccs_filter_supported(Curves) -> %% Description: returns all supported groups (TLS 1.3 and later) %%-------------------------------------------------------------------- groups() -> - tls_v1:groups(4). + tls_v1:groups(). %%-------------------------------------------------------------------- -spec groups(default) -> [group()]. %% Description: returns the default groups (TLS 1.3 and later) %%-------------------------------------------------------------------- groups(default) -> - tls_v1:default_groups(4). + tls_v1:default_groups(). %%-------------------------------------------------------------------- -spec getopts(SslSocket, OptionNames) -> @@ -1432,9 +1432,9 @@ format_error({error, Reason}) -> format_error(Reason) -> do_format_error(Reason). -tls_version({3, _} = Version) -> +tls_version(?'TLS-1.X'=Version) -> Version; -tls_version({254, _} = Version) -> +tls_version(?'DTLS-1.X' = Version) -> dtls_v1:corresponding_tls_version(Version). %%-------------------------------------------------------------------- @@ -1484,20 +1484,20 @@ str_to_suite(CipherSuiteName) -> %%%-------------------------------------------------------------- %%% Internal functions %%%-------------------------------------------------------------------- -supported_suites(exclusive, {3,Minor}) -> - tls_v1:exclusive_suites(Minor); -supported_suites(exclusive, {254, Minor}) -> - dtls_v1:exclusive_suites(Minor); +supported_suites(exclusive, ?'TLS-1.X'=Version) -> + tls_v1:exclusive_suites(Version); +supported_suites(exclusive, ?'DTLS-1.X'=Version) -> + dtls_v1:exclusive_suites(Version); supported_suites(default, Version) -> ssl_cipher:suites(Version); supported_suites(all, Version) -> ssl_cipher:all_suites(Version); supported_suites(anonymous, Version) -> ssl_cipher:anonymous_suites(Version); -supported_suites(exclusive_anonymous, {3, Minor}) -> - tls_v1:exclusive_anonymous_suites(Minor); -supported_suites(exclusive_anonymous, {254, Minor}) -> - dtls_v1:exclusive_anonymous_suites(Minor). +supported_suites(exclusive_anonymous, ?'TLS-1.X'=Version) -> + tls_v1:exclusive_anonymous_suites(Version); +supported_suites(exclusive_anonymous, ?'DTLS-1.X'=Version) -> + dtls_v1:exclusive_anonymous_suites(Version). do_listen(Port, #config{transport_info = {Transport, _, _, _,_}} = Config, tls_gen_connection) -> tls_socket:listen(Transport, Port, Config); @@ -2530,20 +2530,19 @@ warn_override(_, _UserOpts, _NewOpt, _OldOpts, _LogLevel) -> ok. is_dtls_configured(Versions) -> - Fun = fun (Version) when Version =:= {254, 253} orelse - Version =:= {254, 255} -> + Fun = fun (Version) when Version =:= ?'DTLS-1.2' orelse + Version =:= ?'DTLS-1.0' -> true; (_) -> false end, lists:any(Fun, Versions). - handle_hashsigns_option(Value, Version) -> try - if Version >= {3,4} -> + if Version >= ?'TLS-1.3' -> tls_v1:signature_schemes(Version, Value); - Version =:= {3,3} -> + Version =:= ?'TLS-1.2' -> tls_v1:signature_algs(Version, Value); true -> undefined @@ -2606,11 +2605,11 @@ handle_cipher_option(Value, Versions) when is_list(Value) -> option_error(ciphers, Value) end. -binary_cipher_suites([{3,4} = Version], []) -> +binary_cipher_suites([?'TLS-1.3'], []) -> %% Defaults to all supported suites that does %% not require explicit configuration TLS-1.3 %% only mode. - default_binary_suites(exclusive, Version); + default_binary_suites(exclusive, ?'TLS-1.3'); binary_cipher_suites([Version| _], []) -> %% Defaults to all supported suites that does %% not require explicit configuration @@ -2640,15 +2639,15 @@ binary_cipher_suites(Versions, Ciphers0) -> Ciphers = [ssl_cipher_format:suite_openssl_str_to_map(C) || C <- string:lexemes(Ciphers0, ":")], binary_cipher_suites(Versions, Ciphers). -default_binary_suites(exclusive, {_, Minor}) -> - ssl_cipher:filter_suites(tls_v1:exclusive_suites(Minor)); +default_binary_suites(exclusive, Version) -> + ssl_cipher:filter_suites(tls_v1:exclusive_suites(Version)); default_binary_suites(default, Version) -> ssl_cipher:filter_suites(ssl_cipher:suites(Version)). -all_suites([{3, 4 = Minor}]) -> - tls_v1:exclusive_suites(Minor); -all_suites([{3, 4} = Version0, Version1 |_]) -> - all_suites([Version0]) ++ +all_suites([?'TLS-1.3']) -> + tls_v1:exclusive_suites(?'TLS-1.3'); +all_suites([?'TLS-1.3', Version1 |_]) -> + all_suites([?'TLS-1.3']) ++ ssl_cipher:all_suites(Version1) ++ ssl_cipher:anonymous_suites(Version1); all_suites([Version|_]) -> @@ -2676,8 +2675,9 @@ tuple_to_map_mac(chacha20_poly1305, _) -> tuple_to_map_mac(_, MAC) -> MAC. -handle_eccs_option(Value, {_Major, Minor}) when is_list(Value) -> - try tls_v1:ecc_curves(Minor, Value) of +%% TODO: remove Version +handle_eccs_option(Value, _Version0) when is_list(Value) -> + try tls_v1:ecc_curves(Value) of Curves -> option_error(Curves =:= [], eccs, none_valid), #elliptic_curves{elliptic_curve_list = Curves} @@ -2686,9 +2686,9 @@ handle_eccs_option(Value, {_Major, Minor}) when is_list(Value) -> error:_ -> option_error(eccs, Value) end. -handle_supported_groups_option(Value, Version) when is_list(Value) -> - {_Major, Minor} = tls_version(Version), - try tls_v1:groups(Minor, Value) of +%% TODO: remove Version +handle_supported_groups_option(Value, _Version0) when is_list(Value) -> + try tls_v1:groups(Value) of Groups -> option_error(Groups =:= [], supported_groups, none_valid), #supported_groups{supported_groups = Groups} @@ -2831,7 +2831,6 @@ map_log_level(true) -> map_log_level(false) -> none. - include_security_info([]) -> false; include_security_info([Item | Items]) -> diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index cc641ca2f5..6bfb647df1 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -65,6 +65,7 @@ -include("ssl_handshake.hrl"). -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). +-include("ssl_record.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([trusted_cert_and_paths/4, @@ -345,13 +346,14 @@ available_cert_key_pairs(CertKeyGroups) -> %% Create the prioritized list of cert key pairs that %% are availble for use in the negotiated version -available_cert_key_pairs(CertKeyGroups, {3, 4}) -> +available_cert_key_pairs(CertKeyGroups, ?'TLS-1.3') -> RevAlgos = [rsa, rsa_pss_pss, ecdsa, eddsa], cert_key_group_to_list(RevAlgos, CertKeyGroups, []); -available_cert_key_pairs(CertKeyGroups, {3, 3}) -> +available_cert_key_pairs(CertKeyGroups, ?'TLS-1.2') -> RevAlgos = [dsa, rsa, rsa_pss_pss, ecdsa], cert_key_group_to_list(RevAlgos, CertKeyGroups, []); -available_cert_key_pairs(CertKeyGroups, {3, N}) when N < 3-> +available_cert_key_pairs(CertKeyGroups, ?'TLS-1.X'=Version) + when Version < ?'TLS-1.2'-> RevAlgos = [dsa, rsa, ecdsa], cert_key_group_to_list(RevAlgos, CertKeyGroups, []). @@ -596,21 +598,22 @@ verify_cert_extensions(Cert, UserState, [_|Exts], Context) -> %% Skip unknown extensions! verify_cert_extensions(Cert, UserState, Exts, Context). -verify_sign(_, #{version := {_, Minor}}) when Minor < 3 -> +verify_sign(_, #{version := ?'TLS-1.X'=Version}) + when Version < ?'TLS-1.2' -> %% This verification is not applicable pre TLS-1.2 true; -verify_sign(Cert, #{version := {3, 3}, +verify_sign(Cert, #{version := ?'TLS-1.2', signature_algs := SignAlgs, signature_algs_cert := undefined}) -> is_supported_signature_algorithm_1_2(Cert, SignAlgs); -verify_sign(Cert, #{version := {3, 3}, +verify_sign(Cert, #{version := ?'TLS-1.2', signature_algs_cert := SignAlgs}) -> is_supported_signature_algorithm_1_2(Cert, SignAlgs); -verify_sign(Cert, #{version := {3, 4}, +verify_sign(Cert, #{version := ?'TLS-1.3', signature_algs := SignAlgs, signature_algs_cert := undefined}) -> is_supported_signature_algorithm_1_3(Cert, SignAlgs); -verify_sign(Cert, #{version := {3, 4}, +verify_sign(Cert, #{version := ?'TLS-1.3', signature_algs_cert := SignAlgs}) -> is_supported_signature_algorithm_1_3(Cert, SignAlgs). diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index d10a6fe6fc..ee185363b3 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -214,16 +214,15 @@ build_cipher_block(BlockSz, Mac, Fragment) -> [Fragment, Mac, padding_with_len(TotSz, BlockSz)]. block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, - Mac, Fragment, {3, N}) - when N == 0; N == 1 -> + Mac, Fragment, ?'TLS-1.0') -> L = build_cipher_block(BlockSz, Mac, Fragment), T = Fun(Key, IV, L), NextIV = next_iv(T, IV), {T, CS0#cipher_state{iv=NextIV}}; block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV, state = IV_Cache0} = CS0, - Mac, Fragment, {3, N}) - when N == 2; N == 3; N == 4 -> + Mac, Fragment, ?'TLS-1.X'=Version) + when Version == ?'TLS-1.1'; Version == ?'TLS-1.2'; Version == ?'TLS-1.3' -> IV_Size = byte_size(IV), <<NextIV:IV_Size/binary, IV_Cache/binary>> = case IV_Cache0 of @@ -321,45 +320,42 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, %% %% Description: Returns a list of supported cipher suites. %%-------------------------------------------------------------------- -suites({3, Minor}) -> - tls_v1:suites(Minor); -suites({_, Minor}) -> - dtls_v1:suites(Minor). -all_suites({3, 4} = Version) -> - suites(Version) - ++ tls_v1:psk_suites({3,3}) - ++ tls_v1:srp_suites({3,3}) - ++ tls_v1:rsa_suites({3,3}) - ++ tls_v1:des_suites({3,3}) - ++ tls_v1:rc4_suites({3,3}); -all_suites({3, _} = Version) -> - suites(Version) - ++ tls_v1:psk_suites(Version) - ++ tls_v1:srp_suites(Version) - ++ tls_v1:rsa_suites(Version) - ++ tls_v1:des_suites(Version) - ++ tls_v1:rc4_suites(Version); +suites(?'TLS-1.X'=Version) -> + tls_v1:suites(Version); +suites(?'DTLS-1.X'=Version) -> + dtls_v1:suites(Version). +all_suites(?'TLS-1.3' = Version) -> + suites(Version) ++ tls_legacy_suites(?'TLS-1.2'); +all_suites(?'TLS-1.X' = Version) -> + suites(Version) ++ tls_legacy_suites(Version); all_suites(Version) -> dtls_v1:all_suites(Version). +tls_legacy_suites(Version) -> + Tests = [ fun tls_v1:psk_suites/1 + , fun tls_v1:srp_suites/1 + , fun tls_v1:rsa_suites/1 + , fun tls_v1:des_suites/1 + , fun tls_v1:rc4_suites/1], + lists:flatmap(fun (Fun) -> Fun(Version) end, Tests). + %%-------------------------------------------------------------------- --spec anonymous_suites(ssl_record:ssl_version() | integer()) -> - [ssl_cipher_format:cipher_suite()]. +-spec anonymous_suites(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. %% %% Description: Returns a list of the anonymous cipher suites, only supported %% if explicitly set by user. Intended only for testing. %%-------------------------------------------------------------------- -anonymous_suites({3, N}) -> - anonymous_suites(N); -anonymous_suites({254, _} = Version) -> - dtls_v1:anonymous_suites(Version); - -anonymous_suites(1 = N) -> - tls_v1:exclusive_anonymous_suites(N); -anonymous_suites(4 = N) -> - tls_v1:exclusive_anonymous_suites(N); -anonymous_suites(N) when N > 1-> - tls_v1:exclusive_anonymous_suites(N) ++ anonymous_suites(N-1). + +anonymous_suites(?'TLS-1.X'=Version) -> + SuitesToTest = anonymous_suite_to_test(Version), + lists:flatmap(fun tls_v1:exclusive_anonymous_suites/1, SuitesToTest); +anonymous_suites(?'DTLS-1.X'=Version) -> + dtls_v1:anonymous_suites(Version). + +anonymous_suite_to_test(?'TLS-1.0') -> [?'TLS-1.0']; +anonymous_suite_to_test(?'TLS-1.1') -> [?'TLS-1.1', ?'TLS-1.0']; +anonymous_suite_to_test(?'TLS-1.2') -> [?'TLS-1.2', ?'TLS-1.1', ?'TLS-1.0']; +anonymous_suite_to_test(?'TLS-1.3') -> [?'TLS-1.3']. %%-------------------------------------------------------------------- -spec filter(undefined | binary(), [ssl_cipher_format:cipher_suite()], @@ -687,8 +683,8 @@ scheme_to_components({Hash,Sign}) -> {Hash, Sign, undefined}. mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type, _Length, _Fragment) -> <<>>; -mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) - when N =:= 1; N =:= 2; N =:= 3; N =:= 4 -> +mac_hash(?'TLS-1.X' = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) + when Version =< ?'TLS-1.2', Version =/= ?'SSL-3.0' -> tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version, Length, Fragment). @@ -828,9 +824,9 @@ block_size(Cipher) when Cipher == aes_128_cbc; Cipher == chacha20_poly1305 -> 16. -prf_algorithm(default_prf, {3, N}) when N >= 3 -> +prf_algorithm(default_prf, ?'TLS-1.2') -> ?SHA256; -prf_algorithm(default_prf, {3, _}) -> +prf_algorithm(default_prf, ?'TLS-1.X') -> ?MD5SHA; prf_algorithm(Algo, _) -> hash_algorithm(Algo). @@ -933,8 +929,7 @@ signature_algorithm_to_scheme(#'SignatureAlgorithm'{algorithm = ?'id-RSASSA-PSS' %% We return the original (possibly invalid) PadLength in any case. %% An invalid PadLength will be caught by is_correct_padding/2 %% -generic_block_cipher_from_bin({3, N}, T, IV, HashSize) - when N == 0; N == 1 -> +generic_block_cipher_from_bin(?'TLS-1.0', T, IV, HashSize)-> Sz1 = byte_size(T) - 1, <<_:Sz1/binary, ?BYTE(PadLength0)>> = T, PadLength = if @@ -948,8 +943,8 @@ generic_block_cipher_from_bin({3, N}, T, IV, HashSize) padding=Padding, padding_length=PadLength0, next_iv = IV}; -generic_block_cipher_from_bin({3, N}, T, IV, HashSize) - when N == 2; N == 3; N == 4 -> +generic_block_cipher_from_bin(Version, T, IV, HashSize) + when Version == ?'TLS-1.1'; Version == ?'TLS-1.2' -> Sz1 = byte_size(T) - 1, <<_:Sz1/binary, ?BYTE(PadLength)>> = T, IVLength = byte_size(IV), @@ -968,14 +963,14 @@ generic_stream_cipher_from_bin(T, HashSz) -> mac=Mac}. is_correct_padding(#generic_block_cipher{padding_length = Len, - padding = Padding}, {3, 0}, _) -> + padding = Padding}, ?'SSL-3.0', _) -> Len == byte_size(Padding); %% Only length check is done in SSL 3.0 spec %% For interoperability reasons it is possible to disable -%% the padding check when using TLS 1.0, as it is not strictly required +%% the padding check when using TLS 1.0 (mimicking SSL-3.0), as it is not strictly required %% in the spec (only recommended), however this makes TLS 1.0 vunrable to the Poodle attack %% so by default this clause will not match -is_correct_padding(GenBlockCipher, {3, 1}, false) -> - is_correct_padding(GenBlockCipher, {3, 0}, false); +is_correct_padding(GenBlockCipher, ?'TLS-1.0', false) -> + is_correct_padding(GenBlockCipher, ?'SSL-3.0', false); %% Padding must be checked in TLS 1.1 and after is_correct_padding(#generic_block_cipher{padding_length = Len, padding = Padding}, _, _) -> @@ -1053,14 +1048,14 @@ filter_suites_pubkey(ecdsa, Ciphers, _, OtpCert) -> ec_ecdhe_suites(Ciphers)), filter_keyuse_suites(keyAgreement, Uses, CiphersSuites, ec_ecdh_suites(Ciphers)). -filter_suites_signature(_, Ciphers, {3, N}) when N >= 3 -> +filter_suites_signature(_, Ciphers, ?'TLS-1.X'=Version) when Version >= ?'TLS-1.2' -> Ciphers; filter_suites_signature(rsa, Ciphers, Version) -> - (Ciphers -- ecdsa_signed_suites(Ciphers, Version)) -- dsa_signed_suites(Ciphers, Version); + (Ciphers -- ecdsa_signed_suites(Ciphers, Version)) -- dsa_signed_suites(Ciphers); filter_suites_signature(dsa, Ciphers, Version) -> (Ciphers -- ecdsa_signed_suites(Ciphers, Version)) -- rsa_signed_suites(Ciphers, Version); filter_suites_signature(ecdsa, Ciphers, Version) -> - (Ciphers -- rsa_signed_suites(Ciphers, Version)) -- dsa_signed_suites(Ciphers, Version). + (Ciphers -- rsa_signed_suites(Ciphers, Version)) -- dsa_signed_suites(Ciphers). %% From RFC 5246 - Section 7.4.2. Server Certificate @@ -1079,7 +1074,7 @@ filter_suites_signature(ecdsa, Ciphers, Version) -> %% extension. The names DH_DSS, DH_RSA, ECDH_ECDSA, and ECDH_RSA are %% historical. %% Note: DH_DSS and DH_RSA is not supported -rsa_signed({3,N}) when N >= 3 -> +rsa_signed(?'TLS-1.2') -> fun(rsa) -> true; (dhe_rsa) -> true; (ecdhe_rsa) -> true; @@ -1102,7 +1097,8 @@ rsa_signed_suites(Ciphers, Version) -> cipher_filters => [], mac_filters => [], prf_filters => []}). -ecdsa_signed({3,N}) when N >= 3 -> + +ecdsa_signed(Version) when Version >= ?'TLS-1.2' -> fun(ecdhe_ecdsa) -> true; (_) -> false end; @@ -1164,12 +1160,12 @@ dss_keyed_suites(Ciphers) -> prf_filters => []}). %% Cert should be signed by DSS (DSA) -dsa_signed_suites(Ciphers, Version) -> - filter_suites(Ciphers, #{key_exchange_filters => [dsa_signed(Version)], +dsa_signed_suites(Ciphers) -> + filter_suites(Ciphers, #{key_exchange_filters => [dsa_signed()], cipher_filters => [], mac_filters => [], prf_filters => []}). -dsa_signed(_) -> +dsa_signed() -> fun(dhe_dss) -> true; (_) -> false end. diff --git a/lib/ssl/src/ssl_gen_statem.erl b/lib/ssl/src/ssl_gen_statem.erl index d0941a9689..88488dc355 100644 --- a/lib/ssl/src/ssl_gen_statem.erl +++ b/lib/ssl/src/ssl_gen_statem.erl @@ -1167,7 +1167,7 @@ handle_alert(#alert{level = ?WARNING} = Alert, StateName, #state{static_env = #static_env{role = Role, protocol_cb = Connection}, connection_env = #connection_env{negotiated_version = Version}, - ssl_options = #{log_level := LogLevel}} = State) when Version < {3,4} -> + ssl_options = #{log_level := LogLevel}} = State) when Version < ?'TLS-1.3' -> log_alert(LogLevel, Role, Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), @@ -1201,9 +1201,9 @@ handle_trusted_certs_db(#state{static_env = #static_env{cert_db_ref = Ref, ok end. -maybe_invalidate_session({3, 4},_, _, _, _, _) -> +maybe_invalidate_session(?'TLS-1.3',_, _, _, _, _) -> ok; -maybe_invalidate_session({3, N}, Type, Role, Host, Port, Session) when N < 4 -> +maybe_invalidate_session(?'TLS-1.X'=Version, Type, Role, Host, Port, Session) when Version < ?'TLS-1.3' -> maybe_invalidate_session(Type, Role, Host, Port, Session). maybe_invalidate_session({false, first}, server = Role, Host, Port, Session) -> @@ -1285,14 +1285,14 @@ format_status(terminate, [_, StateName, State]) -> %%-------------------------------------------------------------------- next_statem_state([Version], client) -> case ssl:tls_version(Version) of - {3,4} -> + ?'TLS-1.3' -> wait_sh; _ -> hello end; next_statem_state([Version], server) -> case ssl:tls_version(Version) of - {3,4} -> + ?'TLS-1.3' -> start; _ -> hello @@ -2234,7 +2234,7 @@ maybe_generate_client_shares(#{versions := [Version|_], supported_groups := #supported_groups{ supported_groups = [Group|_]}}) - when Version =:= {3,4} -> + when Version =:= ?'TLS-1.3' -> %% Generate only key_share entry for the most preferred group ssl_cipher:generate_client_shares([Group]); maybe_generate_client_shares(_) -> diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 1915b6f10c..c0ff731166 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -69,13 +69,13 @@ %% Cipher suites handling -export([available_suites/2, available_signature_algs/2, available_signature_algs/3, - cipher_suites/3, prf/6, select_session/9, supported_ecc/1, + cipher_suites/3, prf/6, select_session/9, premaster_secret/2, premaster_secret/3, premaster_secret/4]). %% Extensions handling -export([client_hello_extensions/10, handle_client_hello_extensions/10, %% Returns server hello extensions - handle_server_hello_extensions/10, select_curve/3, select_curve/4, + handle_server_hello_extensions/10, select_curve/2, select_curve/3, select_hashsign/4, select_hashsign/5, select_hashsign_algs/3, empty_extensions/2, add_server_share/3, add_alpn/2, add_selected_version/1, decode_alpn/1, max_frag_enum/1 @@ -391,26 +391,29 @@ verify_signature(_, Msg, {HashAlgo, SignAlgo}, Signature, SignAlgo == rsa_pss_pss -> Options = verify_options(SignAlgo, HashAlgo, PubKeyParams), public_key:verify(Msg, HashAlgo, Signature, PubKey, Options); -verify_signature({3, Minor}, Msg, {HashAlgo, SignAlgo}, Signature, {?rsaEncryption, PubKey, PubKeyParams}) - when Minor >= 3 -> +verify_signature(?'TLS-1.X'=Version, Msg, {HashAlgo, SignAlgo}, Signature, {?rsaEncryption, PubKey, PubKeyParams}) + when Version >= ?'TLS-1.2' -> Options = verify_options(SignAlgo, HashAlgo, PubKeyParams), public_key:verify(Msg, HashAlgo, Signature, PubKey, Options); -verify_signature({3, Minor}, {digest, Digest}, _HashAlgo, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) when Minor =< 2 -> +verify_signature(?'TLS-1.X'=Version, {digest, Digest}, _HashAlgo, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) + when Version =< ?'TLS-1.1' -> case public_key:decrypt_public(Signature, PubKey, [{rsa_pad, rsa_pkcs1_padding}]) of Digest -> true; _ -> false end; -verify_signature({3, 4}, Msg, {_, eddsa}, Signature, {?'id-Ed25519', PubKey, PubKeyParams}) -> +verify_signature(?'TLS-1.3', Msg, {_, eddsa}, Signature, {?'id-Ed25519', PubKey, PubKeyParams}) -> public_key:verify(Msg, none, Signature, {PubKey, PubKeyParams}); -verify_signature({3, 4}, Msg, {_, eddsa}, Signature, {?'id-Ed448', PubKey, PubKeyParams}) -> +verify_signature(?'TLS-1.3', Msg, {_, eddsa}, Signature, {?'id-Ed448', PubKey, PubKeyParams}) -> public_key:verify(Msg, none, Signature, {PubKey, PubKeyParams}); verify_signature(_, Msg, {HashAlgo, _SignAlg}, Signature, {?'id-ecPublicKey', PublicKey, PublicKeyParams}) -> public_key:verify(Msg, HashAlgo, Signature, {PublicKey, PublicKeyParams}); -verify_signature({3, Minor}, _Msg, {_HashAlgo, anon}, _Signature, _) when Minor =< 3 -> +verify_signature(?'TLS-1.X'=Version, _Msg, {_HashAlgo, anon}, _Signature, _) + when Version =< ?'TLS-1.2' -> true; -verify_signature({3, Minor}, Msg, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) when Minor =< 3-> +verify_signature(?'TLS-1.X'=Version, Msg, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) + when Version =< ?'TLS-1.2' -> public_key:verify(Msg, HashAlgo, Signature, {PublicKey, PublicKeyParams}). %%-------------------------------------------------------------------- @@ -564,7 +567,7 @@ encode_handshake(#server_key_params{params_bin = Keys, hashsign = HashSign, encode_handshake(#certificate_request{certificate_types = CertTypes, hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSignAlgos}, certificate_authorities = CertAuths}, - {3,3}) -> + ?'TLS-1.2') -> HashSigns = << <<(ssl_cipher:signature_scheme(SignatureScheme)):16 >> || SignatureScheme <- HashSignAlgos >>, EncCertAuths = encode_cert_auths(CertAuths), @@ -596,8 +599,6 @@ encode_handshake(#certificate_verify{signature = BinSig, hashsign_algorithm = Ha encode_handshake(#finished{verify_data = VerifyData}, _Version) -> {?FINISHED, VerifyData}. -encode_hello_extensions(_, {3, 0}) -> - <<>>; encode_hello_extensions(Extensions, _) -> encode_extensions(hello_extensions_list(Extensions), <<>>). @@ -888,7 +889,7 @@ decode_handshake(_Version, ?CERTIFICATE_STATUS, <<?BYTE(?CERTIFICATE_STATUS_TYPE response = ASN1OcspResponse}; decode_handshake(_Version, ?SERVER_KEY_EXCHANGE, Keys) -> #server_key_exchange{exchange_keys = Keys}; -decode_handshake({3, 3} = Version, ?CERTIFICATE_REQUEST, +decode_handshake(?'TLS-1.2' = Version, ?CERTIFICATE_REQUEST, <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary, ?UINT16(HashSignsLen), HashSigns:HashSignsLen/binary, ?UINT16(CertAuthsLen), EncCertAuths:CertAuthsLen/binary>>) -> @@ -903,9 +904,8 @@ decode_handshake(_Version, ?CERTIFICATE_REQUEST, certificate_authorities = decode_cert_auths(EncCertAuths, [])}; decode_handshake(_Version, ?SERVER_HELLO_DONE, <<>>) -> #server_hello_done{}; -decode_handshake({Major, Minor}, ?CERTIFICATE_VERIFY,<<HashSign:2/binary, ?UINT16(SignLen), - Signature:SignLen/binary>>) - when Major == 3, Minor >= 3 -> +decode_handshake(?'TLS-1.2', ?CERTIFICATE_VERIFY,<<HashSign:2/binary, ?UINT16(SignLen), + Signature:SignLen/binary>>) -> #certificate_verify{hashsign_algorithm = dec_hashsign(HashSign), signature = Signature}; decode_handshake(_Version, ?CERTIFICATE_VERIFY,<<?UINT16(SignLen), Signature:SignLen/binary>>)-> #certificate_verify{signature = Signature}; @@ -1014,11 +1014,11 @@ available_suites(ServerCert, UserSuites, Version, HashSigns, Curve) -> available_signature_algs(undefined, _) -> undefined; -available_signature_algs(SupportedHashSigns, Version) when Version >= {3, 3} -> +available_signature_algs(SupportedHashSigns, Version) when Version >= ?'TLS-1.2' -> case contains_scheme(SupportedHashSigns) of true -> case Version of - {3,3} -> + ?'TLS-1.2' -> #hash_sign_algos{hash_sign_algos = ssl_cipher:signature_schemes_1_2(SupportedHashSigns)}; _ -> #signature_algorithms{signature_scheme_list = SupportedHashSigns} @@ -1030,12 +1030,12 @@ available_signature_algs(_, _) -> undefined. available_signature_algs(undefined, SupportedHashSigns, Version) when - Version >= {3,3} -> + Version >= ?'TLS-1.2' -> SupportedHashSigns; available_signature_algs(#hash_sign_algos{hash_sign_algos = ClientHashSigns}, SupportedHashSigns0, - Version) when Version >= {3,3} -> + Version) when Version >= ?'TLS-1.2' -> SupportedHashSigns = - case (Version == {3,3}) andalso contains_scheme(SupportedHashSigns0) of + case (Version == ?'TLS-1.2') andalso contains_scheme(SupportedHashSigns0) of true -> ssl_cipher:signature_schemes_1_2(SupportedHashSigns0); false -> @@ -1068,7 +1068,7 @@ cipher_suites(Suites, true) -> %% %% Description: use the TLS PRF to generate key material %%-------------------------------------------------------------------- -prf({3,_N}, PRFAlgo, Secret, Label, Seed, WantedLength) -> +prf(?'TLS-1.X', PRFAlgo, Secret, Label, Seed, WantedLength) -> {ok, tls_v1:prf(PRFAlgo, Secret, Label, Seed, WantedLength)}. select_session(SuggestedSessionId, CipherSuites, HashSigns, Compressions, SessIdTracker, Session0, Version, SslOpts, CertKeyAlts) -> @@ -1130,8 +1130,7 @@ server_select_cert_key_pair_and_params(CipherSuites, [#{private_key := Key, cert end end. -is_acceptable_cert(Cert, HashSigns, {Major, Minor}) when Major == 3, - Minor >= 3 -> +is_acceptable_cert(Cert, HashSigns, ?'TLS-1.X'=Version) when Version >= ?'TLS-1.2' -> {SignAlgo0, Param, _, _, _} = get_cert_params(Cert), SignAlgo = sign_algo(SignAlgo0, Param), is_acceptable_hash_sign(SignAlgo, HashSigns); @@ -1139,12 +1138,6 @@ is_acceptable_cert(_,_,_) -> %% Not negotiable pre TLS-1.2. So if cert is available for version it is acceptable true. -supported_ecc({Major, Minor}) when ((Major == 3) and (Minor >= 1)) orelse (Major > 3) -> - Curves = tls_v1:ecc_curves(Minor), - #elliptic_curves{elliptic_curve_list = Curves}; -supported_ecc(_) -> - #elliptic_curves{elliptic_curve_list = []}. - premaster_secret(OtherPublicDhKey, MyPrivateKey, #'DHParameter'{} = Params) -> try public_key:compute_key(OtherPublicDhKey, MyPrivateKey, Params) @@ -1269,7 +1262,7 @@ add_tls12_extensions(_Version, }. -add_common_extensions({3,4}, +add_common_extensions(?'TLS-1.3', HelloExtensions, _CipherSuites, #{eccs := SupportedECCs, @@ -1306,7 +1299,7 @@ add_common_extensions(Version, signature_algs_cert => signature_algs_cert(SignatureCertSchemes)}. -maybe_add_tls13_extensions({3,4}, +maybe_add_tls13_extensions(?'TLS-1.3', HelloExtensions0, #{versions := SupportedVersions} = Opts, KeyShare, @@ -1449,7 +1442,7 @@ add_alpn(Extensions, ALPN0) -> Extensions#{alpn => ALPN}. add_selected_version(Extensions) -> - SupportedVersions = #server_hello_selected_version{selected_version = {3,4}}, + SupportedVersions = #server_hello_selected_version{selected_version = ?'TLS-1.3'}, Extensions#{server_hello_selected_version => SupportedVersions}. kse_remove_private_key(#key_share_entry{ @@ -1587,12 +1580,11 @@ handle_server_hello_extensions(RecordCB, Random, CipherSuite, Compression, end end. -select_curve(Client, Server, Version) -> - select_curve(Client, Server, Version, false). +select_curve(Client, Server) -> + select_curve(Client, Server, false). select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves}, #elliptic_curves{elliptic_curve_list = ServerCurves}, - _, ServerOrder) -> case ServerOrder of false -> @@ -1600,25 +1592,25 @@ select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves}, true -> select_shared_curve(ServerCurves, ClientCurves) end; -select_curve(undefined, _, {_,Minor}, _) -> +select_curve(undefined, _, _) -> %% Client did not send ECC extension use default curve if %% ECC cipher is negotiated - case tls_v1:ecc_curves(Minor, [secp256r1]) of + case tls_v1:ecc_curves([secp256r1]) of [] -> %% Curve not supported by cryptolib ECC algorithms can not be negotiated no_curve; [CurveOid] -> {namedCurve, CurveOid} end; -select_curve({supported_groups, Groups}, Server,{_, Minor} = Version, HonorServerOrder) -> +select_curve({supported_groups, Groups}, Server, HonorServerOrder) -> %% TLS-1.3 hello but lesser version chosen TLSCommonCurves = [secp256r1,secp384r1,secp521r1], Curves = [tls_v1:enum_to_oid(tls_v1:group_to_enum(Name)) || Name <- Groups, lists:member(Name, TLSCommonCurves)], - case tls_v1:ecc_curves(Minor, Curves) of + case tls_v1:ecc_curves(Curves) of [] -> - select_curve(undefined, Server, Version, HonorServerOrder); + select_curve(undefined, Server, HonorServerOrder); [_|_] = ClientCurves -> - select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves}, Server, Version, HonorServerOrder) + select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves}, Server, HonorServerOrder) end. %%-------------------------------------------------------------------- @@ -1639,12 +1631,12 @@ select_hashsign(_, _, KeyExAlgo, _, _Version) when KeyExAlgo == dh_anon; %% The signature_algorithms extension was introduced with TLS 1.2. Ignore it if we have %% negotiated a lower version. select_hashsign({ClientHashSigns, ClientSignatureSchemes}, - Cert, KeyExAlgo, undefined, {3, 3} = Version) -> + Cert, KeyExAlgo, undefined, ?'TLS-1.2' = Version) -> select_hashsign({ClientHashSigns, ClientSignatureSchemes}, Cert, KeyExAlgo, tls_v1:default_signature_algs([Version]), Version); select_hashsign({#hash_sign_algos{hash_sign_algos = ClientHashSigns}, ClientSignatureSchemes0}, - Cert, KeyExAlgo, SupportedHashSigns, {3, 3}) -> + Cert, KeyExAlgo, SupportedHashSigns, ?'TLS-1.2') -> ClientSignatureSchemes = get_signature_scheme(ClientSignatureSchemes0), {SignAlgo0, Param, PublicKeyAlgo0, _, _} = get_cert_params(Cert), SignAlgo = sign_algo(SignAlgo0, Param), @@ -1701,7 +1693,7 @@ select_hashsign(#certificate_request{ certificate_types = Types}, Cert, SupportedHashSigns, - {3, 3}) -> + ?'TLS-1.2') -> {SignAlgo0, Param, PublicKeyAlgo0, _, _} = get_cert_params(Cert), SignAlgo = {_, KeyType} = sign_algo(SignAlgo0, Param), PublicKeyAlgo = ssl_certificate:public_key_type(PublicKeyAlgo0), @@ -1893,9 +1885,9 @@ get_signature_scheme(#signature_algorithms_cert{ %% ECDHE_ECDSA), behave as if the client had sent value {sha1,ecdsa}. %%-------------------------------------------------------------------- -select_hashsign_algs(HashSign, _, {3, 3}) when HashSign =/= undefined -> +select_hashsign_algs(HashSign, _, ?'TLS-1.2') when HashSign =/= undefined -> HashSign; -select_hashsign_algs(undefined, ?rsaEncryption, {3,3}) -> +select_hashsign_algs(undefined, ?rsaEncryption, ?'TLS-1.2') -> {sha, rsa}; select_hashsign_algs(undefined,?'id-ecPublicKey', _) -> {sha, ecdsa}; @@ -1991,7 +1983,7 @@ int_to_bin(I) -> %% The end-entity certificate provided by the client MUST contain a %% key that is compatible with certificate_types. -certificate_types(Version) when Version =< {3,3} -> +certificate_types(Version) when Version =< ?'TLS-1.2' -> ECDSA = supported_cert_type_or_empty(ecdsa, ?ECDSA_SIGN), RSA = supported_cert_type_or_empty(rsa, ?RSA_SIGN), DSS = supported_cert_type_or_empty(dss, ?DSS_SIGN), @@ -2138,21 +2130,21 @@ digitally_signed(Version, Msg, HashAlgo, PrivateKey, SignAlgo) -> throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, bad_key(PrivateKey))) end. -do_digitally_signed({3, Minor}, Msg, HashAlgo, {#'RSAPrivateKey'{} = Key, - #'RSASSA-PSS-params'{}}, SignAlgo) when Minor >= 3 -> +do_digitally_signed(?'TLS-1.X'=Version, Msg, HashAlgo, {#'RSAPrivateKey'{} = Key, + #'RSASSA-PSS-params'{}}, SignAlgo) when Version >= ?'TLS-1.2' -> Options = signature_options(SignAlgo, HashAlgo), public_key:sign(Msg, HashAlgo, Key, Options); -do_digitally_signed({3, Minor}, {digest, Digest}, _HashAlgo, #'RSAPrivateKey'{} = Key, rsa) when Minor =< 2 -> +do_digitally_signed(?'TLS-1.X'=Version, {digest, Digest}, _HashAlgo, #'RSAPrivateKey'{} = Key, rsa) when Version =< ?'TLS-1.1' -> public_key:encrypt_private(Digest, Key, [{rsa_pad, rsa_pkcs1_padding}]); -do_digitally_signed({3, Minor}, {digest, Digest}, _, - #{algorithm := rsa} = Engine, rsa) when Minor =< 2-> +do_digitally_signed(?'TLS-1.X'=Version, {digest, Digest}, _, + #{algorithm := rsa} = Engine, rsa) when Version =< ?'TLS-1.1' -> crypto:private_encrypt(rsa, Digest, maps:remove(algorithm, Engine), rsa_pkcs1_padding); do_digitally_signed(_, Msg, HashAlgo, #{algorithm := Alg} = Engine, SignAlgo) -> Options = signature_options(SignAlgo, HashAlgo), crypto:sign(Alg, HashAlgo, Msg, maps:remove(algorithm, Engine), Options); -do_digitally_signed({3, Minor}, {digest, _} = Msg , HashAlgo, Key, _) when Minor =< 2 -> +do_digitally_signed(?'TLS-1.X'=Version, {digest, _} = Msg , HashAlgo, Key, _) when Version =< ?'TLS-1.1' -> public_key:sign(Msg, HashAlgo, Key); do_digitally_signed(_, Msg, HashAlgo, Key, SignAlgo) -> Options = signature_options(SignAlgo, HashAlgo), @@ -2326,10 +2318,12 @@ encrypted_premaster_secret(Secret, RSAPublicKey) -> throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, premaster_encryption_failed)) end. -calc_certificate_verify({3, N}, HashAlgo, _MasterSecret, Handshake) -> - tls_v1:certificate_verify(HashAlgo, N, lists:reverse(Handshake)). -calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) -> - tls_v1:finished(Role, N, PrfAlgo, MasterSecret, lists:reverse(Handshake)). +-spec calc_certificate_verify(ssl_record:ssl_version(), md5sha | ssl:hash(), _, [binary()]) -> binary(). +calc_certificate_verify(?'TLS-1.X', HashAlgo, _MasterSecret, Handshake) -> + tls_v1:certificate_verify(HashAlgo, lists:reverse(Handshake)). + +calc_finished(?'TLS-1.X'=Version, Role, PrfAlgo, MasterSecret, Handshake) -> + tls_v1:finished(Role, Version, PrfAlgo, MasterSecret, lists:reverse(Handshake)). master_secret(Version, MasterSecret, #security_parameters{ @@ -2357,11 +2351,12 @@ master_secret(Version, MasterSecret, {MasterSecret, ssl_record:set_pending_cipher_state(ConnStates2, ClientCipherState, ServerCipherState, Role)}. -setup_keys({3,N}, PrfAlgo, MasterSecret, +setup_keys({3,_}=Version, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) -> - tls_v1:setup_keys(N, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, + tls_v1:setup_keys(Version, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, IVS). -calc_master_secret({3,_}, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> +calc_master_secret(?'TLS-1.X'=Version, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) + when Version < ?'TLS-1.3' -> tls_v1:master_secret(PrfAlgo, PremasterSecret, ClientRandom, ServerRandom). %% Update pending connection states with parameters exchanged via @@ -2485,8 +2480,6 @@ encode_server_key(#server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B} <<?UINT16(NLen), N/binary, ?UINT16(GLen), G/binary, ?BYTE(SLen), S/binary, ?UINT16(BLen), B/binary>>. -encode_client_key(#encrypted_premaster_secret{premaster_secret = PKEPMS},{3, 0}) -> - PKEPMS; encode_client_key(#encrypted_premaster_secret{premaster_secret = PKEPMS}, _) -> PKEPMSLen = byte_size(PKEPMS), <<?UINT16(PKEPMSLen), PKEPMS/binary>>; @@ -2527,8 +2520,8 @@ encode_client_key(#client_srp_public{srp_a = A}, _) -> enc_sign({_, anon}, _Sign, _Version) -> <<>>; -enc_sign({HashAlg, SignAlg}, Signature, _Version = {Major, Minor}) - when Major == 3, Minor >= 3-> +enc_sign({HashAlg, SignAlg}, Signature, ?'TLS-1.X'=Version) + when Version >= ?'TLS-1.2'-> SignLen = byte_size(Signature), HashSign = enc_hashsign(HashAlg, SignAlg), <<HashSign/binary, ?UINT16(SignLen), Signature/binary>>; @@ -2720,8 +2713,6 @@ dec_server_key(<<?UINT16(NLen), N:NLen/binary, dec_server_key(_, KeyExchange, _) -> throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, {unknown_or_malformed_key_exchange, KeyExchange})). -dec_client_key(PKEPMS, ?KEY_EXCHANGE_RSA, {3, 0}) -> - #encrypted_premaster_secret{premaster_secret = PKEPMS}; dec_client_key(<<?UINT16(_), PKEPMS/binary>>, ?KEY_EXCHANGE_RSA, _) -> #encrypted_premaster_secret{premaster_secret = PKEPMS}; dec_client_key(<<>>, ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> @@ -2745,10 +2736,6 @@ dec_client_key(<<?UINT16(Len), Id:Len/binary, ?BYTE(DH_YLen), DH_Y:DH_YLen/binary>>, ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN_PSK, _) -> #client_ecdhe_psk_identity{identity = Id, dh_public = DH_Y}; -dec_client_key(<<?UINT16(Len), Id:Len/binary, PKEPMS/binary>>, - ?KEY_EXCHANGE_RSA_PSK, {3, 0}) -> - #client_rsa_psk_identity{identity = Id, - exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; dec_client_key(<<?UINT16(Len), Id:Len/binary, ?UINT16(_), PKEPMS/binary>>, ?KEY_EXCHANGE_RSA_PSK, _) -> #client_rsa_psk_identity{identity = Id, @@ -2762,27 +2749,27 @@ dec_server_key_params(Len, Keys, Version) -> dec_server_key_signature(Params, Signature, Version). dec_server_key_signature(Params, <<?BYTE(8), ?BYTE(SignAlgo), - ?UINT16(0)>>, {Major, Minor}) - when Major == 3, Minor >= 3 -> + ?UINT16(0)>>, ?'TLS-1.X'=Version) + when Version >= ?'TLS-1.2' -> <<?UINT16(Scheme0)>> = <<?BYTE(8), ?BYTE(SignAlgo)>>, Scheme = ssl_cipher:signature_scheme(Scheme0), {Hash, Sign, _} = ssl_cipher:scheme_to_components(Scheme), {Params, {Hash, Sign}, <<>>}; dec_server_key_signature(Params, <<?BYTE(8), ?BYTE(SignAlgo), - ?UINT16(Len), Signature:Len/binary>>, {Major, Minor}) - when Major == 3, Minor >= 3 -> + ?UINT16(Len), Signature:Len/binary>>, ?'TLS-1.X'=Version) + when Version >= ?'TLS-1.2' -> <<?UINT16(Scheme0)>> = <<?BYTE(8), ?BYTE(SignAlgo)>>, Scheme = ssl_cipher:signature_scheme(Scheme0), {Hash, Sign, _} = ssl_cipher:scheme_to_components(Scheme), {Params, {Hash, Sign}, Signature}; dec_server_key_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo), - ?UINT16(0)>>, {Major, Minor}) - when Major == 3, Minor >= 3 -> + ?UINT16(0)>>, ?'TLS-1.X'=Version) + when Version >= ?'TLS-1.2' -> HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}, {Params, HashSign, <<>>}; dec_server_key_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo), - ?UINT16(Len), Signature:Len/binary>>, {Major, Minor}) - when Major == 3, Minor >= 3 -> + ?UINT16(Len), Signature:Len/binary>>, ?'TLS-1.X'=Version) + when Version >= ?'TLS-1.2' -> HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}, {Params, HashSign, Signature}; dec_server_key_signature(Params, <<>>, _) -> @@ -2868,7 +2855,7 @@ decode_extensions(<<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen), decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) - when Version < {3,3} -> + when Version < ?'TLS-1.2' -> SignAlgoListLen = Len - 2, <<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData, HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} || @@ -2879,7 +2866,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), HashSignAlgos}}); decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) - when Version =:= {3,3} -> + when Version =:= ?'TLS-1.2' -> SignSchemeListLen = Len - 2, <<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData, HashSigns = decode_sign_alg(Version, SignSchemeList), @@ -2889,7 +2876,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), hash_sign_algos = HashSigns}}); decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) - when Version =:= {3,4} -> + when Version =:= ?'TLS-1.3' -> SignSchemeListLen = Len - 2, <<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData, SignSchemes = decode_sign_alg(Version, SignSchemeList), @@ -2900,7 +2887,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) - when Version =:= {3,4} -> + when Version =:= ?'TLS-1.3' -> SignSchemeListLen = Len - 2, <<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData, %% Ignore unknown signature algorithms @@ -2951,7 +2938,7 @@ decode_extensions(<<?UINT16(?USE_SRTP_EXT), ?UINT16(Len), decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) - when Version < {3,4} -> + when Version < ?'TLS-1.3' -> <<?UINT16(_), EllipticCurveList/binary>> = ExtData, %% Ignore unknown curves Pick = fun(Enum) -> @@ -2970,7 +2957,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len), decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) - when Version =:= {3,4} -> + when Version =:= ?'TLS-1.3' -> <<?UINT16(_), GroupList/binary>> = ExtData, %% Ignore unknown curves Pick = fun(Enum) -> @@ -3025,7 +3012,7 @@ decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len), decode_extensions(Rest, Version, MessageType, Acc#{server_hello_selected_version => #server_hello_selected_version{selected_version = - {3,4}}}); + ?'TLS-1.3'}}); decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len), ExtData:Len/binary, Rest/binary>>, @@ -3144,7 +3131,7 @@ decode_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>> decode_extensions(_, _, _, Acc) -> Acc. -decode_sign_alg({3,3}, SignSchemeList) -> +decode_sign_alg(?'TLS-1.2', SignSchemeList) -> %% Ignore unknown signature algorithms Fun = fun(Elem) -> case ssl_cipher:signature_scheme(Elem) of @@ -3169,7 +3156,7 @@ decode_sign_alg({3,3}, SignSchemeList) -> end, lists:filtermap(Fun, [SignScheme || <<?UINT16(SignScheme)>> <= SignSchemeList]); -decode_sign_alg({3,4}, SignSchemeList) -> +decode_sign_alg(?'TLS-1.3', SignSchemeList) -> %% Ignore unknown signature algorithms Fun = fun(Elem) -> case ssl_cipher:signature_scheme(Elem) of @@ -3183,7 +3170,7 @@ decode_sign_alg({3,4}, SignSchemeList) -> <<?UINT16(SignScheme)>> <= SignSchemeList]). dec_hashsign(Value) -> - [HashSign] = decode_sign_alg({3,3}, Value), + [HashSign] = decode_sign_alg(?'TLS-1.2', Value), HashSign. @@ -3420,7 +3407,7 @@ filter_hashsigns([Suite | Suites], [#{key_exchange := KeyExchange} | Algos], Has %% In this case hashsigns is not used as the kexchange is anonaymous filter_hashsigns(Suites, Algos, HashSigns, Version, [Suite| Acc]). -do_filter_hashsigns(rsa = SignAlgo, Suite, Suites, Algos, HashSigns, {3,3} = Version, Acc) -> +do_filter_hashsigns(rsa = SignAlgo, Suite, Suites, Algos, HashSigns, ?'TLS-1.2' = Version, Acc) -> case (lists:keymember(SignAlgo, 2, HashSigns) orelse lists:keymember(rsa_pss_rsae, 2, HashSigns) orelse lists:keymember(rsa_pss_pss, 2, HashSigns)) of @@ -3792,7 +3779,7 @@ cert_curve(Cert, ECCCurve0, CipherSuite) -> empty_extensions() -> #{}. -empty_extensions({3,4}, client_hello) -> +empty_extensions(?'TLS-1.3', client_hello) -> #{ sni => undefined, %% max_frag_enum => undefined, @@ -3816,8 +3803,8 @@ empty_extensions({3,4}, client_hello) -> %% post_handshake_auth => undefined, signature_algs_cert => undefined }; -empty_extensions({3, 3}, client_hello) -> - Ext = empty_extensions({3,2}, client_hello), +empty_extensions(?'TLS-1.2', client_hello) -> + Ext = empty_extensions(?'TLS-1.1', client_hello), Ext#{signature_algs => undefined}; empty_extensions(_, client_hello) -> #{renegotiation_info => undefined, @@ -3827,12 +3814,12 @@ empty_extensions(_, client_hello) -> ec_point_formats => undefined, elliptic_curves => undefined, sni => undefined}; -empty_extensions({3,4}, server_hello) -> +empty_extensions(?'TLS-1.3', server_hello) -> #{server_hello_selected_version => undefined, key_share => undefined, pre_shared_key => undefined }; -empty_extensions({3,4}, hello_retry_request) -> +empty_extensions(?'TLS-1.3', hello_retry_request) -> #{server_hello_selected_version => undefined, key_share => undefined, pre_shared_key => undefined, %% TODO remove! @@ -3922,7 +3909,7 @@ error_to_propagate({error, {bad_cert, root_cert_expired}} = Error, _) -> error_to_propagate(_, Error) -> Error. -path_validation_cb({3,4}) -> +path_validation_cb(?'TLS-1.3') -> tls_handshake_1_3; path_validation_cb(_) -> ?MODULE. diff --git a/lib/ssl/src/ssl_logger.erl b/lib/ssl/src/ssl_logger.erl index 8777233b81..570eca6881 100644 --- a/lib/ssl/src/ssl_logger.erl +++ b/lib/ssl/src/ssl_logger.erl @@ -290,19 +290,20 @@ get_server_version(Version, Extensions) -> Version end. -version({3,4}) -> +-spec version(ssl_record:ssl_version()) -> string(). +version(?'TLS-1.3') -> "TLS 1.3"; -version({3,3}) -> +version(?'TLS-1.2') -> "TLS 1.2"; -version({3,2}) -> +version(?'TLS-1.1') -> "TLS 1.1"; -version({3,1}) -> +version(?'TLS-1.0') -> "TLS 1.0"; -version({3,0}) -> +version(?'SSL-3.0') -> "SSL 3.0"; -version({254,253}) -> +version(?'DTLS-1.2') -> "DTLS 1.2"; -version({254,255}) -> +version(?'DTLS-1.0') -> "DTLS 1.0"; version({M,N}) -> io_lib:format("TLS/DTLS [0x0~B0~B]", [M,N]). diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index b7b68edd82..1ad6ccf467 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -55,11 +55,10 @@ -export([cipher/4, cipher/5, decipher/4, cipher_aead/4, cipher_aead/5, decipher_aead/5, is_correct_mac/2, nonce_seed/3]). --define(TLS_1_3, {3, 4}). -export_type([ssl_version/0, ssl_atom_version/0, connection_states/0, connection_state/0]). --type ssl_version() :: {integer(), integer()}. +-type ssl_version() :: {non_neg_integer(), non_neg_integer()}. -type ssl_atom_version() :: tls_record:tls_atom_version(). -type connection_states() :: map(). %% Map -type connection_state() :: map(). %% Map @@ -496,7 +495,7 @@ init_security_parameters(?SERVER, Version) -> #security_parameters{connection_end = ?SERVER, server_random = make_random(Version)}. -make_random({_Major, _Minor} = Version) when Version >= ?TLS_1_3 -> +make_random(Version) when Version >= ?'TLS-1.3' -> ssl_cipher:random_bytes(32); make_random(_Version) -> Secs_since_1970 = calendar:datetime_to_gregorian_seconds( diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl index e39ca92bc2..bcf383e749 100644 --- a/lib/ssl/src/ssl_record.hrl +++ b/lib/ssl/src/ssl_record.hrl @@ -180,4 +180,16 @@ next_iv % opaque IV[SecurityParameters.record_iv_length]; }). + +-define('TLS-1.X', {3, _}). +-define('TLS-1.3', {3, 4}). +-define('TLS-1.2', {3, 3}). +-define('TLS-1.1', {3, 2}). +-define('TLS-1.0', {3, 1}). +-define('DTLS-1.X', {254, _}). +-define('DTLS-1.0', {254, 255}). +-define('DTLS-1.2', {254, 253}). +-define('SSL-2.0', {2, 0}). +-define('SSL-3.0', {3, 0}). + -endif. % -ifdef(ssl_record). diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl index c551dbd93d..d45d751493 100644 --- a/lib/ssl/src/ssl_session.erl +++ b/lib/ssl/src/ssl_session.erl @@ -28,6 +28,7 @@ -include("ssl_handshake.hrl"). -include("ssl_internal.hrl"). -include("ssl_api.hrl"). +-include("ssl_record.hrl"). %% Internal application API -export([is_new/2, @@ -89,7 +90,7 @@ client_select_session({_, _, #{versions := Versions, HVersion = RecordCb:highest_protocol_version(Versions), case LVersion of - {3, 4} -> + ?'TLS-1.3' -> %% Session reuse is not supported, do pure legacy %% middlebox comp mode negotiation, by providing either %% empty session id (no middle box) or random id (middle @@ -241,7 +242,7 @@ record_cb(dtls) -> legacy_session_id() -> crypto:strong_rand_bytes(32). -maybe_handle_middlebox({3, 4}, #session{session_id = ?EMPTY_ID} = Session, Options)-> +maybe_handle_middlebox(?'TLS-1.3', #session{session_id = ?EMPTY_ID} = Session, Options)-> case maps:get(middlebox_comp_mode, Options,true) of true -> Session#session{session_id = legacy_session_id()}; diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 71db67bbd2..4f9cdaca73 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -597,7 +597,7 @@ choose_tls_fsm(#{versions := Versions}, } }) -> case ssl_handshake:select_supported_version(ClientVersions, Versions) of - {3,4} -> + ?'TLS-1.3' -> tls_1_3_fsm; _Else -> tls_1_0_to_1_2_fsm diff --git a/lib/ssl/src/tls_gen_connection.erl b/lib/ssl/src/tls_gen_connection.erl index ddea76c53a..b3ad5008a1 100644 --- a/lib/ssl/src/tls_gen_connection.erl +++ b/lib/ssl/src/tls_gen_connection.erl @@ -33,6 +33,7 @@ -include("ssl_alert.hrl"). -include("ssl_api.hrl"). -include("ssl_internal.hrl"). +-include("tls_record_1_3.hrl"). %% Setup -export([start_fsm/8, @@ -741,7 +742,7 @@ activate_socket(#state{protocol_specific = #{active_n_toggle := true, active_n : next_record(State, CipherTexts, ConnectionStates, Check) -> next_record(State, CipherTexts, ConnectionStates, Check, [], false). %% -next_record(#state{connection_env = #connection_env{negotiated_version = {3,4} = Version}} = State, +next_record(#state{connection_env = #connection_env{negotiated_version = ?'TLS-1.3' = Version}} = State, [CT|CipherTexts], ConnectionStates0, Check, Acc, IsEarlyData) -> case tls_record:decode_cipher_text(Version, CT, ConnectionStates0, Check) of {Record = #ssl_tls{type = ?APPLICATION_DATA, fragment = Fragment}, ConnectionStates} -> @@ -831,7 +832,7 @@ next_record_done(#state{protocol_buffers = Buffers} = State, CipherTexts, Connec %% field in TLS-1.3 client hello). The versions are instead negotiated with an hello extension. When %% decoding the server_hello messages we want to go through TLS-1.3 decode functions to be able %% to handle TLS-1.3 extensions if TLS-1.3 will be the negotiated version. -handle_unnegotiated_version({3,3} , #{versions := [{3,4} = Version |_]} = Options, Data, Buffer, client, hello) -> +handle_unnegotiated_version(?LEGACY_VERSION , #{versions := [?'TLS-1.3' = Version |_]} = Options, Data, Buffer, client, hello) -> %% The effective version for decoding the server hello message should be the TLS-1.3. Possible coalesced TLS-1.2 %% server handshake messages should be decoded with the negotiated version in later state. <<_:8, ?UINT24(Length), _/binary>> = Data, @@ -839,7 +840,7 @@ handle_unnegotiated_version({3,3} , #{versions := [{3,4} = Version |_]} = Option {HSPacket, <<>> = NewHsBuffer} = tls_handshake:get_tls_handshakes(Version, FirstPacket, Buffer, Options), {HSPacket, NewHsBuffer, RecordRest}; %% TLS-1.3 RetryRequest -handle_unnegotiated_version({3,3} , #{versions := [{3,4} = Version |_]} = Options, Data, Buffer, client, wait_sh) -> +handle_unnegotiated_version(?'TLS-1.2' , #{versions := [?'TLS-1.3' = Version |_]} = Options, Data, Buffer, client, wait_sh) -> tls_handshake:get_tls_handshakes(Version, Data, Buffer, Options); %% When the `negotiated_version` variable is not yet set use the highest supported version. handle_unnegotiated_version(undefined, #{versions := [Version|_]} = Options, Data, Buff, _, _) -> diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl index 6e2d0fa903..af8f8a18bf 100644 --- a/lib/ssl/src/tls_handshake.erl +++ b/lib/ssl/src/tls_handshake.erl @@ -74,9 +74,9 @@ client_hello(_Host, _Port, ConnectionStates, %% legacy_version field MUST be set to 0x0303, which is the version %% number for TLS 1.2. LegacyVersion = - case tls_record:is_higher(Version, {3,2}) of + case tls_record:is_higher(Version, ?'TLS-1.1') of true -> - {3,3}; + ?'TLS-1.2'; false -> Version end, @@ -168,15 +168,15 @@ hello(#server_hello{server_version = LegacyVersion, %% (Section 4.2.1), and the legacy_version field MUST be set to 0x0303, which is the version %% number for TLS 1.2. %% The "supported_versions" extension is supported from TLS 1.2. - case LegacyVersion > {3,3} orelse - LegacyVersion =:= {3,3} andalso Version < {3,3} of + case LegacyVersion > ?'TLS-1.2' orelse + LegacyVersion =:= ?'TLS-1.2' andalso Version < ?'TLS-1.2' of true -> throw(?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)); false -> case tls_record:is_acceptable_version(Version, SupportedVersions) of true -> case Version of - {3,3} -> + ?'TLS-1.2' -> IsNew = ssl_session:is_new(OldId, SessionId), %% TLS 1.2 ServerHello with "supported_versions" (special case) handle_server_hello_extensions(Version, SessionId, Random, CipherSuite, @@ -342,7 +342,7 @@ handle_client_hello(Version, ClientSignatureSchemes = get_signature_ext(signature_algs_cert, HelloExt, Version), AvailableHashSigns = ssl_handshake:available_signature_algs( ClientHashSigns, SupportedHashSigns, Version), - ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, Version, ECCOrder), + ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, ECCOrder), {Type, #session{cipher_suite = CipherSuite, own_certificates = [OwnCert |_]} = Session1} = ssl_handshake:select_session(SugesstedId, CipherSuites, @@ -409,7 +409,7 @@ do_hello(Version, Versions, CipherSuites, Hello, SslOpts, Info, Renegotiation) - end. %%-------------------------------------------------------------------- -enc_handshake(#hello_request{}, {3, N}) when N < 4 -> +enc_handshake(#hello_request{}, ?'TLS-1.X'=Version) when Version < ?'TLS-1.3' -> {?HELLO_REQUEST, <<>>}; enc_handshake(#client_hello{client_version = {Major, Minor} = Version, random = Random, @@ -428,7 +428,7 @@ enc_handshake(#client_hello{client_version = {Major, Minor} = Version, ?BYTE(SIDLength), SessionID/binary, ?UINT16(CsLength), BinCipherSuites/binary, ?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>}; -enc_handshake(HandshakeMsg, {3, 4}) -> +enc_handshake(HandshakeMsg, ?'TLS-1.3') -> tls_handshake_1_3:encode_handshake(HandshakeMsg); enc_handshake(HandshakeMsg, Version) -> ssl_handshake:encode_handshake(HandshakeMsg, Version). @@ -450,7 +450,8 @@ get_tls_handshakes_aux(Version, <<?BYTE(Type), ?UINT24(Length), get_tls_handshakes_aux(_Version, Data, _, Acc) -> {lists:reverse(Acc), Data}. -decode_handshake({3, N}, ?HELLO_REQUEST, <<>>) when N < 4 -> +decode_handshake(?'TLS-1.X'=Version, ?HELLO_REQUEST, <<>>) + when Version < ?'TLS-1.3' -> #hello_request{}; decode_handshake(Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, @@ -469,7 +470,7 @@ decode_handshake(Version, ?CLIENT_HELLO, compression_methods = erlang:binary_to_list(Comp_methods), extensions = DecodedExtensions }; -decode_handshake({3, 4}, Tag, Msg) -> +decode_handshake(?'TLS-1.3', Tag, Msg) -> tls_handshake_1_3:decode_handshake(Tag, Msg); decode_handshake(Version, Tag, Msg) -> ssl_handshake:decode_handshake(Version, Tag, Msg). @@ -480,7 +481,7 @@ ocsp_expect(true) -> ocsp_expect(_) -> no_staple. -get_signature_ext(Ext, HelloExt, {3,3}) -> +get_signature_ext(Ext, HelloExt, ?'TLS-1.2') -> case maps:get(Ext, HelloExt, undefined) of %% Signature algorithms was not sent undefined -> diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl index 6f883b7b64..1aab52c7fd 100644 --- a/lib/ssl/src/tls_handshake_1_3.erl +++ b/lib/ssl/src/tls_handshake_1_3.erl @@ -106,7 +106,7 @@ server_hello(MsgType, SessionId, KeyShare, PSK, ConnectionStates) -> #{security_parameters := SecParams} = ssl_record:pending_connection_state(ConnectionStates, read), Extensions = server_hello_extensions(MsgType, KeyShare, PSK), - #server_hello{server_version = {3,3}, %% legacy_version + #server_hello{server_version = ?LEGACY_VERSION, %% legacy_version cipher_suite = SecParams#security_parameters.cipher_suite, compression_method = 0, %% legacy attribute random = server_hello_random(MsgType, SecParams), @@ -123,15 +123,15 @@ server_hello(MsgType, SessionId, KeyShare, PSK, ConnectionStates) -> %% ClientHello, with the exception of optionally the "cookie" (see %% Section 4.2.2) extension. server_hello_extensions(hello_retry_request = MsgType, KeyShare, _) -> - SupportedVersions = #server_hello_selected_version{selected_version = {3,4}}, + SupportedVersions = #server_hello_selected_version{selected_version = ?'TLS-1.3'}, Extensions = #{server_hello_selected_version => SupportedVersions}, ssl_handshake:add_server_share(MsgType, Extensions, KeyShare); server_hello_extensions(MsgType, KeyShare, undefined) -> - SupportedVersions = #server_hello_selected_version{selected_version = {3,4}}, + SupportedVersions = #server_hello_selected_version{selected_version = ?'TLS-1.3'}, Extensions = #{server_hello_selected_version => SupportedVersions}, ssl_handshake:add_server_share(MsgType, Extensions, KeyShare); server_hello_extensions(MsgType, KeyShare, {SelectedIdentity, _}) -> - SupportedVersions = #server_hello_selected_version{selected_version = {3,4}}, + SupportedVersions = #server_hello_selected_version{selected_version = ?'TLS-1.3'}, PreSharedKey = #pre_shared_key_server_hello{selected_identity = SelectedIdentity}, Extensions = #{server_hello_selected_version => SupportedVersions, pre_shared_key => PreSharedKey}, @@ -571,7 +571,7 @@ encode_handshake(#key_update{request_update = Update}) -> EncUpdate = encode_key_update(Update), {?KEY_UPDATE, <<EncUpdate/binary>>}; encode_handshake(HandshakeMsg) -> - ssl_handshake:encode_handshake(HandshakeMsg, {3,4}). + ssl_handshake:encode_handshake(HandshakeMsg, ?'TLS-1.3'). encode_early_data(Cipher, #state{ @@ -604,7 +604,7 @@ decode_handshake(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, Cipher_suite:2/binary, ?BYTE(Comp_method), ?UINT16(ExtLen), Extensions:ExtLen/binary>>) when Random =:= ?HELLO_RETRY_REQUEST_RANDOM -> - HelloExtensions = ssl_handshake:decode_hello_extensions(Extensions, {3,4}, {Major, Minor}, + HelloExtensions = ssl_handshake:decode_hello_extensions(Extensions, ?'TLS-1.3', {Major, Minor}, hello_retry_request), #server_hello{ server_version = {Major,Minor}, @@ -661,7 +661,7 @@ decode_handshake(?END_OF_EARLY_DATA, _) -> decode_handshake(?KEY_UPDATE, <<?BYTE(Update)>>) -> #key_update{request_update = decode_key_update(Update)}; decode_handshake(Tag, HandshakeMsg) -> - ssl_handshake:decode_handshake({3,4}, Tag, HandshakeMsg). + ssl_handshake:decode_handshake(?'TLS-1.3', Tag, HandshakeMsg). is_valid_binder(Binder, HHistory, PSK, Hash) -> case HHistory of @@ -741,7 +741,7 @@ encode_extensions(Exts)-> ssl_handshake:encode_extensions(extensions_list(Exts)). decode_extensions(Exts, MessageType) -> - ssl_handshake:decode_extensions(Exts, {3,4}, MessageType). + ssl_handshake:decode_extensions(Exts, ?'TLS-1.3', MessageType). extensions_list(Extensions) -> [Ext || {_, Ext} <- maps:to_list(Extensions)]. @@ -780,7 +780,7 @@ certificate_entry(DER) -> sign(THash, Context, HashAlgo, PrivateKey, SignAlgo) -> Content = build_content(Context, THash), try - {ok, ssl_handshake:digitally_signed({3,4}, Content, HashAlgo, PrivateKey, SignAlgo)} + {ok, ssl_handshake:digitally_signed(?'TLS-1.3', Content, HashAlgo, PrivateKey, SignAlgo)} catch throw:Alert -> {error, Alert} end. @@ -788,7 +788,7 @@ sign(THash, Context, HashAlgo, PrivateKey, SignAlgo) -> verify(THash, Context, HashAlgo, SignAlgo, Signature, PublicKeyInfo) -> Content = build_content(Context, THash), - try ssl_handshake:verify_signature({3, 4}, Content, {HashAlgo, SignAlgo}, Signature, PublicKeyInfo) of + try ssl_handshake:verify_signature(?'TLS-1.3', Content, {HashAlgo, SignAlgo}, Signature, PublicKeyInfo) of Result -> {ok, Result} catch @@ -824,7 +824,7 @@ validate_certificate_chain(CertEntries, CertDbHandle, CertDbRef, ?DEFAULT_OCSP_RESPONDER_CERTS end, ssl_handshake:certify(#certificate{asn1_certificates = Certs}, CertDbHandle, CertDbRef, - SslOptions, CRLDbHandle, Role, Host, {3,4}, + SslOptions, CRLDbHandle, Role, Host, ?'TLS-1.3', #{cert_ext => CertExt, ocsp_state => OcspState, ocsp_responder_certs => OcspResponderCerts}). @@ -1265,7 +1265,7 @@ update_start_state(#state{connection_states = ConnectionStates0, sign_alg = SelectedSignAlg, dh_public_value = PeerPublicKey, cipher_suite = Cipher}, - connection_env = CEnv#connection_env{negotiated_version = {3,4}}}. + connection_env = CEnv#connection_env{negotiated_version = ?'TLS-1.3'}}. update_resumption_master_secret(#state{connection_states = ConnectionStates0} = State, @@ -1640,25 +1640,25 @@ handle_pre_shared_key(#state{ssl_options = #{session_tickets := Tickets}, %% message, as described in Section 4.4.1. maybe_add_binders(Hello, undefined, _) -> Hello; -maybe_add_binders(Hello0, TicketData, Version) when Version =:= {3,4} -> +maybe_add_binders(Hello0, TicketData, Version) when Version =:= ?'TLS-1.3' -> HelloBin0 = tls_handshake:encode_handshake(Hello0, Version), HelloBin1 = iolist_to_binary(HelloBin0), Truncated = truncate_client_hello(HelloBin1), Binders = create_binders([Truncated], TicketData), update_binders(Hello0, Binders); -maybe_add_binders(Hello, _, Version) when Version =< {3,3} -> +maybe_add_binders(Hello, _, Version) when Version =< ?'TLS-1.2' -> Hello. %% %% HelloRetryRequest maybe_add_binders(Hello, _, undefined, _) -> Hello; -maybe_add_binders(Hello0, {[HRR,MessageHash|_], _}, TicketData, Version) when Version =:= {3,4} -> +maybe_add_binders(Hello0, {[HRR,MessageHash|_], _}, TicketData, Version) when Version =:= ?'TLS-1.3' -> HelloBin0 = tls_handshake:encode_handshake(Hello0, Version), HelloBin1 = iolist_to_binary(HelloBin0), Truncated = truncate_client_hello(HelloBin1), Binders = create_binders([MessageHash,HRR,Truncated], TicketData), update_binders(Hello0, Binders); -maybe_add_binders(Hello, _, _, Version) when Version =< {3,3} -> +maybe_add_binders(Hello, _, _, Version) when Version =< ?'TLS-1.2' -> Hello. create_binders(Context, TicketData) -> @@ -1684,7 +1684,7 @@ truncate_client_hello(HelloBin0) -> <<?BYTE(Type), ?UINT24(_Length), Body/binary>> = HelloBin0, CH0 = #client_hello{ extensions = #{pre_shared_key := PSK0} = Extensions0} = - tls_handshake:decode_handshake({3,4}, Type, Body), + tls_handshake:decode_handshake(?'TLS-1.3', Type, Body), #pre_shared_key_client_hello{offered_psks = OfferedPsks0} = PSK0, OfferedPsks = OfferedPsks0#offered_psks{binders = []}, PSK = PSK0#pre_shared_key_client_hello{offered_psks = OfferedPsks}, @@ -1697,8 +1697,8 @@ truncate_client_hello(HelloBin0) -> %% The original length of the binders can still be determined by %% re-encoding the original ClientHello and using its size as reference %% when we subtract the size of the truncated binary. - TruncatedSize = iolist_size(tls_handshake:encode_handshake(CH, {3,4})), - RefSize = iolist_size(tls_handshake:encode_handshake(CH0, {3,4})), + TruncatedSize = iolist_size(tls_handshake:encode_handshake(CH, ?'TLS-1.3')), + RefSize = iolist_size(tls_handshake:encode_handshake(CH0, ?'TLS-1.3')), BindersSize = RefSize - TruncatedSize, %% Return the truncated ClientHello by cutting of the binders from the original @@ -1710,7 +1710,7 @@ maybe_add_early_data_indication(#client_hello{ extensions = Extensions0} = ClientHello, EarlyData, Version) - when Version =:= {3,4} andalso + when Version =:= ?'TLS-1.3' andalso is_binary(EarlyData) andalso byte_size(EarlyData) > 0 -> Extensions = Extensions0#{early_data => @@ -1785,7 +1785,7 @@ choose_ticket(_, _) -> ciphers_for_early_data(CipherSuites0) -> %% Use only supported TLS 1.3 cipher suites Supported = lists:filter(fun(CipherSuite) -> - lists:member(CipherSuite, tls_v1:exclusive_suites(4)) end, + lists:member(CipherSuite, tls_v1:exclusive_suites(?'TLS-1.3')) end, CipherSuites0), %% Return supported block cipher algorithms lists:map(fun(#{cipher := Cipher}) -> Cipher end, diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl index ff23b2a99b..7bab5199b5 100644 --- a/lib/ssl/src/tls_record.erl +++ b/lib/ssl/src/tls_record.erl @@ -130,7 +130,7 @@ get_tls_records(Data, Versions, {Hdr, {Front,Size,Rear}}, MaxFragLen, SslOpts) - % %% Description: Encodes a handshake message to send on the ssl-socket. %%-------------------------------------------------------------------- -encode_handshake(Frag, {3, 4}, ConnectionStates) -> +encode_handshake(Frag, ?'TLS-1.3', ConnectionStates) -> tls_record_1_3:encode_handshake(Frag, ConnectionStates); encode_handshake(Frag, Version, #{current_write := @@ -158,7 +158,7 @@ encode_handshake(Frag, Version, %% %% Description: Encodes an alert message to send on the ssl-socket. %%-------------------------------------------------------------------- -encode_alert_record(Alert, {3, 4}, ConnectionStates) -> +encode_alert_record(Alert, ?'TLS-1.3', ConnectionStates) -> tls_record_1_3:encode_alert_record(Alert, ConnectionStates); encode_alert_record(#alert{level = Level, description = Description}, Version, ConnectionStates) -> @@ -180,7 +180,7 @@ encode_change_cipher_spec(Version, ConnectionStates) -> %% %% Description: Encodes data to send on the ssl-socket. %%-------------------------------------------------------------------- -encode_data(Data, {3, 4}, ConnectionStates) -> +encode_data(Data, ?'TLS-1.3', ConnectionStates) -> tls_record_1_3:encode_data(Data, ConnectionStates); encode_data(Data, Version, #{current_write := #{beast_mitigation := BeastMitigation, @@ -207,7 +207,7 @@ encode_data(Data, Version, %% %% Description: Decode cipher text %%-------------------------------------------------------------------- -decode_cipher_text({3,4}, CipherTextRecord, ConnectionStates, _) -> +decode_cipher_text(?'TLS-1.3', CipherTextRecord, ConnectionStates, _) -> tls_record_1_3:decode_cipher_text(CipherTextRecord, ConnectionStates); decode_cipher_text(_, CipherTextRecord, #{current_read := @@ -279,26 +279,26 @@ decode_cipher_text(_, #ssl_tls{version = Version, %% or vice versa. %%-------------------------------------------------------------------- protocol_version('tlsv1.3') -> - {3, 4}; + ?'TLS-1.3'; protocol_version('tlsv1.2') -> - {3, 3}; + ?'TLS-1.2'; protocol_version('tlsv1.1') -> - {3, 2}; + ?'TLS-1.1'; protocol_version(tlsv1) -> - {3, 1}; + ?'TLS-1.0'; protocol_version(sslv3) -> - {3, 0}; + ?'SSL-3.0'; protocol_version(sslv2) -> %% Backwards compatibility - {2, 0}; -protocol_version({3, 4}) -> + ?'SSL-2.0'; +protocol_version(?'TLS-1.3') -> 'tlsv1.3'; -protocol_version({3, 3}) -> +protocol_version(?'TLS-1.2') -> 'tlsv1.2'; -protocol_version({3, 2}) -> +protocol_version(?'TLS-1.1') -> 'tlsv1.1'; -protocol_version({3, 1}) -> +protocol_version(?'TLS-1.0') -> tlsv1; -protocol_version({3, 0}) -> +protocol_version(?'SSL-3.0') -> sslv3. %%-------------------------------------------------------------------- -spec lowest_protocol_version(tls_version(), tls_version()) -> tls_version(). @@ -473,8 +473,8 @@ is_acceptable_version(_,_) -> false. -spec hello_version([tls_version()]) -> tls_version(). -hello_version([Highest|_]) when Highest >= {3,3} -> - {3,3}; +hello_version([Highest|_]) when Highest >= ?'TLS-1.2' -> + ?'TLS-1.2'; hello_version(Versions) -> lowest_protocol_version(Versions). @@ -576,7 +576,7 @@ validate_tls_record_version(Versions, Q, MaxFragLen, SslOpts, Acc, Type, Version false -> ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, {unsupported_version, Version}) end; - {3, 4} when Version =:= {3, 3} -> + ?'TLS-1.3' when Version =:= ?'TLS-1.2' -> validate_tls_record_length(Versions, Q, MaxFragLen, SslOpts, Acc, Type, Version, Length); Version -> %% Exact version match @@ -718,15 +718,13 @@ encode_fragments(Type, Version, [Text|Data], %% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 ciphers are %% not vulnerable to this attack. split_iovec(Data, Version, BCA, one_n_minus_one, MaxLength) - when (BCA =/= ?RC4) andalso ({3, 1} == Version orelse - {3, 0} == Version) -> + when BCA =/= ?RC4, ?'TLS-1.0' == Version -> {Part, RestData} = split_iovec(Data, 1, []), [Part|split_iovec(RestData, MaxLength)]; %% 0/n splitting countermeasure for clients that are incompatible with 1/n-1 %% splitting. split_iovec(Data, Version, BCA, zero_n, MaxLength) - when (BCA =/= ?RC4) andalso ({3, 1} == Version orelse - {3, 0} == Version) -> + when BCA =/= ?RC4, ?'TLS-1.0' == Version -> {Part, RestData} = split_iovec(Data, 0, []), [Part|split_iovec(RestData, MaxLength)]; split_iovec(Data, _Version, _BCA, _BeatMitigation, MaxLength) -> @@ -763,7 +761,7 @@ highest_protocol_version() -> lowest_protocol_version() -> lowest_protocol_version(supported_protocol_versions()). -max_len([{3,4}|_])-> +max_len([?'TLS-1.3'|_])-> ?TLS13_MAX_CIPHER_TEXT_LENGTH; max_len(_) -> ?MAX_CIPHER_TEXT_LENGTH. diff --git a/lib/ssl/src/tls_record_1_3.erl b/lib/ssl/src/tls_record_1_3.erl index 440d9e0998..2a256b77d8 100644 --- a/lib/ssl/src/tls_record_1_3.erl +++ b/lib/ssl/src/tls_record_1_3.erl @@ -171,7 +171,7 @@ decode_cipher_text(#ssl_tls{type = ?ALERT, fragment = <<?FATAL,?ILLEGAL_PARAMETER>>}, ConnectionStates0) -> {#ssl_tls{type = ?ALERT, - version = {3,4}, %% Internally use real version + version = ?'TLS-1.3', %% Internally use real version fragment = <<?FATAL,?ILLEGAL_PARAMETER>>}, ConnectionStates0}; %% TLS 1.3 server can receive a User Cancelled Alert when handshake is %% paused and then cancelled on the client side. @@ -180,7 +180,7 @@ decode_cipher_text(#ssl_tls{type = ?ALERT, fragment = <<?FATAL,?USER_CANCELED>>}, ConnectionStates0) -> {#ssl_tls{type = ?ALERT, - version = {3,4}, %% Internally use real version + version = ?'TLS-1.3', %% Internally use real version fragment = <<?FATAL,?USER_CANCELED>>}, ConnectionStates0}; %% RFC8446 - TLS 1.3 %% D.4. Middlebox Compatibility Mode @@ -195,7 +195,7 @@ decode_cipher_text(#ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>}, ConnectionStates0) -> {#ssl_tls{type = ?CHANGE_CIPHER_SPEC, - version = {3,4}, %% Internally use real version + version = ?'TLS-1.3', %% Internally use real version fragment = <<1>>}, ConnectionStates0}; decode_cipher_text(#ssl_tls{type = Type, version = ?LEGACY_VERSION, @@ -206,7 +206,7 @@ decode_cipher_text(#ssl_tls{type = Type, cipher_suite = ?TLS_NULL_WITH_NULL_NULL} }} = ConnnectionStates0) -> {#ssl_tls{type = Type, - version = {3,4}, %% Internally use real version + version = ?'TLS-1.3', %% Internally use real version fragment = CipherFragment}, ConnnectionStates0}; decode_cipher_text(#ssl_tls{type = Type}, _) -> %% Version mismatch is already asserted @@ -288,7 +288,7 @@ encode_plain_text(#inner_plaintext{ Encoded = cipher_aead(PlainText, BulkCipherAlgo, Key, Seq, IV, TagLen), %% 23 (application_data) for outward compatibility #tls_cipher_text{opaque_type = ?OPAQUE_TYPE, - legacy_version = {3,3}, + legacy_version = ?LEGACY_VERSION, encoded_record = Encoded}; encode_plain_text(#inner_plaintext{ content = Data, @@ -301,7 +301,7 @@ encode_plain_text(#inner_plaintext{ %% When record protection has not yet been engaged, TLSPlaintext %% structures are written directly onto the wire. #tls_cipher_text{opaque_type = Type, - legacy_version = {3,3}, + legacy_version = ?'TLS-1.2', encoded_record = Data}. additional_data(Length) -> @@ -375,7 +375,7 @@ decode_inner_plaintext(PlainText) -> Type =:= ?HANDSHAKE orelse Type =:= ?ALERT -> #ssl_tls{type = Type, - version = {3,4}, %% Internally use real version + version = ?'TLS-1.3', %% Internally use real version fragment = init_binary(PlainText)}; _Else -> ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE, empty_alert) diff --git a/lib/ssl/src/tls_record_1_3.hrl b/lib/ssl/src/tls_record_1_3.hrl index c6214a5de3..bee16d603d 100644 --- a/lib/ssl/src/tls_record_1_3.hrl +++ b/lib/ssl/src/tls_record_1_3.hrl @@ -43,7 +43,7 @@ %% } ContentType; -define(INVALID, 0). --define(LEGACY_VERSION, {3,3}). +-define(LEGACY_VERSION, ?'TLS-1.2'). -define(OPAQUE_TYPE, 23). -record(inner_plaintext, { diff --git a/lib/ssl/src/tls_sender.erl b/lib/ssl/src/tls_sender.erl index 45244015be..856db9f16c 100644 --- a/lib/ssl/src/tls_sender.erl +++ b/lib/ssl/src/tls_sender.erl @@ -575,7 +575,7 @@ maybe_update_cipher_key(#data{connection_states = ConnectionStates0, maybe_update_cipher_key(StateData, _) -> StateData. -update_bytes_sent(Version, StateData, _) when Version < {3,4} -> +update_bytes_sent(Version, StateData, _) when Version < ?'TLS-1.3' -> StateData; %% Count bytes sent in TLS 1.3 for AES-GCM update_bytes_sent(_, #data{static = #static{key_update_at = seq_num_wrap}} = StateData, _) -> @@ -588,20 +588,12 @@ update_bytes_sent(_, #data{static = #static{bytes_sent = Sent} = Static} = State %% approximately 2^-57 for Authenticated Encryption (AE) security. For %% ChaCha20/Poly1305, the record sequence number would wrap before the %% safety limit is reached. -key_update_at(Version, #{security_parameters := +key_update_at(?'TLS-1.3', #{security_parameters := #security_parameters{ - bulk_cipher_algorithm = CipherAlgo}}, KeyUpdateAt) - when Version >= {3,4} -> - case CipherAlgo of - ?AES_GCM -> - KeyUpdateAt; - ?CHACHA20_POLY1305 -> - seq_num_wrap; - ?AES_CCM -> - KeyUpdateAt; - ?AES_CCM_8 -> - KeyUpdateAt - end; + bulk_cipher_algorithm = ?CHACHA20_POLY1305}}, _KeyUpdateAt) -> + seq_num_wrap; +key_update_at(?'TLS-1.3', _, KeyUpdateAt) -> + KeyUpdateAt; key_update_at(_, _, KeyUpdateAt) -> KeyUpdateAt. @@ -624,11 +616,11 @@ set_opts(SocketOptions, [{packet, N}]) -> time_to_rekey(Version, _Data, #{current_write := #{sequence_number := ?MAX_SEQUENCE_NUMBER}}, - _, _, _) when Version >= {3,4} -> + _, _, _) when Version >= ?'TLS-1.3' -> key_update; -time_to_rekey(Version, _Data, _, _, seq_num_wrap, _) when Version >= {3,4} -> +time_to_rekey(Version, _Data, _, _, seq_num_wrap, _) when Version >= ?'TLS-1.3' -> false; -time_to_rekey(Version, Data, _, _, KeyUpdateAt, BytesSent) when Version >= {3,4} -> +time_to_rekey(Version, Data, _, _, KeyUpdateAt, BytesSent) when Version >= ?'TLS-1.3' -> DataSize = iolist_size(Data), case (BytesSent + DataSize) > KeyUpdateAt of true -> diff --git a/lib/ssl/src/tls_server_connection_1_3.erl b/lib/ssl/src/tls_server_connection_1_3.erl index 08d147709e..ab9c7884fa 100644 --- a/lib/ssl/src/tls_server_connection_1_3.erl +++ b/lib/ssl/src/tls_server_connection_1_3.erl @@ -174,7 +174,7 @@ user_hello({call, From}, {handshake_continue, NewOptions, Timeout}, Options = #{versions := Versions} -> State = ssl_gen_statem:ssl_config(Options, ?SERVER_ROLE, State0), case ssl_handshake:select_supported_version(ClientVersions, Versions) of - {3,4} -> + ?'TLS-1.3' -> {next_state, start, State#state{start_or_recv_from = From, handshake_env = HSEnv#handshake_env{continue_status = continue}}, [{{timeout, handshake}, Timeout, close}]}; @@ -216,7 +216,7 @@ start(internal, #client_hello{extensions = #{client_hello_versions := #client_hello_versions{versions = ClientVersions} }} = Hello, #state{ssl_options = #{handshake := full}} = State) -> - case tls_record:is_acceptable_version({3,4}, ClientVersions) of + case tls_record:is_acceptable_version(?'TLS-1.3', ClientVersions) of true -> handle_client_hello(Hello, State); false -> @@ -435,7 +435,7 @@ do_handle_client_hello(#client_hello{cipher_suites = ClientCiphers, Groups = Maybe(tls_handshake_1_3:select_common_groups(ServerGroups, ClientGroups)), Maybe(validate_client_key_share(ClientGroups, ClientShares#key_share_client_hello.client_shares)), - CertKeyPairs = ssl_certificate:available_cert_key_pairs(CertKeyAlts, {3,4}), + CertKeyPairs = ssl_certificate:available_cert_key_pairs(CertKeyAlts, ?'TLS-1.3'), #session{own_certificates = [Cert|_]} = Session = Maybe(select_server_cert_key_pair(Session0, CertKeyPairs, ClientSignAlgs, ClientSignAlgsCert, CertAuths, State0, @@ -883,7 +883,7 @@ select_cipher_suite(_, [], _) -> select_cipher_suite(true, ClientCiphers, ServerCiphers) -> select_cipher_suite(false, ServerCiphers, ClientCiphers); select_cipher_suite(false, [Cipher|ClientCiphers], ServerCiphers) -> - case lists:member(Cipher, tls_v1:exclusive_suites(4)) andalso + case lists:member(Cipher, tls_v1:exclusive_suites(?'TLS-1.3')) andalso lists:member(Cipher, ServerCiphers) of true -> {ok, Cipher}; diff --git a/lib/ssl/src/tls_socket.erl b/lib/ssl/src/tls_socket.erl index aa25d63ba9..0a4920fe3a 100644 --- a/lib/ssl/src/tls_socket.erl +++ b/lib/ssl/src/tls_socket.erl @@ -23,6 +23,7 @@ -include("ssl_internal.hrl"). -include("ssl_api.hrl"). +-include("ssl_record.hrl"). -export([send/3, listen/3, @@ -282,7 +283,7 @@ session_tickets_tracker(ListenSocket, Lifetime, TicketStoreSize, MaxEarlyDataSiz TicketStoreSize, MaxEarlyDataSize, AntiReplay, Seed]). -session_id_tracker(_, #{versions := [{3,4}]}) -> +session_id_tracker(_, #{versions := [?'TLS-1.3']}) -> {ok, not_relevant}; %% Regardless of the option reuse_sessions we need the session_id_tracker %% to generate session ids, but no sessions will be stored unless diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl index 502410182b..24ad57344c 100644 --- a/lib/ssl/src/tls_v1.erl +++ b/lib/ssl/src/tls_v1.erl @@ -29,13 +29,13 @@ -include("ssl_internal.hrl"). -include("ssl_record.hrl"). --export([master_secret/4, - finished/5, - certificate_verify/3, - mac_hash/7, +-export([master_secret/4, + finished/5, + certificate_verify/2, + mac_hash/7, hmac_hash/3, - setup_keys/8, - suites/1, + setup_keys/8, + suites/1, exclusive_suites/1, exclusive_anonymous_suites/1, psk_suites/1, @@ -44,50 +44,49 @@ srp_suites/1, srp_suites_anon/1, srp_exclusive/1, - rc4_suites/1, + rc4_suites/1, rc4_exclusive/1, des_suites/1, des_exclusive/1, rsa_suites/1, rsa_exclusive/1, prf/5, - ecc_curves/1, - ecc_curves/2, - oid_to_enum/1, - enum_to_oid/1, - default_signature_algs/1, + ecc_curves/1, + oid_to_enum/1, + enum_to_oid/1, + default_signature_algs/1, signature_algs/2, signature_schemes/2, rsa_schemes/0, - groups/1, - groups/2, - group_to_enum/1, - enum_to_group/1, - default_groups/1]). - --export([derive_secret/4, - hkdf_expand_label/5, - hkdf_extract/3, + groups/0, + groups/1, + group_to_enum/1, + enum_to_group/1, + default_groups/0]). + +-export([derive_secret/4, + hkdf_expand_label/5, + hkdf_extract/3, hkdf_expand/4, key_length/1, - key_schedule/3, - key_schedule/4, + key_schedule/3, + key_schedule/4, create_info/3, - external_binder_key/2, + external_binder_key/2, resumption_binder_key/2, - client_early_traffic_secret/3, + client_early_traffic_secret/3, early_exporter_master_secret/3, - client_handshake_traffic_secret/3, + client_handshake_traffic_secret/3, server_handshake_traffic_secret/3, - client_application_traffic_secret_0/3, + client_application_traffic_secret_0/3, server_application_traffic_secret_0/3, - exporter_master_secret/3, + exporter_master_secret/3, resumption_master_secret/3, - update_traffic_secret/2, + update_traffic_secret/2, calculate_traffic_keys/3, - transcript_hash/2, - finished_key/2, - finished_verify_data/3, + transcript_hash/2, + finished_key/2, + finished_verify_data/3, pre_shared_key/3]). %% Tracing @@ -118,7 +117,7 @@ derive_secret(Secret, Label, Messages, Algo) -> Hash, ssl_cipher:hash_size(Algo), Algo). -spec hkdf_expand_label(Secret::binary(), Label0::binary(), - Context::binary(), Length::integer(), + Context::binary(), Length::integer(), Algo::ssl:hash()) -> KeyingMaterial::binary(). hkdf_expand_label(Secret, Label0, Context, Length, Algo) -> HkdfLabel = create_info(Label0, Context, Length), @@ -143,14 +142,14 @@ create_info(Label0, Context0, Length) -> -spec hkdf_extract(MacAlg::ssl:hash(), Salt::binary(), KeyingMaterial::binary()) -> PseudoRandKey::binary(). -hkdf_extract(MacAlg, Salt, KeyingMaterial) -> +hkdf_extract(MacAlg, Salt, KeyingMaterial) -> hmac_hash(MacAlg, Salt, KeyingMaterial). -spec hkdf_expand(PseudoRandKey::binary(), ContextInfo::binary(), Length::integer(), Algo::ssl:hash()) -> KeyingMaterial::binary(). - -hkdf_expand(PseudoRandKey, ContextInfo, Length, Algo) -> + +hkdf_expand(PseudoRandKey, ContextInfo, Length, Algo) -> Iterations = erlang:ceil(Length / ssl_cipher:hash_size(Algo)), hkdf_expand(Algo, PseudoRandKey, ContextInfo, Length, 1, Iterations, <<>>, <<>>). @@ -173,10 +172,15 @@ master_secret(PrfAlgo, PreMasterSecret, ClientRandom, ServerRandom) -> [ClientRandom, ServerRandom], 48). %% TLS 1.0 -1.2 --------------------------------------------------- --spec finished(client | server, integer(), integer(), binary(), [binary()]) -> binary(). +-spec finished(Role, Version, PrfAlgo, MasterSecret, Handshake) -> binary() when + Role :: client | server, + Version :: ssl_record:ssl_version(), + PrfAlgo :: integer(), + MasterSecret :: binary(), + Handshake :: [binary()]. %% TLS 1.0 -1.1 --------------------------------------------------- finished(Role, Version, PrfAlgo, MasterSecret, Handshake) - when Version == 1; Version == 2; PrfAlgo == ?MD5SHA -> + when Version == ?'TLS-1.0'; Version == ?'TLS-1.1'; PrfAlgo == ?MD5SHA -> %% RFC 2246 & 4346 - 7.4.9. Finished %% struct { %% opaque verify_data[12]; @@ -192,7 +196,7 @@ finished(Role, Version, PrfAlgo, MasterSecret, Handshake) %% TLS 1.2 --------------------------------------------------- finished(Role, Version, PrfAlgo, MasterSecret, Handshake) - when Version == 3 -> + when Version == ?'TLS-1.2' -> %% RFC 5246 - 7.4.9. Finished %% struct { %% opaque verify_data[12]; @@ -206,30 +210,29 @@ finished(Role, Version, PrfAlgo, MasterSecret, Handshake) %% TODO 1.3 finished --spec certificate_verify(md5sha | sha, integer(), [binary()]) -> binary(). - +-spec certificate_verify(HashAlgo, Handshake) -> binary() when + HashAlgo :: md5sha | ssl:hash(), + Handshake :: [binary()]. %% TLS 1.0 -1.1 --------------------------------------------------- -certificate_verify(md5sha, _Version, Handshake) -> +certificate_verify(md5sha, Handshake) -> MD5 = crypto:hash(md5, Handshake), SHA = crypto:hash(sha, Handshake), {digest, <<MD5/binary, SHA/binary>>}; %% TLS 1.0 -1.1 --------------------------------------------------- %% TLS 1.2 --------------------------------------------------- -certificate_verify(_HashAlgo, _Version, Handshake) -> +certificate_verify(_HashAlgo, Handshake) -> %% crypto:hash(HashAlgo, Handshake). %% Optimization: Let crypto calculate the hash in sign/verify call Handshake. %% TLS 1.2 --------------------------------------------------- - --spec setup_keys(integer(), integer(), binary(), binary(), binary(), integer(), +-spec setup_keys(ssl_record:ssl_version(), integer(), binary(), binary(), binary(), integer(), integer(), integer()) -> {binary(), binary(), binary(), binary(), binary(), binary()}. %% TLS v1.0 --------------------------------------------------- -setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, - KeyMatLen, IVSize) - when Version == 1 -> +setup_keys(?'TLS-1.0', _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, + KeyMatLen, IVSize) -> %% RFC 2246 - 6.3. Key calculation %% key_block = PRF(SecurityParameters.master_secret, %% "key expansion", @@ -254,9 +257,8 @@ setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize %% TLS v1.0 --------------------------------------------------- %% TLS v1.1 --------------------------------------------------- -setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, - KeyMatLen, IVSize) - when Version == 2 -> +setup_keys(?'TLS-1.1', _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, + KeyMatLen, IVSize) -> %% RFC 4346 - 6.3. Key calculation %% key_block = PRF(SecurityParameters.master_secret, %% "key expansion", @@ -282,9 +284,8 @@ setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize %% TLS v1.1 --------------------------------------------------- %% TLS v1.2 --------------------------------------------------- -setup_keys(Version, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, - KeyMatLen, IVSize) - when Version == 3; Version == 4 -> +setup_keys(?'TLS-1.2', PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, + KeyMatLen, IVSize) -> %% RFC 5246 - 6.3. Key calculation %% key_block = PRF(SecurityParameters.master_secret, %% "key expansion", @@ -508,19 +509,19 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, Mac. %% TLS 1.0 -1.2 --------------------------------------------------- -%% TODO 1.3 same as above? +-spec suites(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. --spec suites(1|2|3|4) -> [ssl_cipher_format:cipher_suite()]. +suites(?'TLS-1.X'=Version) -> + lists:flatmap(fun exclusive_suites/1, suites_to_test(Version)). -suites(Minor) when Minor == 1; Minor == 2 -> - exclusive_suites(1); -suites(3) -> - exclusive_suites(3) ++ suites(2); +suites_to_test(?'TLS-1.0') -> [?'TLS-1.0']; +suites_to_test(?'TLS-1.1') -> [?'TLS-1.0']; +suites_to_test(?'TLS-1.2') -> [?'TLS-1.2', ?'TLS-1.0']; +suites_to_test(?'TLS-1.3') -> [?'TLS-1.3', ?'TLS-1.2', ?'TLS-1.0']. -suites(4) -> - exclusive_suites(4) ++ suites(3). +-spec exclusive_suites(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. -exclusive_suites(4) -> +exclusive_suites(?'TLS-1.3') -> [?TLS_AES_256_GCM_SHA384, ?TLS_AES_128_GCM_SHA256, @@ -529,7 +530,7 @@ exclusive_suites(4) -> ?TLS_AES_128_CCM_SHA256, ?TLS_AES_128_CCM_8_SHA256 ]; -exclusive_suites(3) -> +exclusive_suites(?'TLS-1.2') -> [?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, ?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, @@ -568,12 +569,12 @@ exclusive_suites(3) -> ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, - + ?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, ?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, - + ?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - + ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 @@ -583,13 +584,13 @@ exclusive_suites(3) -> %% ?TLS_DH_RSA_WITH_AES_128_GCM_SHA256, %% ?TLS_DH_DSS_WITH_AES_128_GCM_SHA256 ]; -exclusive_suites(2) -> +exclusive_suites(?'TLS-1.1') -> []; -exclusive_suites(1) -> +exclusive_suites(?'TLS-1.0') -> [ ?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, ?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - + ?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, @@ -604,17 +605,18 @@ exclusive_suites(1) -> ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA ]. - + %%-------------------------------------------------------------------- --spec exclusive_anonymous_suites(Minor:: integer()) -> [ssl_cipher_format:cipher_suite()]. +-spec exclusive_anonymous_suites(ssl_record:ssl_version()) -> + [ssl_cipher_format:cipher_suite()]. %% %% Description: Returns a list of the anonymous cipher suites introduced %% in Version, only supported if explicitly set by user. %%-------------------------------------------------------------------- -exclusive_anonymous_suites(4) -> +exclusive_anonymous_suites(?'TLS-1.3') -> []; -exclusive_anonymous_suites(3 = N) -> - psk_anon_exclusive(N) ++ +exclusive_anonymous_suites(?'TLS-1.2') -> + psk_anon_exclusive(?'TLS-1.2') ++ [?TLS_DH_anon_WITH_AES_128_GCM_SHA256, ?TLS_DH_anon_WITH_AES_256_GCM_SHA384, ?TLS_DH_anon_WITH_AES_128_CBC_SHA256, @@ -625,35 +627,34 @@ exclusive_anonymous_suites(3 = N) -> ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, ?TLS_DH_anon_WITH_RC4_128_MD5]; -exclusive_anonymous_suites(2 = N) -> - psk_anon_exclusive(N) ++ +exclusive_anonymous_suites(?'TLS-1.1') -> + psk_anon_exclusive(?'TLS-1.1') ++ [?TLS_ECDH_anon_WITH_AES_128_CBC_SHA, ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA, ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, - + ?TLS_DH_anon_WITH_DES_CBC_SHA, ?TLS_DH_anon_WITH_RC4_128_MD5]; -exclusive_anonymous_suites(N = 1) -> - psk_anon_exclusive(N) ++ +exclusive_anonymous_suites(?'TLS-1.0') -> + psk_anon_exclusive(?'TLS-1.0') ++ [?TLS_DH_anon_WITH_RC4_128_MD5, ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, ?TLS_DH_anon_WITH_DES_CBC_SHA - ] ++ srp_suites_anon({3,1}). + ] ++ srp_suites_anon(?'TLS-1.0'). %%-------------------------------------------------------------------- --spec psk_suites(ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()]. +-spec psk_suites(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. %% %% Description: Returns a list of the PSK cipher suites, only supported %% if explicitly set by user. %%-------------------------------------------------------------------- -psk_suites({3, 3}) -> - psk_exclusive(3); -psk_suites({3, N}) -> - psk_exclusive(N). - -psk_exclusive(3) -> - psk_exclusive(1) -- [?TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA]; -psk_exclusive(1) -> +psk_suites(?'TLS-1.X'=Version) -> + psk_exclusive(Version). + +-spec psk_exclusive(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. +psk_exclusive(?'TLS-1.2') -> + psk_exclusive(?'TLS-1.0') -- [?TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA]; +psk_exclusive(?'TLS-1.0') -> [ ?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, @@ -667,15 +668,17 @@ psk_exclusive(_) -> []. %%-------------------------------------------------------------------- --spec psk_suites_anon(ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()]. +-spec psk_suites_anon(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. %% %% Description: Returns a list of the anonymous PSK cipher suites, only supported %% if explicitly set by user. %%-------------------------------------------------------------------- -psk_suites_anon({3, _}) -> - psk_anon_exclusive(3) ++ psk_anon_exclusive(1). +psk_suites_anon(?'TLS-1.X') -> + psk_anon_exclusive(?'TLS-1.2') ++ psk_anon_exclusive(?'TLS-1.0'). + +-spec psk_anon_exclusive(ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. -psk_anon_exclusive(3) -> +psk_anon_exclusive(?'TLS-1.2') -> [ ?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, ?TLS_PSK_WITH_AES_256_GCM_SHA384, @@ -695,7 +698,7 @@ psk_anon_exclusive(3) -> ?TLS_PSK_WITH_AES_128_CCM, ?TLS_PSK_WITH_AES_128_CCM_8 ]; -psk_anon_exclusive(1) -> +psk_anon_exclusive(?'TLS-1.0') -> [ ?TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, ?TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, @@ -723,15 +726,19 @@ psk_anon_exclusive(_) -> %% Description: Returns a list of the SRP cipher suites, only supported %% if explicitly set by user. %%-------------------------------------------------------------------- -srp_suites({3, 3}) -> - srp_exclusive(1) -- [?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, - ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA - ]; -srp_suites({3, N}) when N == 1; - N == 2 -> - srp_exclusive(1). - -srp_exclusive(1) -> +srp_suites(?'TLS-1.2') -> + srp_exclusive(?'TLS-1.0') -- [?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA + ]; +srp_suites(?'TLS-1.1') -> + srp_exclusive(?'TLS-1.0'); +srp_suites(?'TLS-1.0') -> + srp_exclusive(?'TLS-1.0'). + + +-spec srp_exclusive(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()]. + +srp_exclusive(?'TLS-1.0') -> [?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, @@ -748,30 +755,36 @@ srp_exclusive(_) -> %% Description: Returns a list of the SRP anonymous cipher suites, only supported %% if explicitly set by user. %%-------------------------------------------------------------------- -srp_suites_anon({3, 3}) -> - srp_exclusive_anon(1) -- [?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA]; -srp_suites_anon({3, N}) when N == 1; - N == 2 -> - srp_exclusive_anon(1). -srp_exclusive_anon(1) -> +srp_suites_anon(?'TLS-1.2') -> + srp_exclusive_anon(?'TLS-1.0') -- [?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA]; +srp_suites_anon(?'TLS-1.1') -> + srp_exclusive_anon(?'TLS-1.0'); +srp_suites_anon(?'TLS-1.0') -> + srp_exclusive_anon(?'TLS-1.0'). + + +srp_exclusive_anon(?'TLS-1.0') -> [?TLS_SRP_SHA_WITH_AES_128_CBC_SHA, ?TLS_SRP_SHA_WITH_AES_256_CBC_SHA, ?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA ]. %%-------------------------------------------------------------------- --spec rc4_suites(Version::ssl_record:ssl_version() | integer()) -> - [ssl_cipher_format:cipher_suite()]. +-spec rc4_suites(Version::ssl_record:ssl_version()) -> + [ssl_cipher_format:cipher_suite()]. %% %% Description: Returns a list of the RSA|(ECDH/RSA)| (ECDH/ECDSA) %% with RC4 cipher suites, only supported if explicitly set by user. %% Are not considered secure any more. Other RC4 suites already %% belonged to the user configured only category. %%-------------------------------------------------------------------- -rc4_suites({3, _}) -> - rc4_exclusive(1). +rc4_suites(?'TLS-1.X') -> + rc4_exclusive(?'TLS-1.0'). + +-spec rc4_exclusive(Version::ssl_record:ssl_version()) -> + [ssl_cipher_format:cipher_suite()]. -rc4_exclusive(1) -> +rc4_exclusive(?'TLS-1.0') -> [?TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ?TLS_ECDHE_RSA_WITH_RC4_128_SHA, ?TLS_ECDH_ECDSA_WITH_RC4_128_SHA, @@ -788,10 +801,10 @@ rc4_exclusive(_) -> %% with DES cipher, only supported if explicitly set by user. %% Are not considered secure any more. %%-------------------------------------------------------------------- -des_suites({3, _}) -> - des_exclusive(1). +des_suites(?'TLS-1.X') -> + des_exclusive(?'TLS-1.0'). -des_exclusive(1)-> +des_exclusive(?'TLS-1.0')-> [?TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, ?TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, @@ -803,27 +816,28 @@ des_exclusive(1)-> des_exclusive(_) -> []. %%-------------------------------------------------------------------- --spec rsa_suites(Version::ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()]. +-spec rsa_suites(Version::ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. %% %% Description: Returns a list of the RSA key exchange %% cipher suites, only supported if explicitly set by user. %% Are not considered secure any more. %%-------------------------------------------------------------------- -rsa_suites({3, 3}) -> - rsa_exclusive(3) ++ rsa_exclusive(1); -rsa_suites({3, 2}) -> - rsa_exclusive(1); -rsa_suites({3, 1}) -> - rsa_exclusive(1). - -rsa_exclusive(3) -> +rsa_suites(?'TLS-1.X'=Version) -> + lists:flatmap(fun rsa_exclusive/1, rsa_suites_to_test(Version)). + +rsa_suites_to_test(?'TLS-1.2') -> [?'TLS-1.2', ?'TLS-1.0']; +rsa_suites_to_test(?'TLS-1.1') -> [?'TLS-1.0']; +rsa_suites_to_test(?'TLS-1.0') -> [?'TLS-1.0']. + +-spec rsa_exclusive(Version::ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()]. +rsa_exclusive(?'TLS-1.2') -> [ ?TLS_RSA_WITH_AES_256_GCM_SHA384, ?TLS_RSA_WITH_AES_256_CBC_SHA256, ?TLS_RSA_WITH_AES_128_GCM_SHA256, ?TLS_RSA_WITH_AES_128_CBC_SHA256 ]; -rsa_exclusive(1) -> +rsa_exclusive(?'TLS-1.0') -> [?TLS_RSA_WITH_AES_256_CBC_SHA, ?TLS_RSA_WITH_AES_128_CBC_SHA, ?TLS_RSA_WITH_3DES_EDE_CBC_SHA @@ -831,15 +845,15 @@ rsa_exclusive(1) -> rsa_exclusive(_) -> []. -signature_algs({3, 4}, HashSigns) -> - signature_algs({3, 3}, HashSigns); -signature_algs({3, 3}, HashSigns) -> +signature_algs(?'TLS-1.3', HashSigns) -> + signature_algs(?'TLS-1.2', HashSigns); +signature_algs(?'TLS-1.2', HashSigns) -> CryptoSupports = crypto:supports(), Hashes = proplists:get_value(hashs, CryptoSupports), PubKeys = proplists:get_value(public_keys, CryptoSupports), Schemes = rsa_schemes(), Supported = lists:foldl(fun({Hash, dsa = Sign} = Alg, Acc) -> - case proplists:get_bool(dss, PubKeys) + case proplists:get_bool(dss, PubKeys) andalso proplists:get_bool(Hash, Hashes) andalso is_pair(Hash, Sign, Hashes) of @@ -848,9 +862,9 @@ signature_algs({3, 3}, HashSigns) -> false -> Acc end; - ({Hash, Sign} = Alg, Acc) -> - case proplists:get_bool(Sign, PubKeys) - andalso proplists:get_bool(Hash, Hashes) + ({Hash, Sign} = Alg, Acc) -> + case proplists:get_bool(Sign, PubKeys) + andalso proplists:get_bool(Hash, Hashes) andalso is_pair(Hash, Sign, Hashes) of true -> @@ -861,7 +875,7 @@ signature_algs({3, 3}, HashSigns) -> (Alg, Acc) when is_atom(Alg) -> case lists:member(Alg, Schemes) of true -> - [NewAlg] = signature_schemes({3,4}, [Alg]), + [NewAlg] = signature_schemes(?'TLS-1.3', [Alg]), [NewAlg| Acc]; false -> Acc @@ -869,11 +883,11 @@ signature_algs({3, 3}, HashSigns) -> end, [], HashSigns), lists:reverse(Supported). -default_signature_algs([{3, 4} = Version]) -> - default_signature_schemes(Version) ++ legacy_signature_schemes(Version); -default_signature_algs([{3, 4}, {3,3} | _]) -> - default_signature_schemes({3,4}) ++ default_pre_1_3_signature_algs_only(); -default_signature_algs([{3, 3} = Version |_]) -> +default_signature_algs([?'TLS-1.3']) -> + default_signature_schemes(?'TLS-1.3') ++ legacy_signature_schemes(?'TLS-1.3'); +default_signature_algs([?'TLS-1.3', ?'TLS-1.2' | _]) -> + default_signature_schemes(?'TLS-1.3') ++ default_pre_1_3_signature_algs_only(); +default_signature_algs([?'TLS-1.2' = Version |_]) -> Default = [%% SHA2 ++ PSS {sha512, ecdsa}, rsa_pss_pss_sha512, @@ -905,10 +919,10 @@ default_pre_1_3_signature_algs_only() -> {sha224, ecdsa}, {sha224, rsa} ], - signature_algs({3,3}, Default). + signature_algs(?'TLS-1.2', Default). signature_schemes(Version, [_|_] =SignatureSchemes) when is_tuple(Version) - andalso Version >= {3, 3} -> + andalso Version >= ?'TLS-1.2' -> CryptoSupports = crypto:supports(), Hashes = proplists:get_value(hashs, CryptoSupports), PubKeys = proplists:get_value(public_keys, CryptoSupports), @@ -991,7 +1005,7 @@ legacy_signature_schemes(Version) -> %% MAY appear in "signature_algorithms" and %% "signature_algorithms_cert" for backward compatibility with %% TLS 1.2. - LegacySchemes = + LegacySchemes = [rsa_pkcs1_sha512, rsa_pkcs1_sha384, rsa_pkcs1_sha256], @@ -1031,7 +1045,7 @@ hmac_hash(?NULL, _, _) -> hmac_hash(Alg, Key, Value) -> crypto:mac(hmac, mac_algo(Alg), Key, Value). -mac_algo(Alg) when is_atom(Alg) -> +mac_algo(Alg) when is_atom(Alg) -> Alg; mac_algo(?MD5) -> md5; mac_algo(?SHA) -> sha; @@ -1121,19 +1135,23 @@ is_pair(Hash, rsa, Hashs) -> is_pair(_,_,_) -> false. +%% Should we create a new function for ecc_curves(Version) +%% and another explicit one for ecc_curve_named([TLSCurves])? %% list ECC curves in preferred order --spec ecc_curves(1..3 | all) -> [named_curve()]. +-spec ecc_curves(TLS | DTLS | all) -> [named_curve()] when + TLS :: ?'TLS-1.0' | ?'TLS-1.1' | ?'TLS-1.2', + DTLS :: ?'DTLS-1.X'; + ([named_curve()]) -> [named_curve()]. ecc_curves(all) -> [sect571r1,sect571k1,secp521r1,brainpoolP512r1, sect409k1,sect409r1,brainpoolP384r1,secp384r1, sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1]; -ecc_curves(Minor) -> +ecc_curves(Version) when is_tuple(Version) -> TLSCurves = ecc_curves(all), - ecc_curves(Minor, TLSCurves). + ecc_curves(TLSCurves); --spec ecc_curves(1..3, [named_curve()]) -> [named_curve()]. -ecc_curves(_Minor, TLSCurves) -> +ecc_curves(TLSCurves) when is_list(TLSCurves) -> CryptoCurves = crypto:ec_curves(), lists:foldr(fun(Curve, Curves) -> case proplists:get_bool(Curve, CryptoCurves) of @@ -1142,7 +1160,11 @@ ecc_curves(_Minor, TLSCurves) -> end end, [], TLSCurves). --spec groups(4 | all | default) -> [group()]. +groups() -> + TLSGroups = groups(all), + groups(TLSGroups). + +-spec groups(all | default | TLSGroups :: list()) -> [group()]. groups(all) -> [x25519, x448, @@ -1159,18 +1181,13 @@ groups(default) -> x448, secp256r1, secp384r1]; -groups(Minor) -> - TLSGroups = groups(all), - groups(Minor, TLSGroups). -%% --spec groups(4, [group()]) -> [group()]. -groups(_Minor, TLSGroups) -> +groups(TLSGroups) when is_list(TLSGroups) -> CryptoGroups = supported_groups(), lists:filter(fun(Group) -> proplists:get_bool(Group, CryptoGroups) end, TLSGroups). -default_groups(Minor) -> +default_groups() -> TLSGroups = groups(default), - groups(Minor, TLSGroups). + groups(TLSGroups). supported_groups() -> %% TODO: Add new function to crypto? diff --git a/lib/ssl/test/property_test/ssl_eqc_handshake.erl b/lib/ssl/test/property_test/ssl_eqc_handshake.erl index 6fccaf6440..a3d6375de2 100644 --- a/lib/ssl/test/property_test/ssl_eqc_handshake.erl +++ b/lib/ssl/test/property_test/ssl_eqc_handshake.erl @@ -57,11 +57,8 @@ -include_lib("ssl/src/ssl_handshake.hrl"). -include_lib("ssl/src/ssl_alert.hrl"). -include_lib("ssl/src/ssl_internal.hrl"). +-include_lib("ssl/src/ssl_record.hrl"). --define('TLS_v1.3', {3,4}). --define('TLS_v1.2', {3,3}). --define('TLS_v1.1', {3,2}). --define('TLS_v1', {3,1}). %%-------------------------------------------------------------------- %% Properties -------------------------------------------------------- @@ -87,7 +84,7 @@ prop_tls_hs_encode_decode() -> %% Message Generators ----------------------------------------------- %%-------------------------------------------------------------------- -tls_msg(?'TLS_v1.3'= Version) -> +tls_msg(?'TLS-1.3'= Version) -> oneof([client_hello(Version), server_hello(Version), %%new_session_ticket() @@ -116,9 +113,9 @@ tls_msg(Version) -> %% %% Shared messages %% -client_hello(?'TLS_v1.3' = Version) -> +client_hello(?'TLS-1.3' = Version) -> #client_hello{session_id = session_id(), - client_version = ?'TLS_v1.2', + client_version = ?'TLS-1.2', cipher_suites = cipher_suites(Version), compression_methods = compressions(Version), random = client_random(Version), @@ -133,8 +130,8 @@ client_hello(Version) -> extensions = client_hello_extensions(Version) }. -server_hello(?'TLS_v1.3' = Version) -> - #server_hello{server_version = ?'TLS_v1.2', +server_hello(?'TLS-1.3' = Version) -> + #server_hello{server_version = ?'TLS-1.2', session_id = session_id(), random = server_random(Version), cipher_suite = cipher_suite(Version), @@ -184,7 +181,7 @@ finished() -> %% encrypted_extensions() -> - ?LET(Exts, extensions(?'TLS_v1.3', encrypted_extensions), + ?LET(Exts, extensions(?'TLS-1.3', encrypted_extensions), #encrypted_extensions{extensions = Exts}). @@ -197,7 +194,7 @@ key_update() -> %%-------------------------------------------------------------------- tls_version() -> - oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1']). + oneof([?'TLS-1.3', ?'TLS-1.2', ?'TLS-1.1', ?'TLS-1.0']). cipher_suite(Version) -> oneof(cipher_suites(Version)). @@ -290,7 +287,7 @@ pre_shared_keyextension() -> %% | | | %% | signature_algorithms_cert (RFC 8446) | CH, CR | %% +--------------------------------------------------+-------------+ -extensions(?'TLS_v1.3' = Version, MsgType = client_hello) -> +extensions(?'TLS-1.3' = Version, MsgType = client_hello) -> ?LET({ ServerName, %% MaxFragmentLength, @@ -398,7 +395,7 @@ extensions(Version, client_hello) -> srp => SRP %% renegotiation_info => RenegotiationInfo })); -extensions(?'TLS_v1.3' = Version, MsgType = server_hello) -> +extensions(?'TLS-1.3' = Version, MsgType = server_hello) -> ?LET({ KeyShare, PreSharedKey, @@ -443,7 +440,7 @@ extensions(Version, server_hello) -> next_protocol_negotiation => NextP %% renegotiation_info => RenegotiationInfo })); -extensions(?'TLS_v1.3' = Version, encrypted_extensions) -> +extensions(?'TLS-1.3' = Version, encrypted_extensions) -> ?LET({ ServerName, %% MaxFragmentLength, @@ -551,7 +548,7 @@ signature() -> 76,105,212,176,25,6,148,49,194,106,253,241,212,200, 37,154,227,53,49,216,72,82,163>>. -client_hello_versions(?'TLS_v1.3') -> +client_hello_versions(?'TLS-1.3') -> ?LET(SupportedVersions, oneof([[{3,4}], %% This list breaks the property but can be used for negative tests @@ -626,11 +623,11 @@ cert_conf()-> peer => [{key, ssl_test_lib:hardcode_rsa_key(6)}]}}). cert_auths() -> - certificate_authorities(?'TLS_v1.3'). + certificate_authorities(?'TLS-1.3'). certificate_request_1_3() -> #certificate_request_1_3{certificate_request_context = <<>>, - extensions = #{certificate_authorities => certificate_authorities(?'TLS_v1.3')} + extensions = #{certificate_authorities => certificate_authorities(?'TLS-1.3')} }. certificate_request(Version) -> #certificate_request{certificate_types = certificate_types(Version), @@ -666,9 +663,9 @@ hash_alg(Version) -> {hash_algorithm(Version, Alg), Alg} ). -hash_algorithm(?'TLS_v1.3', _) -> +hash_algorithm(?'TLS-1.3', _) -> oneof([sha, sha224, sha256, sha384, sha512]); -hash_algorithm(?'TLS_v1.2', rsa) -> +hash_algorithm(?'TLS-1.2', rsa) -> oneof([sha, sha224, sha256, sha384, sha512]); hash_algorithm(_, rsa) -> oneof([md5, sha, sha224, sha256, sha384, sha512]); @@ -677,19 +674,19 @@ hash_algorithm(_, ecdsa) -> hash_algorithm(_, dsa) -> sha. -sign_algorithm(?'TLS_v1.3') -> +sign_algorithm(?'TLS-1.3') -> oneof([rsa, ecdsa]); sign_algorithm(_) -> oneof([rsa, dsa, ecdsa]). - use_srtp() -> FullProfiles = [<<0,1>>, <<0,2>>, <<0,5>>], NullProfiles = [<<0,5>>], ?LET(PP, oneof([FullProfiles, NullProfiles]), #use_srtp{protection_profiles = PP, mki = <<>>}). -certificate_authorities(?'TLS_v1.3') -> - Auths = certificate_authorities(?'TLS_v1.2'), +certificate_authorities(?'TLS-1.3') -> + Auths = certificate_authorities(?'TLS-1.2'), + #certificate_authorities{authorities = Auths}; certificate_authorities(_) -> #{server_config := ServerConf} = cert_conf(), @@ -718,13 +715,13 @@ ec_point_formats() -> ec_point_format_list() -> [?ECPOINT_UNCOMPRESSED]. -elliptic_curves({_, Minor}) when Minor < 4 -> - Curves = tls_v1:ecc_curves(Minor), +elliptic_curves(Version) when Version < ?'TLS-1.3' -> + Curves = tls_v1:ecc_curves(Version), #elliptic_curves{elliptic_curve_list = Curves}. %% RFC 8446 (TLS 1.3) renamed the "elliptic_curve" extension. -supported_groups({_, Minor}) when Minor >= 4 -> - SupportedGroups = tls_v1:groups(Minor), +supported_groups(?'TLS-1.X'=Version) when Version >= ?'TLS-1.3' -> + SupportedGroups = tls_v1:groups(), #supported_groups{supported_groups = SupportedGroups}. diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl index 7d4633095d..ed11926469 100644 --- a/lib/ssl/test/ssl_ECC_SUITE.erl +++ b/lib/ssl/test/ssl_ECC_SUITE.erl @@ -24,6 +24,7 @@ -behaviour(ct_suite). +-include_lib("ssl/src/ssl_record.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("public_key/include/public_key.hrl"). @@ -180,7 +181,7 @@ client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) -> ecc_default_order(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_ecdsa, @@ -195,7 +196,7 @@ ecc_default_order(Config) -> ecc_default_order_custom_curves(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_ecdsa, @@ -210,7 +211,7 @@ ecc_default_order_custom_curves(Config) -> ecc_client_order(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_ecdsa, @@ -225,7 +226,7 @@ ecc_client_order(Config) -> ecc_client_order_custom_curves(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_ecdsa, @@ -252,7 +253,7 @@ ecc_unknown_curve(Config) -> client_ecdh_rsa_server_ecdhe_ecdsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdh_rsa, ecdhe_ecdsa, Config), @@ -266,7 +267,7 @@ client_ecdh_rsa_server_ecdhe_ecdsa_server_custom(Config) -> client_ecdh_rsa_server_ecdhe_rsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdh_rsa, ecdhe_rsa, Config), @@ -281,7 +282,7 @@ client_ecdh_rsa_server_ecdhe_rsa_server_custom(Config) -> client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_rsa, ecdhe_ecdsa, Config), @@ -295,7 +296,7 @@ client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom(Config) -> client_ecdhe_rsa_server_ecdhe_rsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_rsa, ecdhe_rsa, Config), @@ -309,7 +310,7 @@ client_ecdhe_rsa_server_ecdhe_rsa_server_custom(Config) -> end. client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, [[], [], [{extensions, Ext}]]}, {client_chain, Default}], @@ -327,7 +328,7 @@ client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) -> client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_ecdsa, Config), @@ -341,7 +342,7 @@ client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) -> client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_rsa, Config), @@ -355,7 +356,7 @@ client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) -> client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_ecdsa, ecdhe_ecdsa, Config), @@ -369,7 +370,7 @@ client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) -> client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom(Config) -> Default = ssl_test_lib:default_cert_chain_conf(), - DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), + DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(?'TLS-1.0'))), {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, {client_chain, Default}], ecdhe_rsa, ecdhe_ecdsa, Config), diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl index 664f59a47d..c922339541 100644 --- a/lib/ssl/test/ssl_api_SUITE.erl +++ b/lib/ssl/test/ssl_api_SUITE.erl @@ -27,6 +27,7 @@ -include_lib("ssl/src/ssl_api.hrl"). -include_lib("ssl/src/ssl_internal.hrl"). -include_lib("public_key/include/public_key.hrl"). +-include("ssl_record.hrl"). %% Common test -export([all/0, @@ -3856,13 +3857,10 @@ active_n_common(S, N) -> ok({ok,V}) -> V. repeat(N, Fun) -> - repeat(N, N, Fun). + Repeat = fun F(Arg) when is_integer(Arg), Arg > 0 -> Fun(N - Arg), F(Arg - 1); + F(_) -> ok end, + Repeat(N). -repeat(N, T, Fun) when is_integer(N), N > 0 -> - Fun(T-N), - repeat(N-1, T, Fun); -repeat(_, _, _) -> - ok. get_close(Pid, Where) -> receive @@ -4022,55 +4020,63 @@ log(#{msg:={report,_Report}},#{config:=Pid}) -> log(_,_) -> ok. -length_exclusive({3,_} = Version) -> +length_exclusive(?'TLS-1.X' = Version) -> length(exclusive_default_up_to_version(Version, [])) + length(exclusive_non_default_up_to_version(Version, [])); -length_exclusive({254,_} = Version) -> +length_exclusive(?'DTLS-1.X' = Version) -> length(dtls_exclusive_default_up_to_version(Version, [])) + length(dtls_exclusive_non_default_up_to_version(Version, [])). length_all(Version) -> length(ssl:cipher_suites(all, Version)). -exclusive_default_up_to_version({3, 1} = Version, Acc) -> - ssl:cipher_suites(exclusive, Version) ++ Acc; -exclusive_default_up_to_version({3, Minor} = Version, Acc) when Minor =< 4 -> - Suites = ssl:cipher_suites(exclusive, Version), - exclusive_default_up_to_version({3, Minor-1}, Suites ++ Acc). - -dtls_exclusive_default_up_to_version({254, 255} = Version, Acc) -> - ssl:cipher_suites(exclusive, Version) ++ Acc; -dtls_exclusive_default_up_to_version({254, 253} = Version, Acc) -> - Suites = ssl:cipher_suites(exclusive, Version), - dtls_exclusive_default_up_to_version({254, 255}, Suites ++ Acc). - -exclusive_non_default_up_to_version({3, 1} = Version, Acc) -> - exclusive_non_default_version(Version) ++ Acc; -exclusive_non_default_up_to_version({3, 4}, Acc) -> - exclusive_non_default_up_to_version({3, 3}, Acc); -exclusive_non_default_up_to_version({3, Minor} = Version, Acc) when Minor =< 3 -> - Suites = exclusive_non_default_version(Version), - exclusive_non_default_up_to_version({3, Minor-1}, Suites ++ Acc). - -dtls_exclusive_non_default_up_to_version({254, 255} = Version, Acc) -> - dtls_exclusive_non_default_version(Version) ++ Acc; -dtls_exclusive_non_default_up_to_version({254, 253} = Version, Acc) -> - Suites = dtls_exclusive_non_default_version(Version), - dtls_exclusive_non_default_up_to_version({254, 255}, Suites ++ Acc). - -exclusive_non_default_version({_, Minor}) -> - tls_v1:psk_exclusive(Minor) ++ - tls_v1:srp_exclusive(Minor) ++ - tls_v1:rsa_exclusive(Minor) ++ - tls_v1:des_exclusive(Minor) ++ - tls_v1:rc4_exclusive(Minor). +exclusive_default_up_to_version(?'TLS-1.0', Acc) -> + lists:flatmap(fun (Vsn) -> ssl:cipher_suites(exclusive, Vsn) end + , [?'TLS-1.0' | Acc]); +exclusive_default_up_to_version(?'TLS-1.1', Acc) -> + exclusive_default_up_to_version(?'TLS-1.0', [?'TLS-1.1' | Acc]); +exclusive_default_up_to_version(?'TLS-1.2', Acc) -> + exclusive_default_up_to_version(?'TLS-1.1', [?'TLS-1.2' | Acc]); +exclusive_default_up_to_version(?'TLS-1.3', Acc) -> + exclusive_default_up_to_version(?'TLS-1.2', [?'TLS-1.3' | Acc]). + +dtls_exclusive_default_up_to_version(?'DTLS-1.0', Acc) -> + lists:flatmap( fun (Vsn) -> ssl:cipher_suites(exclusive, Vsn) end + , [?'DTLS-1.0' | Acc]); +dtls_exclusive_default_up_to_version(?'DTLS-1.2', Acc) -> + dtls_exclusive_default_up_to_version(?'DTLS-1.0', [?'DTLS-1.2' | Acc]). + +%% TODO: wip +exclusive_non_default_up_to_version(?'TLS-1.0', Acc) -> + lists:flatmap(fun exclusive_non_default_version/1, [?'TLS-1.0' | Acc]); +exclusive_non_default_up_to_version(?'TLS-1.1', Acc) -> + exclusive_non_default_up_to_version(?'TLS-1.0', [?'TLS-1.1' | Acc]); +exclusive_non_default_up_to_version(?'TLS-1.2', Acc) -> + exclusive_non_default_up_to_version(?'TLS-1.1', [?'TLS-1.2' | Acc]); +exclusive_non_default_up_to_version(?'TLS-1.3', Acc) -> + exclusive_non_default_up_to_version(?'TLS-1.2', Acc). + + +dtls_exclusive_non_default_up_to_version(?'DTLS-1.0', Acc) -> + lists:flatmap(fun dtls_exclusive_non_default_version/1, [?'DTLS-1.0' | Acc]); +dtls_exclusive_non_default_up_to_version(?'DTLS-1.2', Acc) -> + dtls_exclusive_non_default_up_to_version(?'DTLS-1.0', [?'DTLS-1.2' | Acc]). + +exclusive_non_default_version(Version) -> + Ls = [ fun tls_v1:psk_exclusive/1 + , fun tls_v1:srp_exclusive/1 + , fun tls_v1:rsa_exclusive/1 + , fun tls_v1:des_exclusive/1 + , fun tls_v1:rc4_exclusive/1], + lists:flatmap(fun(Fn) -> Fn(Version) end, Ls). dtls_exclusive_non_default_version(DTLSVersion) -> - {_,Minor} = ssl:tls_version(DTLSVersion), - tls_v1:psk_exclusive(Minor) ++ - tls_v1:srp_exclusive(Minor) ++ - tls_v1:rsa_exclusive(Minor) ++ - tls_v1:des_exclusive(Minor). + Version = ssl:tls_version(DTLSVersion), + Fns = [ fun tls_v1:psk_exclusive/1 + , fun tls_v1:srp_exclusive/1 + , fun tls_v1:rsa_exclusive/1 + , fun tls_v1:des_exclusive/1], + lists:flatmap(fun (Fn) -> Fn(Version) end, Fns). selected_peer(ExpectedClient, ExpectedServer, ClientOpts, ServerOpts, Config) -> diff --git a/lib/ssl/test/ssl_cert_SUITE.erl b/lib/ssl/test/ssl_cert_SUITE.erl index d445072d7b..5b42624af6 100644 --- a/lib/ssl/test/ssl_cert_SUITE.erl +++ b/lib/ssl/test/ssl_cert_SUITE.erl @@ -25,6 +25,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("public_key/include/public_key.hrl"). +-include("ssl_record.hrl"). %% Common test -export([all/0, @@ -1377,7 +1378,7 @@ rsa_alg(rsa_pss_pss_1_3) -> rsa_alg(Atom) -> Atom. -no_reuse({3, N}) when N >= 4 -> +no_reuse(?'TLS-1.3') -> []; no_reuse(_) -> [{reuse_sessions, false}]. diff --git a/lib/ssl/test/ssl_cert_tests.erl b/lib/ssl/test/ssl_cert_tests.erl index be3f651a13..8df08398da 100644 --- a/lib/ssl/test/ssl_cert_tests.erl +++ b/lib/ssl/test/ssl_cert_tests.erl @@ -467,8 +467,8 @@ test_ciphers(_, 'tlsv1.3' = Version) -> end, Ciphers); test_ciphers(_, Version) when Version == 'dtlsv1'; Version == 'dtlsv1.2' -> - {_, Minor} = dtls_record:protocol_version(Version), - Ciphers = [ssl_cipher_format:suite_bin_to_map(Bin) || Bin <- dtls_v1:suites(Minor)], + NVersion = dtls_record:protocol_version(Version), + Ciphers = [ssl_cipher_format:suite_bin_to_map(Bin) || Bin <- dtls_v1:suites(NVersion)], ct:log("Version ~p Testing ~p~n", [Version, Ciphers]), OpenSSLCiphers = openssl_ciphers(), ct:log("OpenSSLCiphers ~p~n", [OpenSSLCiphers]), diff --git a/lib/ssl/test/ssl_cipher_SUITE.erl b/lib/ssl/test/ssl_cipher_SUITE.erl index def13d0860..c2d92e859d 100644 --- a/lib/ssl/test/ssl_cipher_SUITE.erl +++ b/lib/ssl/test/ssl_cipher_SUITE.erl @@ -25,6 +25,7 @@ -include_lib("common_test/include/ct.hrl"). -include("tls_record.hrl"). -include("ssl_cipher.hrl"). +-include("ssl_record.hrl"). %% Callback functions -export([all/0, @@ -96,10 +97,9 @@ aes_decipher_good() -> aes_decipher_good(Config) when is_list(Config) -> HashSz = 32, CipherState = correct_cipher_state(), - decipher_check_good(HashSz, CipherState, {3,0}), - decipher_check_good(HashSz, CipherState, {3,1}), - decipher_check_good(HashSz, CipherState, {3,2}), - decipher_check_good(HashSz, CipherState, {3,3}). + decipher_check_good(HashSz, CipherState, ?'TLS-1.0'), + decipher_check_good(HashSz, CipherState, ?'TLS-1.1'), + decipher_check_good(HashSz, CipherState, ?'TLS-1.2'). %%-------------------------------------------------------------------- aes_decipher_fail() -> @@ -108,19 +108,17 @@ aes_decipher_fail() -> aes_decipher_fail(Config) when is_list(Config) -> HashSz = 32, CipherState = incorrect_cipher_state(), - decipher_check_fail(HashSz, CipherState, {3,0}), - decipher_check_fail(HashSz, CipherState, {3,1}), - decipher_check_fail(HashSz, CipherState, {3,2}), - decipher_check_fail(HashSz, CipherState, {3,3}). + decipher_check_fail(HashSz, CipherState, ?'TLS-1.0'), + decipher_check_fail(HashSz, CipherState, ?'TLS-1.1'), + decipher_check_fail(HashSz, CipherState, ?'TLS-1.2'). %%-------------------------------------------------------------------- padding_test(Config) when is_list(Config) -> HashSz = 16, CipherState = correct_cipher_state(), - pad_test(HashSz, CipherState, {3,0}), - pad_test(HashSz, CipherState, {3,1}), - pad_test(HashSz, CipherState, {3,2}), - pad_test(HashSz, CipherState, {3,3}). + pad_test(HashSz, CipherState, ?'TLS-1.0'), + pad_test(HashSz, CipherState, ?'TLS-1.1'), + pad_test(HashSz, CipherState, ?'TLS-1.2'). %%-------------------------------------------------------------------- % Internal functions -------------------------------------------------------- @@ -135,21 +133,14 @@ decipher_check_fail(HashSz, CipherState, Version) -> true = {Content, Mac, #cipher_state{iv = NextIV}} =/= ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, aes_fragment(Version), Version, true). -pad_test(HashSz, CipherState, {3,0} = Version) -> - %% 3.0 does not have padding test - {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version), - {Content, Mac, #cipher_state{iv = NextIV}} = - ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, true), - {Content, Mac, #cipher_state{iv = NextIV}} = - ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, false); -pad_test(HashSz, CipherState, {3,1} = Version) -> +pad_test(HashSz, CipherState, ?'TLS-1.0' = Version) -> %% 3.1 should have padding test, but may be disabled {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version), BadCont = badpad_content(Content), {Content, Mac, #cipher_state{iv = NextIV}} = - ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,1}) , {3,1}, false), + ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment(?'TLS-1.0') , ?'TLS-1.0', false), {BadCont, Mac, #cipher_state{iv = NextIV}} = - ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,1}), {3,1}, true); + ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment(?'TLS-1.0'), ?'TLS-1.0', true); pad_test(HashSz, CipherState, Version) -> %% 3.2 and 3.3 must have padding test {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version), @@ -159,7 +150,7 @@ pad_test(HashSz, CipherState, Version) -> {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment(Version), Version, true). -aes_fragment({3,N}) when N == 0; N == 1-> +aes_fragment(?'TLS-1.0') -> <<197,9,6,109,242,87,80,154,85,250,110,81,119,95,65,185,53,206,216,153,246,169, 119,177,178,238,248,174,253,220,242,81,33,0,177,251,91,44,247,53,183,198,165, 63,20,194,159,107>>; @@ -170,7 +161,7 @@ aes_fragment(_) -> 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122, 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>. -badpad_aes_fragment({3,N}) when N == 0; N == 1 -> +badpad_aes_fragment(?'TLS-1.0') -> <<186,139,125,10,118,21,26,248,120,108,193,104,87,118,145,79,225,55,228,10,105, 30,190,37,1,88,139,243,210,99,65,41>>; badpad_aes_fragment(_) -> @@ -178,7 +169,7 @@ badpad_aes_fragment(_) -> 94,121,137,117,157,109,99,113,61,190,138,131,229,201,120,142,179,172,48,77, 234,19,240,33,38,91,93>>. -content_nextiv_mac({3,N}) when N == 0; N == 1 -> +content_nextiv_mac(?'TLS-1.0') -> {<<"HELLO\n">>, <<72,196,247,97,62,213,222,109,210,204,217,186,172,184, 197,148>>, <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>}; @@ -187,7 +178,7 @@ content_nextiv_mac(_) -> <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>, <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>}. -badpad_content_nextiv_mac({3,N}) when N == 0; N == 1 -> +badpad_content_nextiv_mac(?'TLS-1.0') -> {<<"HELLO\n">>, <<225,55,228,10,105,30,190,37,1,88,139,243,210,99,65,41>>, <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>> diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl index 074a795556..b50d93b5d1 100644 --- a/lib/ssl/test/ssl_handshake_SUITE.erl +++ b/lib/ssl/test/ssl_handshake_SUITE.erl @@ -126,7 +126,7 @@ decode_hello_handshake(_Config) -> 16#00, 16#00, 16#33, 16#74, 16#00, 16#07, 16#06, 16#73, 16#70, 16#64, 16#79, 16#2f, 16#32>>, - Version = {3, 0}, + Version = ?'SSL-3.0', DefOpts = ssl:update_options([{verify, verify_none}], client, #{}), {Records, _Buffer} = tls_handshake:get_tls_handshakes(Version, HelloPacket, <<>>, DefOpts), @@ -136,7 +136,7 @@ decode_hello_handshake(_Config) -> decode_single_hello_extension_correctly(_Config) -> Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>, - Extensions = ssl_handshake:decode_extensions(Renegotiation, {3,3}, undefined), + Extensions = ssl_handshake:decode_extensions(Renegotiation, ?'TLS-1.2', undefined), #{renegotiation_info := #renegotiation_info{renegotiated_connection = <<0>>}} = Extensions. decode_supported_elliptic_curves_hello_extension_correctly(_Config) -> @@ -148,13 +148,13 @@ decode_supported_elliptic_curves_hello_extension_correctly(_Config) -> Len = ListLen + 2, Extension = <<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len), ?UINT16(ListLen), EllipticCurveList/binary>>, % after decoding we should see only valid curves - Extensions = ssl_handshake:decode_hello_extensions(Extension, {3,2}, {3,2}, client), + Extensions = ssl_handshake:decode_hello_extensions(Extension, ?'TLS-1.1', ?'TLS-1.1', client), #{elliptic_curves := #elliptic_curves{elliptic_curve_list = [?sect233k1, ?sect193r2]}} = Extensions. decode_unknown_hello_extension_correctly(_Config) -> FourByteUnknown = <<16#CA,16#FE, ?UINT16(4), 3, 0, 1, 2>>, Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>, - Extensions = ssl_handshake:decode_hello_extensions(<<FourByteUnknown/binary, Renegotiation/binary>>, {3,2}, {3,2}, client), + Extensions = ssl_handshake:decode_hello_extensions(<<FourByteUnknown/binary, Renegotiation/binary>>, ?'TLS-1.1', ?'TLS-1.1', client), #{renegotiation_info := #renegotiation_info{renegotiated_connection = <<0>>}} = Extensions. @@ -169,21 +169,21 @@ encode_single_hello_sni_extension_correctly(_Config) -> decode_single_hello_sni_extension_correctly(_Config) -> SNI = <<16#00, 16#00, 16#00, 16#0d, 16#00, 16#0b, 16#00, 16#00, 16#08, $t, $e, $s, $t, $., $c, $o, $m>>, - Decoded = ssl_handshake:decode_hello_extensions(SNI, {3,3}, {3,3}, client), + Decoded = ssl_handshake:decode_hello_extensions(SNI, ?'TLS-1.2', ?'TLS-1.2', client), #{sni := #sni{hostname = "test.com"}} = Decoded. decode_empty_server_sni_correctly(_Config) -> SNI = <<?UINT16(?SNI_EXT),?UINT16(0)>>, - Decoded = ssl_handshake:decode_hello_extensions(SNI, {3,3}, {3,3}, server), + Decoded = ssl_handshake:decode_hello_extensions(SNI, ?'TLS-1.2', ?'TLS-1.2', server), #{sni := #sni{hostname = ""}} = Decoded. select_proper_tls_1_2_rsa_default_hashsign(_Config) -> % RFC 5246 section 7.4.1.4.1 tells to use {sha1,rsa} as default signature_algorithm for RSA key exchanges - {sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, {3,3}), + {sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, ?'TLS-1.2'), % Older versions use MD5/SHA1 combination - {md5sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, {3,2}), - {md5sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, {3,0}). + {md5sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, ?'TLS-1.1'), + {md5sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, ?'SSL-3.0'). ignore_hassign_extension_pre_tls_1_2(Config) -> @@ -191,11 +191,10 @@ ignore_hassign_extension_pre_tls_1_2(Config) -> CertFile = proplists:get_value(certfile, Opts), [{_, Cert, _}] = ssl_test_lib:pem_to_der(CertFile), HashSigns = #hash_sign_algos{hash_sign_algos = [{sha512, rsa}, {sha, dsa}, {sha256, rsa}]}, - {sha512, rsa} = ssl_handshake:select_hashsign({HashSigns, undefined}, Cert, ecdhe_rsa, tls_v1:default_signature_algs([{3,3}]), {3,3}), + {sha512, rsa} = ssl_handshake:select_hashsign({HashSigns, undefined}, Cert, ecdhe_rsa, tls_v1:default_signature_algs([?'TLS-1.2']), ?'TLS-1.2'), %%% Ignore - {md5sha, rsa} = ssl_handshake:select_hashsign({HashSigns, undefined}, Cert, ecdhe_rsa, tls_v1:default_signature_algs([{3,2}]), {3,2}), - {md5sha, rsa} = ssl_handshake:select_hashsign({HashSigns, undefined}, Cert, ecdhe_rsa, tls_v1:default_signature_algs([{3,0}]), {3,0}). - + {md5sha, rsa} = ssl_handshake:select_hashsign({HashSigns, undefined}, Cert, ecdhe_rsa, tls_v1:default_signature_algs([?'TLS-1.1']), ?'TLS-1.1'), + {md5sha, rsa} = ssl_handshake:select_hashsign({HashSigns, undefined}, Cert, ecdhe_rsa, tls_v1:default_signature_algs([?'SSL-3.0']), ?'SSL-3.0'). signature_algorithms(Config) -> Opts = proplists:get_value(server_opts, Config), @@ -212,16 +211,16 @@ signature_algorithms(Config) -> {sha512, rsa} = ssl_handshake:select_hashsign( {HashSigns0, Schemes0}, Cert, ecdhe_rsa, - tls_v1:default_signature_algs([{3,3}]), - {3,3}), + tls_v1:default_signature_algs([?'TLS-1.2']), + ?'TLS-1.2'), HashSigns1 = #hash_sign_algos{ hash_sign_algos = [{sha, dsa}, {sha256, rsa}]}, {sha256, rsa} = ssl_handshake:select_hashsign( {HashSigns1, Schemes0}, Cert, ecdhe_rsa, - tls_v1:default_signature_algs([{3,3}]), - {3,3}), + tls_v1:default_signature_algs([?'TLS-1.2']), + ?'TLS-1.2'), Schemes1 = #signature_algorithms_cert{ signature_scheme_list = [rsa_pkcs1_sha1, ecdsa_sha1]}, @@ -229,22 +228,22 @@ signature_algorithms(Config) -> #alert{} = ssl_handshake:select_hashsign( {HashSigns1, Schemes1}, Cert, ecdhe_rsa, - tls_v1:default_signature_algs([{3,3}]), - {3,3}), + tls_v1:default_signature_algs([?'TLS-1.2']), + ?'TLS-1.2'), %% No scheme, hashsign is used {sha256, rsa} = ssl_handshake:select_hashsign( {HashSigns1, undefined}, Cert, ecdhe_rsa, - tls_v1:default_signature_algs([{3,3}]), - {3,3}), + tls_v1:default_signature_algs([?'TLS-1.2']), + ?'TLS-1.2'), HashSigns2 = #hash_sign_algos{ hash_sign_algos = [{sha, dsa}]}, %% Signature not supported #alert{} = ssl_handshake:select_hashsign( {HashSigns2, Schemes1}, Cert, ecdhe_rsa, - tls_v1:default_signature_algs([{3,3}]), - {3,3}). + tls_v1:default_signature_algs([?'TLS-1.2']), + ?'TLS-1.2'). %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ diff --git a/lib/ssl/test/ssl_mfl_SUITE.erl b/lib/ssl/test/ssl_mfl_SUITE.erl index 362cc3ac31..a9e1a6a8f9 100644 --- a/lib/ssl/test/ssl_mfl_SUITE.erl +++ b/lib/ssl/test/ssl_mfl_SUITE.erl @@ -22,6 +22,7 @@ -behaviour(ct_suite). -include_lib("common_test/include/ct.hrl"). +-include("ssl_record.hrl"). %% Common test -export([all/0, @@ -186,7 +187,7 @@ run_mfl_handshake_continue(Config, MFL) -> receive {Client, {ext, ClientExt}} -> ct:log("Client handshake Ext ~p~n", [ClientExt]), case maps:get(server_hello_selected_version, ClientExt, undefined) of - {3,4} -> + ?'TLS-1.3' -> %% For TLS 1.3 the ssl {handshake, hello} API is inconsistent: %% the server gets all the extensions CH+EE, but the client only CH ignore; diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl index 2a98eb71d0..f1cd8f84b8 100644 --- a/lib/ssl/test/ssl_npn_hello_SUITE.erl +++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl @@ -123,12 +123,12 @@ encode_and_decode_npn_server_hello_test(Config) -> %%-------------------------------------------------------------------- create_server_hello_with_no_advertised_protocols_test(_Config) -> - Hello = ssl_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), #{}), + Hello = ssl_handshake:server_hello(<<>>, ?'SSL-3.0', create_connection_states(), #{}), Extensions = Hello#server_hello.extensions, #{} = Extensions. %%-------------------------------------------------------------------- create_server_hello_with_advertised_protocols_test(_Config) -> - Hello = ssl_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), + Hello = ssl_handshake:server_hello(<<>>, ?'SSL-3.0', create_connection_states(), #{next_protocol_negotiation => [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>]}), Extensions = Hello#server_hello.extensions, #{next_protocol_negotiation := [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>]} = Extensions. diff --git a/lib/ssl/test/ssl_reject_SUITE.erl b/lib/ssl/test/ssl_reject_SUITE.erl index 7221b629ac..a068c4be36 100644 --- a/lib/ssl/test/ssl_reject_SUITE.erl +++ b/lib/ssl/test/ssl_reject_SUITE.erl @@ -22,7 +22,7 @@ -module(ssl_reject_SUITE). -include_lib("common_test/include/ct.hrl"). --include_lib("ssl/src/ssl_record.hrl"). +-include("ssl_record.hrl"). -include_lib("ssl/src/ssl_alert.hrl"). -include_lib("ssl/src/ssl_handshake.hrl"). @@ -48,15 +48,15 @@ accept_sslv3_record_hello/1 ]). --define(TLS_MAJOR, 3). --define(SSL_3_0_MAJOR, 3). --define(SSL_3_0_MINOR, 0). --define(TLS_1_0_MINOR, 1). --define(TLS_1_1_MINOR, 2). --define(TLS_1_2_MINOR, 3). --define(TLS_1_3_MINOR, 4). --define(SSL_2_0_MAJOR, 0). --define(SSL_2_0_MINOR, 1). +-define(TLS_MAJOR, (element(1, ?'TLS-1.2'))). +-define(SSL_3_0_MAJOR, (element(1, ?'SSL-3.0'))). +-define(SSL_3_0_MINOR, (element(2, ?'SSL-3.0'))). +-define(TLS_1_0_MINOR, (element(2, ?'TLS-1.0'))). +-define(TLS_1_1_MINOR, (element(2, ?'TLS-1.1'))). +-define(TLS_1_2_MINOR, (element(2, ?'TLS-1.2'))). +-define(TLS_1_3_MINOR, (element(2, ?'TLS-1.3'))). +-define(SSL_2_0_MAJOR, (element(1, ?'SSL-2.0'))). +-define(SSL_2_0_MINOR, (element(2, ?'SSL-2.0'))). %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- @@ -194,10 +194,11 @@ accept_sslv3_record_hello(Config) when is_list(Config) -> {ok, Socket} = gen_tcp:connect(Hostname, Port, [{active, false}]), gen_tcp:send(Socket, ClientHello), + TLS_Major = ?TLS_MAJOR, case gen_tcp:recv(Socket, 3, 5000) of %% Minor needs to be a TLS version that is a version %% above SSL-3.0 - {ok, [?HANDSHAKE, ?TLS_MAJOR, Minor]} when Minor > ?SSL_3_0_MINOR -> + {ok, [?HANDSHAKE, TLS_Major, Minor]} when Minor > ?SSL_3_0_MINOR -> ok; {error, timeout} -> ct:fail(ssl3_record_not_accepted) diff --git a/lib/ssl/test/ssl_renegotiate_SUITE.erl b/lib/ssl/test/ssl_renegotiate_SUITE.erl index 4b46863415..aa5a32c8aa 100644 --- a/lib/ssl/test/ssl_renegotiate_SUITE.erl +++ b/lib/ssl/test/ssl_renegotiate_SUITE.erl @@ -26,6 +26,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("public_key/include/public_key.hrl"). +-include("ssl_record.hrl"). %% Common test -export([all/0, @@ -87,11 +88,10 @@ all() -> groups() -> [{'dtlsv1.2', [], renegotiate_tests()}, - {'dtlsv1', [], renegotiate_tests()}, - {'tlsv1.3', [], renegotiate_tests()}, - {'tlsv1.2', [], renegotiate_tests()}, - {'tlsv1.1', [], renegotiate_tests()}, - {'tlsv1', [], renegotiate_tests()} + {'dtlsv1', [], renegotiate_tests()}, + {'tlsv1.2', [], renegotiate_tests()}, + {'tlsv1.1', [], renegotiate_tests()}, + {'tlsv1', [], renegotiate_tests()} ]. renegotiate_tests() -> @@ -107,17 +107,6 @@ renegotiate_tests() -> renegotiate_dos_mitigate_passive, renegotiate_dos_mitigate_absolute]. -ssl3_renegotiate_tests() -> - [client_renegotiate, - server_renegotiate, - client_renegotiate_reused_session, - server_renegotiate_reused_session, - client_no_wrap_sequence_number, - server_no_wrap_sequence_number, - renegotiate_dos_mitigate_active, - renegotiate_dos_mitigate_passive, - renegotiate_dos_mitigate_absolute]. - init_per_suite(Config) -> catch crypto:stop(), try crypto:start() of @@ -518,9 +507,7 @@ renegotiate_rejected(Socket) -> ok. %% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast -treashold(N, {3,0}) -> - (N div 2) + 1; -treashold(N, {3,1}) -> +treashold(N, ?'TLS-1.0') -> (N div 2) + 1; treashold(N, _) -> N + 1. diff --git a/lib/ssl/test/ssl_session_SUITE.erl b/lib/ssl/test/ssl_session_SUITE.erl index 40fff3bbbd..f67f998806 100644 --- a/lib/ssl/test/ssl_session_SUITE.erl +++ b/lib/ssl/test/ssl_session_SUITE.erl @@ -660,9 +660,9 @@ faulty_client(Host, Port) -> encode_client_hello(CH, Random) -> - HSBin = tls_handshake:encode_handshake(CH, {3,3}), + HSBin = tls_handshake:encode_handshake(CH, ?'TLS-1.2'), CS = connection_states(Random), - {Encoded, _} = tls_record:encode_handshake(HSBin, {3,3}, CS), + {Encoded, _} = tls_record:encode_handshake(HSBin, ?'TLS-1.2', CS), Encoded. client_hello(Random) -> @@ -738,7 +738,7 @@ client_hello(Random) -> srp => undefined}, - #client_hello{client_version = {3,3}, + #client_hello{client_version = ?'TLS-1.2', random = Random, session_id = crypto:strong_rand_bytes(32), cipher_suites = CipherSuites, diff --git a/lib/ssl/test/tls_1_3_record_SUITE.erl b/lib/ssl/test/tls_1_3_record_SUITE.erl index 75819d0565..951df01810 100644 --- a/lib/ssl/test/tls_1_3_record_SUITE.erl +++ b/lib/ssl/test/tls_1_3_record_SUITE.erl @@ -174,9 +174,9 @@ encode_decode(_Config) -> 146,152,146,151,107,126,216,210,9,93,0,0>>], {[_Header|Encoded], _} = tls_record_1_3:encode_plain_text(22, PlainText, ConnectionStates), - CipherText = #ssl_tls{type = 23, version = {3,3}, fragment = Encoded}, + CipherText = #ssl_tls{type = 23, version = ?'TLS-1.2', fragment = Encoded}, - {#ssl_tls{type = 22, version = {3,4}, fragment = DecodedText}, _} = + {#ssl_tls{type = 22, version = ?'TLS-1.3', fragment = DecodedText}, _} = tls_record_1_3:decode_cipher_text(CipherText, ConnectionStates), DecodedText = iolist_to_binary(PlainText), @@ -260,7 +260,7 @@ encode_decode(_Config) -> 01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"), {CHEncrypted, _} = - tls_record:encode_handshake(ClientHello, {3,4}, ConnStatesNull), + tls_record:encode_handshake(ClientHello, ?'TLS-1.3', ConnStatesNull), ClientHelloRecord = iolist_to_binary(CHEncrypted), %% {server} extract secret "early": @@ -515,7 +515,7 @@ encode_decode(_Config) -> cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"), {SHEncrypted, _} = - tls_record:encode_handshake(ServerHello, {3,4}, ConnStatesNull), + tls_record:encode_handshake(ServerHello, ?'TLS-1.3', ConnStatesNull), ServerHelloRecord = iolist_to_binary(SHEncrypted), %% {server} derive write traffic keys for handshake data: @@ -685,7 +685,7 @@ encode_decode(_Config) -> FinishedHS = #finished{verify_data = FinishedVerifyData}, - FinishedIOList = tls_handshake:encode_handshake(FinishedHS, {3,4}), + FinishedIOList = tls_handshake:encode_handshake(FinishedHS, ?'TLS-1.3'), FinishedHSBin = iolist_to_binary(FinishedIOList), %% {server} derive secret "tls13 c ap traffic": @@ -907,7 +907,7 @@ encode_decode(_Config) -> CFinished = #finished{verify_data = CFinishedVerifyData}, - CFinishedIOList = tls_handshake:encode_handshake(CFinished, {3,4}), + CFinishedIOList = tls_handshake:encode_handshake(CFinished, ?'TLS-1.3'), CFinishedBin = iolist_to_binary(CFinishedIOList), %% {client} derive write traffic keys for application data: @@ -1054,7 +1054,7 @@ encode_decode(_Config) -> ticket_nonce = Nonce, ticket = Ticket, extensions = _Extensions - } = tls_handshake:decode_handshake({3,4}, NWT, TicketBody), + } = tls_handshake:decode_handshake(?'TLS-1.3', NWT, TicketBody), %% ResPRK = resumption master secret ResExpanded = tls_v1:pre_shared_key(ResPRK, Nonce, HKDFAlgo), @@ -1288,7 +1288,7 @@ encode_decode(_Config) -> <<?BYTE(CH), ?UINT24(_Length), ClientHelloBody/binary>> = ClientHelloRecord, #client_hello{extensions = #{pre_shared_key := PreSharedKey}} = - tls_handshake:decode_handshake({3,4}, CH, ClientHelloBody), + tls_handshake:decode_handshake(?'TLS-1.3', CH, ClientHelloBody), #pre_shared_key_client_hello{ offered_psks = #offered_psks{ diff --git a/lib/ssl/test/tls_api_SUITE.erl b/lib/ssl/test/tls_api_SUITE.erl index 69dde6b8b9..655b83d0e8 100644 --- a/lib/ssl/test/tls_api_SUITE.erl +++ b/lib/ssl/test/tls_api_SUITE.erl @@ -790,8 +790,8 @@ tls_reject_warning_alert_in_initial_hs(Config) when is_list(Config) -> ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config), {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config), {Major, Minor} = case ssl_test_lib:protocol_version(Config, tuple) of - {3,4} -> - {3,3}; + ?'TLS-1.3' -> + ?'TLS-1.2'; Other -> Other end, @@ -814,8 +814,8 @@ tls_reject_fake_warning_alert_in_initial_hs(Config) when is_list(Config) -> ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config), {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config), {Major, Minor} = case ssl_test_lib:protocol_version(Config, tuple) of - {3,4} -> - {3,3}; + ?'TLS-1.3' -> + ?'TLS-1.2'; Other -> Other end, @@ -840,8 +840,8 @@ tls_app_data_in_initial_hs_state(Config) when is_list(Config) -> {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config), Version = ssl_test_lib:protocol_version(Config, tuple), {Major, Minor} = case Version of - {3,4} -> - {3,3}; + ?'TLS-1.3' -> + ?'TLS-1.2'; Other -> Other end, @@ -852,7 +852,7 @@ tls_app_data_in_initial_hs_state(Config) when is_list(Config) -> Port = ssl_test_lib:inet_port(Server), {ok, Socket} = gen_tcp:connect("localhost", Port, [{active, false}, binary]), AppData = case Version of - {3, 4} -> + ?'TLS-1.3' -> <<?BYTE(?APPLICATION_DATA), ?BYTE(3), ?BYTE(3), ?UINT16(4), ?BYTE($F), ?BYTE($O), ?BYTE($O), ?BYTE(?APPLICATION_DATA)>>; _ -> diff --git a/lib/ssl/test/tls_server_session_ticket_SUITE.erl b/lib/ssl/test/tls_server_session_ticket_SUITE.erl index e226ed3143..66e96b0a81 100644 --- a/lib/ssl/test/tls_server_session_ticket_SUITE.erl +++ b/lib/ssl/test/tls_server_session_ticket_SUITE.erl @@ -25,6 +25,7 @@ -include_lib("ssl/src/ssl_cipher.hrl"). -include_lib("ssl/src/ssl_internal.hrl"). -include_lib("ssl/src/tls_handshake_1_3.hrl"). +-include("ssl_record.hrl"). %% Callback functions -export([all/0, @@ -53,7 +54,7 @@ -define(TICKET_STORE_SIZE, 1). -define(MASTER_SECRET, "master_secret"). -define(PRF, sha). --define(VERSION, {3,4}). +-define(VERSION, ?'TLS-1.3'). -define(PSK, <<15,168,18,43,216,33,227,142,114,190,70,183,137,57,64,64,66,152,115,94>>). -define(WINDOW_SIZE, 1). -define(SEED, <<1,2,3,4,5>>). |