aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPéter Dimitrov <[email protected]>2018-10-26 11:06:18 +0200
committerPéter Dimitrov <[email protected]>2018-11-01 15:52:57 +0100
commit29b555abdebc7ce2097679286ca94b176aa493b9 (patch)
tree8e6a4a76686d9a4da1b584fe0025a6aa551c1040
parentf3dfe10d8ee4a65362ef75803016b7b2e4368719 (diff)
downloadotp-29b555abdebc7ce2097679286ca94b176aa493b9.tar.gz
otp-29b555abdebc7ce2097679286ca94b176aa493b9.tar.bz2
otp-29b555abdebc7ce2097679286ca94b176aa493b9.zip
ssl: Fix failing property tests
- Updated message generators: ClientHello, ServerHello and EncryptedExtensions - Fixed encoding of the extensions 'signature_algorithms' and 'signature_algorithms_cert' - Updated empty extension definitions Change-Id: I9415e2d022744b9ed4667d20aee2553637ed49f8
-rw-r--r--lib/ssl/src/ssl_handshake.erl105
-rw-r--r--lib/ssl/src/ssl_handshake.hrl8
-rw-r--r--lib/ssl/test/property_test/ssl_eqc_handshake.erl443
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl6
4 files changed, 386 insertions, 176 deletions
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 1e812c92a8..da2e92a76b 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -75,7 +75,7 @@
handle_client_hello_extensions/9, %% Returns server hello extensions
handle_server_hello_extensions/9, select_curve/2, select_curve/3,
select_hashsign/4, select_hashsign/5,
- select_hashsign_algs/3
+ select_hashsign_algs/3, empty_extensions/2
]).
%%====================================================================
@@ -646,7 +646,15 @@ encode_extensions([#hash_sign_algos{hash_sign_algos = HashSignAlgos} | Rest], Ac
Len = ListLen + 2,
encode_extensions(Rest, <<?UINT16(?SIGNATURE_ALGORITHMS_EXT),
?UINT16(Len), ?UINT16(ListLen), SignAlgoList/binary, Acc/binary>>);
-encode_extensions([#signature_scheme_list{
+encode_extensions([#signature_algorithms{
+ signature_scheme_list = SignatureSchemes} | Rest], Acc) ->
+ SignSchemeList = << <<(ssl_cipher:signature_scheme(SignatureScheme)):16 >> ||
+ SignatureScheme <- SignatureSchemes >>,
+ ListLen = byte_size(SignSchemeList),
+ Len = ListLen + 2,
+ encode_extensions(Rest, <<?UINT16(?SIGNATURE_ALGORITHMS_EXT),
+ ?UINT16(Len), ?UINT16(ListLen), SignSchemeList/binary, Acc/binary>>);
+encode_extensions([#signature_algorithms_cert{
signature_scheme_list = SignatureSchemes} | Rest], Acc) ->
SignSchemeList = << <<(ssl_cipher:signature_scheme(SignatureScheme)):16 >> ||
SignatureScheme <- SignatureSchemes >>,
@@ -711,7 +719,7 @@ decode_handshake(Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32
session_id = Session_ID,
cipher_suite = Cipher_suite,
compression_method = Comp_method,
- extensions = empty_hello_extensions(Version, server)};
+ extensions = empty_extensions(Version, server_hello)};
decode_handshake(Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID:SID_length/binary,
@@ -780,7 +788,12 @@ decode_vector(<<?UINT16(Len), Vector:Len/binary>>) ->
%% Description: Decodes TLS hello extensions
%%--------------------------------------------------------------------
decode_hello_extensions(Extensions, Version, Role) ->
- decode_extensions(Extensions, Version, empty_hello_extensions(Version, Role)).
+ MessageType =
+ case Role of
+ client -> client_hello;
+ server -> server_hello
+ end,
+ decode_extensions(Extensions, Version, empty_extensions(Version, MessageType)).
%%--------------------------------------------------------------------
-spec decode_extensions(binary(),tuple()) -> map().
@@ -1049,14 +1062,14 @@ maybe_add_tls13_extensions({3,4},
HelloExtensions#{client_hello_versions =>
#client_hello_versions{versions = SupportedVersions},
signature_algs_cert =>
- signature_scheme_list(SignatureSchemes)};
+ signature_algs_cert(SignatureSchemes)};
maybe_add_tls13_extensions(_, HelloExtensions, _) ->
HelloExtensions.
-signature_scheme_list(undefined) ->
+signature_algs_cert(undefined) ->
undefined;
-signature_scheme_list(SignatureSchemes) ->
- #signature_scheme_list{signature_scheme_list = SignatureSchemes}.
+signature_algs_cert(SignatureSchemes) ->
+ #signature_algorithms_cert{signature_scheme_list = SignatureSchemes}.
handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
Exts, Version,
@@ -1071,7 +1084,7 @@ handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
ClientCipherSuites, Compression,
ConnectionStates0, Renegotiation, SecureRenegotation),
- Empty = empty_hello_extensions(Version, client),
+ Empty = empty_extensions(Version, server_hello),
ServerHelloExtensions = Empty#{renegotiation_info => renegotiation_info(RecordCB, server,
ConnectionStates, Renegotiation),
ec_point_formats => server_ecc_extension(Version, maps:get(ec_point_formats, Exts, undefined))
@@ -1279,7 +1292,7 @@ get_cert_params(Cert) ->
get_signature_scheme(undefined) ->
undefined;
-get_signature_scheme(#signature_scheme_list{
+get_signature_scheme(#signature_algorithms_cert{
signature_scheme_list = ClientSignatureSchemes}) ->
ClientSignatureSchemes.
@@ -2101,7 +2114,8 @@ decode_extensions(<<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen),
decode_extensions(Rest, Version, Acc#{srp => #srp{username = SRP}});
decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
- ExtData:Len/binary, Rest/binary>>, Version, Acc) ->
+ ExtData:Len/binary, Rest/binary>>, Version, Acc)
+ when Version < {3,4} ->
SignAlgoListLen = Len - 2,
<<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData,
HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} ||
@@ -2110,6 +2124,17 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
#hash_sign_algos{hash_sign_algos =
HashSignAlgos}});
+decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
+ ExtData:Len/binary, Rest/binary>>, Version, Acc)
+ when Version =:= {3,4} ->
+ SignSchemeListLen = Len - 2,
+ <<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData,
+ SignSchemes = [ssl_cipher:signature_scheme(SignScheme) ||
+ <<?UINT16(SignScheme)>> <= SignSchemeList],
+ decode_extensions(Rest, Version, Acc#{signature_algs =>
+ #signature_algorithms{
+ signature_scheme_list = SignSchemes}});
+
decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
ExtData:Len/binary, Rest/binary>>, Version, Acc) ->
SignSchemeListLen = Len - 2,
@@ -2117,7 +2142,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
SignSchemes = [ssl_cipher:signature_scheme(SignScheme) ||
<<?UINT16(SignScheme)>> <= SignSchemeList],
decode_extensions(Rest, Version, Acc#{signature_algs_cert =>
- #signature_scheme_list{
+ #signature_algorithms_cert{
signature_scheme_list = SignSchemes}});
decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
@@ -2756,27 +2781,37 @@ cert_curve(Cert, ECCCurve0, CipherSuite) ->
{ECCCurve0, CipherSuite}
end.
-empty_hello_extensions({3, 4}, server) ->
- #{server_hello_selected_version => undefined,
- key_share => undefined,
- pre_shared_key => undefined,
- sni => undefined
- };
-empty_hello_extensions({3, 4}, client) ->
- #{client_hello_versions => undefined,
- signature_algs => undefined,
- signature_algs_cert => undefined,
+empty_extensions() ->
+ #{}.
+
+empty_extensions({3,4}, client_hello) ->
+ #{
sni => undefined,
+ %% max_fragment_length => undefined,
+ %% status_request => undefined,
+ elliptic_curves => undefined,
+ signature_algs => undefined,
+ %% use_srtp => undefined,
+ %% heartbeat => undefined,
alpn => undefined,
+ %% signed_cert_timestamp => undefined,
+ %% client_cert_type => undefined,
+ %% server_cert_type => undefined,
+ %% padding => undefined,
key_share => undefined,
- pre_shared_key => undefined
+ pre_shared_key => undefined,
+ %% psk_key_exhange_modes => undefined,
+ %% early_data => undefined,
+ %% cookie => undefined,
+ client_hello_versions => undefined,
+ %% cert_authorities => undefined,
+ %% post_handshake_auth => undefined,
+ signature_algs_cert => undefined
};
-empty_hello_extensions({3, 3}, client) ->
- Ext = empty_hello_extensions({3,2}, client),
- Ext#{client_hello_versions => undefined,
- signature_algs => undefined,
- signature_algs_cert => undefined};
-empty_hello_extensions(_, client) ->
+empty_extensions({3, 3}, client_hello) ->
+ Ext = empty_extensions({3,2}, client_hello),
+ Ext#{signature_algs => undefined};
+empty_extensions(_, client_hello) ->
#{renegotiation_info => undefined,
alpn => undefined,
next_protocol_negotiation => undefined,
@@ -2784,11 +2819,13 @@ empty_hello_extensions(_, client) ->
ec_point_formats => undefined,
elliptic_curves => undefined,
sni => undefined};
-empty_hello_extensions(_, server) ->
+empty_extensions({3,4}, server_hello) ->
+ #{server_hello_selected_version => undefined,
+ key_share => undefined,
+ pre_shared_key => undefined
+ };
+empty_extensions(_, server_hello) ->
#{renegotiation_info => undefined,
alpn => undefined,
next_protocol_negotiation => undefined,
- ec_point_formats => undefined,
- sni => undefined}.
-empty_extensions() ->
- #{}.
+ ec_point_formats => undefined}.
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index 4336742e76..1fd143a641 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -315,9 +315,9 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-define(SIGNATURE_ALGORITHMS_EXT, 13).
--record(hash_sign_algos, {
- hash_sign_algos
- }).
+-record(hash_sign_algos, {hash_sign_algos}).
+%% RFC 8446 (TLS 1.3)
+-record(signature_algorithms, {signature_scheme_list}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% RFC 7301 Application-Layer Protocol Negotiation
@@ -436,6 +436,6 @@
-define(SIGNATURE_ALGORITHMS_CERT_EXT, 50).
--record(signature_scheme_list, {signature_scheme_list}).
+-record(signature_algorithms_cert, {signature_scheme_list}).
-endif. % -ifdef(ssl_handshake).
diff --git a/lib/ssl/test/property_test/ssl_eqc_handshake.erl b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
index 99c6554f15..8b3b81aaf1 100644
--- a/lib/ssl/test/property_test/ssl_eqc_handshake.erl
+++ b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
@@ -85,17 +85,14 @@ prop_tls_hs_encode_decode() ->
).
%%--------------------------------------------------------------------
-%% Message Generators --------------------------------------------------
+%% Message Generators -----------------------------------------------
%%--------------------------------------------------------------------
-tls_version() ->
- oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1', ?'SSL_v3']).
-
tls_msg(?'TLS_v1.3'= Version) ->
oneof([client_hello(Version),
server_hello(Version),
%%new_session_ticket()
- #end_of_early_data{},
+ #end_of_early_data{},
encrypted_extensions(),
certificate_1_3(),
%%certificate_request_1_3,
@@ -104,7 +101,8 @@ tls_msg(?'TLS_v1.3'= Version) ->
key_update()
]);
tls_msg(Version) ->
- oneof([#hello_request{},
+ oneof([
+ #hello_request{},
client_hello(Version),
server_hello(Version),
certificate(),
@@ -116,6 +114,9 @@ tls_msg(Version) ->
finished()
]).
+%%
+%% Shared messages
+%%
client_hello(?'TLS_v1.3' = Version) ->
#client_hello{session_id = session_id(),
client_version = ?'TLS_v1.2',
@@ -150,10 +151,6 @@ server_hello(Version) ->
extensions = server_hello_extensions(Version)
}.
-encrypted_extensions() ->
- ?LET(Exts, extensions(?'TLS_v1.3'),
- #encrypted_extensions{extensions = Exts}).
-
certificate() ->
#certificate{
asn1_certificates = certificate_chain()
@@ -166,17 +163,35 @@ certificate_1_3() ->
entries = certificate_entries(Certs, [])
}).
-key_update() ->
- #key_update{request_update = request_update()}.
-
finished() ->
?LET(Size, digest_size(),
#finished{verify_data = crypto:strong_rand_bytes(Size)}).
+%%
+%% TLS 1.0-1.2 messages
+%%
+
+
+
+%%
+%% TLS 1.3 messages
+%%
+
+encrypted_extensions() ->
+ ?LET(Exts, extensions(?'TLS_v1.3', encrypted_extensions),
+ #encrypted_extensions{extensions = Exts}).
+
+
+key_update() ->
+ #key_update{request_update = request_update()}.
+
+
%%--------------------------------------------------------------------
%% Messge Data Generators -------------------------------------------
%%--------------------------------------------------------------------
+tls_version() ->
+ oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1', ?'SSL_v3']).
cipher_suite(Version) ->
oneof(cipher_suites(Version)).
@@ -200,52 +215,14 @@ server_random(_) ->
crypto:strong_rand_bytes(32).
-client_hello_extensions(?'TLS_v1.3' = Version) ->
- ?LET({Versions, Ext}, {supported_versions(Version), c_hello_extensions(Version)},
- maps:merge(Ext, #{client_hello_versions => client_hello_versions(Versions)})
- );
-client_hello_extensions(?'TLS_v1.2' = Version) ->
- ?LET({Versions, Exts}, {supported_versions(Version), c_hello_extensions(Version)},
- maps:merge(Exts, #{client_hello_versions => client_hello_versions(Versions)})
- );
client_hello_extensions(Version) ->
- ?LET(Exts,
- c_hello_extensions(Version),
- maps:merge(empty_hello_extensions(Version, client), Exts)).
-
-server_hello_extensions(?'TLS_v1.3' = Version) ->
- ?LET(Exts,
- s_hello_extensions(Version),
- maps:merge(Exts, #{server_hello_selected_version => server_hello_selected_version(Version)}));
-server_hello_extensions(Version) ->
- ?LET(Exts,
- s_hello_extensions(Version),
- Exts).
-
-c_hello_extensions(?'TLS_v1.3'= Version) ->
- ?LET({KeyShare, PreShare}, {key_share_client_hello(),
- pre_shared_keyextension()},
- maps:merge(empty_hello_extensions(Version, client),
- #{key_share => KeyShare,
- pre_shared_key => PreShare
- })
- );
-c_hello_extensions(Version) ->
- ?LET(Exts, extensions(Version),
- maps:merge(empty_hello_extensions(Version, client),
+ ?LET(Exts, extensions(Version, client_hello),
+ maps:merge(ssl_handshake:empty_extensions(Version, client_hello),
Exts)).
-s_hello_extensions(?'TLS_v1.3'= Version) ->
- ?LET({KeyShare, PreShare}, {key_share_server_hello(),
- pre_shared_keyextension()},
- maps:merge(empty_hello_extensions(Version, server),
- #{key_share => KeyShare,
- pre_shared_key => PreShare
- })
- );
-s_hello_extensions(Version) ->
- ?LET(Exts, extensions(Version),
- maps:merge(empty_hello_extensions(Version, server),
+server_hello_extensions(Version) ->
+ ?LET(Exts, extensions(Version, server_hello),
+ maps:merge(ssl_handshake:empty_extensions(Version, server_hello),
Exts)).
key_share_client_hello() ->
@@ -260,83 +237,260 @@ pre_shared_keyextension() ->
oneof([undefined]).
%%oneof([#pre_shared_keyextension{},undefined]).
-extensions(?'TLS_v1.3') ->
- ?LET({Ext_1_3, Exts}, {extensions_1_3(), extensions(?'TLS_v1.2')}, maps:merge(Ext_1_3, Exts));
-extensions(?'SSL_v3') ->
+%% +--------------------------------------------------+-------------+
+%% | Extension | TLS 1.3 |
+%% +--------------------------------------------------+-------------+
+%% | server_name [RFC6066] | CH, EE |
+%% | | |
+%% | max_fragment_length [RFC6066] | CH, EE |
+%% | | |
+%% | status_request [RFC6066] | CH, CR, CT |
+%% | | |
+%% | supported_groups [RFC7919] | CH, EE |
+%% | | |
+%% | signature_algorithms (RFC 8446) | CH, CR |
+%% | | |
+%% | use_srtp [RFC5764] | CH, EE |
+%% | | |
+%% | heartbeat [RFC6520] | CH, EE |
+%% | | |
+%% | application_layer_protocol_negotiation [RFC7301] | CH, EE |
+%% | | |
+%% | signed_certificate_timestamp [RFC6962] | CH, CR, CT |
+%% | | |
+%% | client_certificate_type [RFC7250] | CH, EE |
+%% | | |
+%% | server_certificate_type [RFC7250] | CH, EE |
+%% | | |
+%% | padding [RFC7685] | CH |
+%% | | |
+%% | key_share (RFC 8446) | CH, SH, HRR |
+%% | | |
+%% | pre_shared_key (RFC 8446) | CH, SH |
+%% | | |
+%% | psk_key_exchange_modes (RFC 8446) | CH |
+%% | | |
+%% | early_data (RFC 8446) | CH, EE, NST |
+%% | | |
+%% | cookie (RFC 8446) | CH, HRR |
+%% | | |
+%% | supported_versions (RFC 8446) | CH, SH, HRR |
+%% | | |
+%% | certificate_authorities (RFC 8446) | CH, CR |
+%% | | |
+%% | oid_filters (RFC 8446) | CR |
+%% | | |
+%% | post_handshake_auth (RFC 8446) | CH |
+%% | | |
+%% | signature_algorithms_cert (RFC 8446) | CH, CR |
+%% +--------------------------------------------------+-------------+
+extensions(?'TLS_v1.3' = Version, client_hello) ->
+ ?LET({
+ ServerName,
+ %% MaxFragmentLength,
+ %% StatusRequest,
+ SupportedGroups,
+ SignatureAlgorithms,
+ %% UseSrtp,
+ %% Heartbeat,
+ ALPN,
+ %% SignedCertTimestamp,
+ %% ClientCertiticateType,
+ %% ServerCertificateType,
+ %% Padding,
+ %% KeyShare,
+ %% PreSharedKey,
+ %% PSKKeyExchangeModes,
+ %% EarlyData,
+ %% Cookie,
+ SupportedVersions,
+ %% CertAuthorities,
+ %% PostHandshakeAuth,
+ SignatureAlgorithmsCert
+ },
+ {
+ oneof([server_name(), undefined]),
+ %% oneof([max_fragment_length(), undefined]),
+ %% oneof([status_request(), undefined]),
+ oneof([supported_groups(Version), undefined]),
+ oneof([signature_algs(Version), undefined]),
+ %% oneof([use_srtp(), undefined]),
+ %% oneof([heartbeat(), undefined]),
+ oneof([alpn(), undefined]),
+ %% oneof([signed_cert_timestamp(), undefined]),
+ %% oneof([client_cert_type(), undefined]),
+ %% oneof([server_cert_type(), undefined]),
+ %% oneof([padding(), undefined]),
+ %% oneof([key_share(), undefined]),
+ %% oneof([pre_shared_key(), undefined]),
+ %% oneof([psk_key_exchange_modes(), undefined]),
+ %% oneof([early_data(), undefined]),
+ %% oneof([cookie(), undefined]),
+ oneof([client_hello_versions(Version), undefined]),
+ %% oneof([cert_authorities(), undefined]),
+ %% oneof([post_handshake_auth(), undefined]),
+ oneof([signature_algs_cert(), undefined])
+ },
+ maps:filter(fun(_, undefined) ->
+ false;
+ (_,_) ->
+ true
+ end,
+ #{
+ sni => ServerName,
+ %% max_fragment_length => MaxFragmentLength,
+ %% status_request => StatusRequest,
+ elliptic_curves => SupportedGroups,
+ signature_algs => SignatureAlgorithms,
+ %% use_srtp => UseSrtp,
+ %% heartbeat => Heartbeat,
+ alpn => ALPN,
+ %% signed_cert_timestamp => SignedCertTimestamp,
+ %% client_cert_type => ClientCertificateType,
+ %% server_cert_type => ServerCertificateType,
+ %% padding => Padding,
+ %% key_share => KeyShare,
+ %% pre_shared_key => PreSharedKey,
+ %% psk_key_exhange_modes => PSKKeyExchangeModes,
+ %% early_data => EarlyData,
+ %% cookie => Cookie,
+ client_hello_versions => SupportedVersions,
+ %% cert_authorities => CertAuthorities,
+ %% post_handshake_auth => PostHandshakeAuth,
+ signature_algs_cert => SignatureAlgorithmsCert
+ }));
+extensions(?'SSL_v3', client_hello) ->
#{};
-extensions(Version) ->
- ?LET({SNI, ECPoitF, ECCurves, ALPN, NextP, SRP},
- {oneof([sni(), undefined]),
- oneof([ec_poit_formats(), undefined]),
+extensions(Version, client_hello) ->
+ ?LET({
+ SNI,
+ ECPoitF,
+ ECCurves,
+ ALPN,
+ NextP,
+ SRP
+ %% RenegotiationInfo
+ },
+ {
+ oneof([sni(), undefined]),
+ oneof([ec_point_formats(), undefined]),
oneof([elliptic_curves(Version), undefined]),
oneof([alpn(), undefined]),
oneof([next_protocol_negotiation(), undefined]),
- oneof([srp(), undefined])},
+ oneof([srp(), undefined])
+ %% oneof([renegotiation_info(), undefined])
+ },
maps:filter(fun(_, undefined) ->
false;
(_,_) ->
true
end,
- #{sni => SNI,
+ #{
+ sni => SNI,
ec_point_formats => ECPoitF,
elliptic_curves => ECCurves,
alpn => ALPN,
next_protocol_negotiation => NextP,
- srp => SRP})).
-
-extensions_1_3() ->
- %% ?LET(Entry, key_share_entry(),
- %% maps:filter(fun(_, undefined) ->
- %% false;
- %% (_,_) ->
- %% true
- %% end, #{key_share_entry => Entry})).
- ?LET({HashSign, SigAlgCert}, {oneof([hash_sign_algos(?'TLS_v1.2')]), oneof([signature_scheme_list()])},
- #{signature_algs => HashSign,
- signature_algs_cert => SigAlgCert}).
-
-empty_hello_extensions({3, 4}, server) ->
- #{server_hello_selected_version => undefined,
- key_share => undefined,
- pre_shared_key => undefined,
- sni => undefined
- };
-empty_hello_extensions({3, 4}, client) ->
- #{client_hello_versions => undefined,
- signature_algs => undefined,
- signature_algs_cert => undefined,
- sni => undefined,
- alpn => undefined,
- key_share => undefined,
- pre_shared_key => undefined
- };
-empty_hello_extensions({3, 3}, client) ->
- Ext = empty_hello_extensions({3,2}, client),
- Ext#{client_hello_versions => undefined,
- signature_algs => undefined,
- signature_algs_cert => undefined};
-empty_hello_extensions(_, client) ->
- #{renegotiation_info => undefined,
- alpn => undefined,
- next_protocol_negotiation => undefined,
- srp => undefined,
- ec_point_formats => undefined,
- elliptic_curves => undefined,
- sni => undefined};
-empty_hello_extensions(_, server) ->
- #{renegotiation_info => undefined,
- alpn => undefined,
- next_protocol_negotiation => undefined,
- ec_point_formats => undefined,
- sni => undefined}.
+ srp => SRP
+ %% renegotiation_info => RenegotiationInfo
+ }));
+extensions(?'TLS_v1.3' = Version, server_hello) ->
+ ?LET({
+ %% KeyShare,
+ %% PreSharedKeys,
+ SupportedVersions
+ },
+ {
+ %% oneof([key_share(), undefined]),
+ %% oneof([pre_shared_keys(), undefined]),
+ oneof([server_hello_selected_version(), undefined])
+ },
+ maps:filter(fun(_, undefined) ->
+ false;
+ (_,_) ->
+ true
+ end,
+ #{
+ %% key_share => KeyShare,
+ %% pre_shared_keys => PreSharedKeys,
+ server_hello_selected_version => SupportedVersions
+ }));
+extensions(Version, server_hello) ->
+ ?LET({
+ ECPoitF,
+ ALPN,
+ NextP
+ %% RenegotiationInfo,
+ },
+ {
+ oneof([ec_point_formats(), undefined]),
+ oneof([alpn(), undefined]),
+ oneof([next_protocol_negotiation(), undefined])
+ %% oneof([renegotiation_info(), undefined]),
+ },
+ maps:filter(fun(_, undefined) ->
+ false;
+ (_,_) ->
+ true
+ end,
+ #{
+ ec_point_formats => ECPoitF,
+ alpn => ALPN,
+ next_protocol_negotiation => NextP
+ %% renegotiation_info => RenegotiationInfo
+ }));
+extensions(?'TLS_v1.3' = Version, encrypted_extensions) ->
+ ?LET({
+ ServerName,
+ %% MaxFragmentLength,
+ SupportedGroups,
+ %% UseSrtp,
+ %% Heartbeat,
+ ALPN
+ %% ClientCertiticateType,
+ %% ServerCertificateType,
+ %% EarlyData
+ },
+ {
+ oneof([server_name(), undefined]),
+ %% oneof([max_fragment_length(), undefined]),
+ oneof([supported_groups(Version), undefined]),
+ %% oneof([use_srtp(), undefined]),
+ %% oneof([heartbeat(), undefined]),
+ oneof([alpn(), undefined])
+ %% oneof([client_cert_type(), undefined]),
+ %% oneof([server_cert_type(), undefined]),
+ %% oneof([early_data(), undefined])
+ },
+ maps:filter(fun(_, undefined) ->
+ false;
+ (_,_) ->
+ true
+ end,
+ #{
+ sni => ServerName,
+ %% max_fragment_length => MaxFragmentLength,
+ elliptic_curves => SupportedGroups,
+ %% use_srtp => UseSrtp,
+ %% heartbeat => Heartbeat,
+ alpn => ALPN
+ %% client_cert_type => ClientCertificateType,
+ %% server_cert_type => ServerCertificateType,
+ %% early_data => EarlyData
+ })).
+
+server_name() ->
+ ?LET(ServerName, sni(),
+ ServerName).
+ %% sni().
signature_algs_cert() ->
- ?LET(Algs, signature_scheme_list(),
- Algs).
+ ?LET(List, sig_scheme_list(),
+ #signature_algorithms_cert{signature_scheme_list = List}).
-signature_scheme_list() ->
+signature_algorithms() ->
?LET(List, sig_scheme_list(),
- #signature_scheme_list{signature_scheme_list = List}).
+ #signature_algorithms{signature_scheme_list = List}).
sig_scheme_list() ->
oneof([[rsa_pkcs1_sha256],
@@ -357,16 +511,23 @@ sig_scheme_list() ->
ecdsa_sha1]
]).
-supported_versions(?'TLS_v1.3') ->
- oneof([[{3,4}],
- [{3,3},{3,4}],
- [{3,4},{3,3},{3,2},{3,1},{3,0}]
- ]);
-supported_versions(_) ->
- oneof([[{3,3}],
- [{3,3},{3,2}],
- [{3,3},{3,2},{3,1},{3,0}]
- ]).
+client_hello_versions(?'TLS_v1.3') ->
+ ?LET(SupportedVersions,
+ oneof([[{3,4}],
+ [{3,3},{3,4}],
+ [{3,4},{3,3},{3,2},{3,1},{3,0}]
+ ]),
+ #client_hello_versions{versions = SupportedVersions});
+client_hello_versions(_) ->
+ ?LET(SupportedVersions,
+ oneof([[{3,3}],
+ [{3,3},{3,2}],
+ [{3,3},{3,2},{3,1},{3,0}]
+ ]),
+ #client_hello_versions{versions = SupportedVersions}).
+
+server_hello_selected_version() ->
+ #server_hello_selected_version{selected_version = {3,4}}.
request_update() ->
oneof([?UPDATE_NOT_REQUESTED, ?UPDATE_REQUESTED]).
@@ -431,13 +592,25 @@ certificate_types(?'TLS_v1.2') ->
certificate_types(_) ->
iolist_to_binary([<<?BYTE(?ECDSA_SIGN)>>, <<?BYTE(?RSA_SIGN)>>, <<?BYTE(?DSS_SIGN)>>]).
+
+
+signature_algs({3,4}) ->
+ ?LET(Algs, signature_algorithms(),
+ Algs);
+signature_algs({3,3} = Version) ->
+ #hash_sign_algos{hash_sign_algos = hash_alg_list(Version)};
+signature_algs(Version) when Version < {3,3} ->
+ undefined.
+
+
+
hashsign_algorithms({_, N} = Version) when N >= 3 ->
#hash_sign_algos{hash_sign_algos = hash_alg_list(Version)};
hashsign_algorithms(_) ->
undefined.
hash_alg_list(Version) ->
- ?LET(NumOf, choose(0,15),
+ ?LET(NumOf, choose(1,15),
?LET(List, [hash_alg(Version) || _ <- lists:seq(1,NumOf)],
lists:usort(List)
)).
@@ -481,27 +654,27 @@ key_share_entry() ->
undefined.
%%#key_share_entry{}.
-client_hello_versions(Versions) ->
- #client_hello_versions{versions = Versions}.
-
server_hello_selected_version(Version) ->
#server_hello_selected_version{selected_version = Version}.
sni() ->
#sni{hostname = net_adm:localhost()}.
-ec_poit_formats() ->
+ec_point_formats() ->
#ec_point_formats{ec_point_format_list = ec_point_format_list()}.
ec_point_format_list() ->
[?ECPOINT_UNCOMPRESSED].
-elliptic_curves({_, Minor}) ->
+elliptic_curves({_, Minor}) when Minor < 4 ->
Curves = tls_v1:ecc_curves(Minor),
#elliptic_curves{elliptic_curve_list = Curves}.
-hash_sign_algos(Version) ->
- #hash_sign_algos{hash_sign_algos = hash_alg_list(Version)}.
+%% RFC 8446 (TLS 1.3) renamed the "elliptic_curve" extension.
+supported_groups({_, Minor}) when Minor >= 4 ->
+ SupportedGroups = tls_v1:groups(Minor),
+ #supported_groups{supported_groups = SupportedGroups}.
+
alpn() ->
?LET(ExtD, alpn_protocols(), #alpn{extension_data = ExtD}).
@@ -520,7 +693,7 @@ renegotiation_info() ->
#renegotiation_info{renegotiated_connection = 0}.
gen_name() ->
- ?LET(Size, choose(0,10), gen_string(Size)).
+ ?LET(Size, choose(1,10), gen_string(Size)).
gen_char() ->
choose($a,$z).
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index 861fecc554..c35ee6cb57 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -112,7 +112,7 @@ decode_hello_handshake(_Config) ->
decode_single_hello_extension_correctly(_Config) ->
Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>,
- Extensions = ssl_handshake:decode_extensions(Renegotiation),
+ Extensions = ssl_handshake:decode_extensions(Renegotiation, {3,3}),
#{renegotiation_info := #renegotiation_info{renegotiated_connection = <<0>>}} = Extensions.
decode_supported_elliptic_curves_hello_extension_correctly(_Config) ->
@@ -200,7 +200,7 @@ signature_algorithms(Config) ->
hash_sign_algos = [{sha512, rsa},
{sha, dsa},
{sha, rsa}]},
- Schemes0 = #signature_scheme_list{
+ Schemes0 = #signature_algorithms_cert{
signature_scheme_list = [rsa_pkcs1_sha1,
ecdsa_sha1]},
{sha512, rsa} = ssl_handshake:select_hashsign(
@@ -216,7 +216,7 @@ signature_algorithms(Config) ->
Cert, ecdhe_rsa,
tls_v1:default_signature_algs({3,3}),
{3,3}),
- Schemes1 = #signature_scheme_list{
+ Schemes1 = #signature_algorithms_cert{
signature_scheme_list = [rsa_pkcs1_sha256,
ecdsa_sha1]},
%% Signature not supported