fix(tls): fix incompatible tls options and issue with tls version gap
This commit is contained in:
parent
267053cc35
commit
6d88cd7a20
|
@ -478,7 +478,7 @@ to_server_opts(Type, Opts) ->
|
||||||
Versions = integral_versions(Type, maps:get(versions, Opts, undefined)),
|
Versions = integral_versions(Type, maps:get(versions, Opts, undefined)),
|
||||||
Ciphers = integral_ciphers(Versions, maps:get(ciphers, Opts, undefined)),
|
Ciphers = integral_ciphers(Versions, maps:get(ciphers, Opts, undefined)),
|
||||||
Path = fun(Key) -> resolve_cert_path_for_read_strict(maps:get(Key, Opts, undefined)) end,
|
Path = fun(Key) -> resolve_cert_path_for_read_strict(maps:get(Key, Opts, undefined)) end,
|
||||||
filter(
|
ensure_valid_options(
|
||||||
maps:to_list(Opts#{
|
maps:to_list(Opts#{
|
||||||
keyfile => Path(keyfile),
|
keyfile => Path(keyfile),
|
||||||
certfile => Path(certfile),
|
certfile => Path(certfile),
|
||||||
|
@ -511,7 +511,7 @@ to_client_opts(Type, Opts) ->
|
||||||
SNI = ensure_sni(Get(server_name_indication)),
|
SNI = ensure_sni(Get(server_name_indication)),
|
||||||
Versions = integral_versions(Type, Get(versions)),
|
Versions = integral_versions(Type, Get(versions)),
|
||||||
Ciphers = integral_ciphers(Versions, Get(ciphers)),
|
Ciphers = integral_ciphers(Versions, Get(ciphers)),
|
||||||
filter(
|
ensure_valid_options(
|
||||||
[
|
[
|
||||||
{keyfile, KeyFile},
|
{keyfile, KeyFile},
|
||||||
{certfile, CertFile},
|
{certfile, CertFile},
|
||||||
|
@ -556,33 +556,96 @@ resolve_cert_path_for_read_strict(Path) ->
|
||||||
resolve_cert_path_for_read(Path) ->
|
resolve_cert_path_for_read(Path) ->
|
||||||
emqx_schema:naive_env_interpolation(Path).
|
emqx_schema:naive_env_interpolation(Path).
|
||||||
|
|
||||||
filter([], _) ->
|
ensure_valid_options(Options, Versions0) ->
|
||||||
[];
|
Versions = validate_version_gap(Versions0),
|
||||||
filter([{_, undefined} | T], Versions) ->
|
ensure_valid_options(Options, Versions, []).
|
||||||
filter(T, Versions);
|
|
||||||
filter([{_, ""} | T], Versions) ->
|
%% See also lib/ssl/src/ssl.erl#L2617.
|
||||||
filter(T, Versions);
|
%% Do not allow configuration of TLS 1.3 with a gap where TLS 1.2 is not supported
|
||||||
filter([{K, V} | T], Versions) ->
|
%% as that configuration can trigger the built in version downgrade protection
|
||||||
|
%% mechanism and the handshake can fail with an Illegal Parameter alert.
|
||||||
|
validate_version_gap(Versions) ->
|
||||||
|
case lists:member('tlsv1.3', Versions) of
|
||||||
|
true when length(Versions) >= 2 ->
|
||||||
|
case lists:member('tlsv1.2', Versions) of
|
||||||
|
true ->
|
||||||
|
Versions;
|
||||||
|
false ->
|
||||||
|
NewVersions = ['tlsv1.3'],
|
||||||
|
?SLOG(warning, #{
|
||||||
|
msg => "tlsv13_version_gap",
|
||||||
|
versions => Versions,
|
||||||
|
new_versions => NewVersions
|
||||||
|
}),
|
||||||
|
NewVersions
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
Versions
|
||||||
|
end.
|
||||||
|
|
||||||
|
ensure_valid_options([], _, Acc) ->
|
||||||
|
lists:reverse(Acc);
|
||||||
|
ensure_valid_options([{_, undefined} | T], Versions, Acc) ->
|
||||||
|
ensure_valid_options(T, Versions, Acc);
|
||||||
|
ensure_valid_options([{_, ""} | T], Versions, Acc) ->
|
||||||
|
ensure_valid_options(T, Versions, Acc);
|
||||||
|
ensure_valid_options([{K, V} | T], Versions, Acc) ->
|
||||||
case tls_option_compatible_versions(K) of
|
case tls_option_compatible_versions(K) of
|
||||||
all ->
|
all ->
|
||||||
[{K, V} | filter(T, Versions)];
|
ensure_valid_options(T, Versions, [{K, V} | Acc]);
|
||||||
CompatibleVersions ->
|
CompatibleVersions ->
|
||||||
case CompatibleVersions -- (CompatibleVersions -- Versions) of
|
Enabled = sets:from_list(Versions),
|
||||||
[] ->
|
Compatible = sets:from_list(CompatibleVersions),
|
||||||
filter(T, Versions);
|
case sets:size(sets:intersection(Enabled, Compatible)) > 0 of
|
||||||
_ ->
|
true ->
|
||||||
[{K, V} | filter(T, Versions)]
|
ensure_valid_options(T, Versions, [{K, V} | Acc]);
|
||||||
|
false ->
|
||||||
|
?SLOG(warning, #{
|
||||||
|
msg => "drop_incompatible_tls_option", option => K, versions => Versions
|
||||||
|
}),
|
||||||
|
ensure_valid_options(T, Versions, Acc)
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% see lib/ssl/src/ssl.erl, assert_option_dependency/4
|
||||||
|
tls_option_compatible_versions(beast_mitigation) ->
|
||||||
|
[dtlsv1, 'tlsv1'];
|
||||||
|
tls_option_compatible_versions(padding_check) ->
|
||||||
|
[dtlsv1, 'tlsv1'];
|
||||||
|
tls_option_compatible_versions(client_renegotiation) ->
|
||||||
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
|
tls_option_compatible_versions(reuse_session) ->
|
||||||
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
tls_option_compatible_versions(reuse_sessions) ->
|
tls_option_compatible_versions(reuse_sessions) ->
|
||||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
tls_option_compatible_versions(secure_renegotiate) ->
|
tls_option_compatible_versions(secure_renegotiate) ->
|
||||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
|
tls_option_compatible_versions(next_protocol_advertised) ->
|
||||||
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
|
tls_option_compatible_versions(client_preferred_next_protocols) ->
|
||||||
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
|
tls_option_compatible_versions(psk_identity) ->
|
||||||
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
|
tls_option_compatible_versions(srp_identity) ->
|
||||||
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
tls_option_compatible_versions(user_lookup_fun) ->
|
tls_option_compatible_versions(user_lookup_fun) ->
|
||||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||||
tls_option_compatible_versions(client_renegotiation) ->
|
tls_option_compatible_versions(early_data) ->
|
||||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(certificate_authorities) ->
|
||||||
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(cookie) ->
|
||||||
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(key_update_at) ->
|
||||||
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(anti_replay) ->
|
||||||
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(session_tickets) ->
|
||||||
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(supported_groups) ->
|
||||||
|
['tlsv1.3'];
|
||||||
|
tls_option_compatible_versions(use_ticket) ->
|
||||||
|
['tlsv1.3'];
|
||||||
tls_option_compatible_versions(_) ->
|
tls_option_compatible_versions(_) ->
|
||||||
all.
|
all.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue