fix(tls): issue when ssl listner is configured to use tls v1.3 only
clients could not connect due to incompatible tls options if ssl listner is configured to use tls v1.3 only
This commit is contained in:
parent
b4d081f424
commit
abbba71191
|
@ -485,7 +485,8 @@ to_server_opts(Type, Opts) ->
|
|||
cacertfile => Path(cacertfile),
|
||||
ciphers => Ciphers,
|
||||
versions => Versions
|
||||
})
|
||||
}),
|
||||
Versions
|
||||
).
|
||||
|
||||
%% @doc Convert hocon-checked tls client options (map()) to
|
||||
|
@ -510,19 +511,22 @@ to_client_opts(Type, Opts) ->
|
|||
SNI = ensure_sni(Get(server_name_indication)),
|
||||
Versions = integral_versions(Type, Get(versions)),
|
||||
Ciphers = integral_ciphers(Versions, Get(ciphers)),
|
||||
filter([
|
||||
{keyfile, KeyFile},
|
||||
{certfile, CertFile},
|
||||
{cacertfile, CAFile},
|
||||
{verify, Verify},
|
||||
{server_name_indication, SNI},
|
||||
{versions, Versions},
|
||||
{ciphers, Ciphers},
|
||||
{reuse_sessions, Get(reuse_sessions)},
|
||||
{depth, Get(depth)},
|
||||
{password, ensure_str(Get(password))},
|
||||
{secure_renegotiate, Get(secure_renegotiate)}
|
||||
]);
|
||||
filter(
|
||||
[
|
||||
{keyfile, KeyFile},
|
||||
{certfile, CertFile},
|
||||
{cacertfile, CAFile},
|
||||
{verify, Verify},
|
||||
{server_name_indication, SNI},
|
||||
{versions, Versions},
|
||||
{ciphers, Ciphers},
|
||||
{reuse_sessions, Get(reuse_sessions)},
|
||||
{depth, Get(depth)},
|
||||
{password, ensure_str(Get(password))},
|
||||
{secure_renegotiate, Get(secure_renegotiate)}
|
||||
],
|
||||
Versions
|
||||
);
|
||||
false ->
|
||||
[]
|
||||
end.
|
||||
|
@ -552,10 +556,35 @@ resolve_cert_path_for_read_strict(Path) ->
|
|||
resolve_cert_path_for_read(Path) ->
|
||||
emqx_schema:naive_env_interpolation(Path).
|
||||
|
||||
filter([]) -> [];
|
||||
filter([{_, undefined} | T]) -> filter(T);
|
||||
filter([{_, ""} | T]) -> filter(T);
|
||||
filter([H | T]) -> [H | filter(T)].
|
||||
filter([], _) ->
|
||||
[];
|
||||
filter([{_, undefined} | T], Versions) ->
|
||||
filter(T, Versions);
|
||||
filter([{_, ""} | T], Versions) ->
|
||||
filter(T, Versions);
|
||||
filter([{K, V} | T], Versions) ->
|
||||
case tls_option_compatible_versions(K) of
|
||||
all ->
|
||||
[{K, V} | filter(T, Versions)];
|
||||
CompatibleVersions ->
|
||||
case CompatibleVersions -- (CompatibleVersions -- Versions) of
|
||||
[] ->
|
||||
filter(T, Versions);
|
||||
_ ->
|
||||
[{K, V} | filter(T, Versions)]
|
||||
end
|
||||
end.
|
||||
|
||||
tls_option_compatible_versions(reuse_sessions) ->
|
||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||
tls_option_compatible_versions(secure_renegotiate) ->
|
||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||
tls_option_compatible_versions(user_lookup_fun) ->
|
||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||
tls_option_compatible_versions(client_renegotiation) ->
|
||||
[dtlsv1, 'dtlsv1.2', 'tlsv1', 'tlsv1.1', 'tlsv1.2'];
|
||||
tls_option_compatible_versions(_) ->
|
||||
all.
|
||||
|
||||
-spec fuzzy_map_get(atom() | binary(), map(), any()) -> any().
|
||||
fuzzy_map_get(Key, Options, Default) ->
|
||||
|
|
|
@ -224,6 +224,71 @@ ssl_file_deterministic_names_test() ->
|
|||
),
|
||||
_ = file:del_dir_r(filename:join(["/tmp", ?FUNCTION_NAME])).
|
||||
|
||||
to_client_opts_test() ->
|
||||
VersionsAll = [tlsv1, 'tlsv1.1', 'tlsv1.2', 'tlsv1.3'],
|
||||
Versions13Only = ['tlsv1.3'],
|
||||
Options = #{
|
||||
enable => true,
|
||||
verify => "Verify",
|
||||
server_name_indication => "SNI",
|
||||
ciphers => "Ciphers",
|
||||
depth => "depth",
|
||||
password => "password",
|
||||
versions => VersionsAll,
|
||||
secure_renegotiate => "secure_renegotiate",
|
||||
reuse_sessions => "reuse_sessions"
|
||||
},
|
||||
Expected1 = lists:usort(maps:keys(Options) -- [enable]),
|
||||
?assertEqual(
|
||||
Expected1, lists:usort(proplists:get_keys(emqx_tls_lib:to_client_opts(tls, Options)))
|
||||
),
|
||||
Expected2 =
|
||||
lists:usort(
|
||||
maps:keys(Options) --
|
||||
[enable, reuse_sessions, secure_renegotiate]
|
||||
),
|
||||
?assertEqual(
|
||||
Expected2,
|
||||
lists:usort(
|
||||
proplists:get_keys(
|
||||
emqx_tls_lib:to_client_opts(tls, Options#{versions := Versions13Only})
|
||||
)
|
||||
)
|
||||
),
|
||||
Expected3 = lists:usort(maps:keys(Options) -- [enable, depth, password]),
|
||||
?assertEqual(
|
||||
Expected3,
|
||||
lists:usort(
|
||||
proplists:get_keys(
|
||||
emqx_tls_lib:to_client_opts(tls, Options#{depth := undefined, password := ""})
|
||||
)
|
||||
)
|
||||
).
|
||||
|
||||
to_server_opts_test() ->
|
||||
VersionsAll = [tlsv1, 'tlsv1.1', 'tlsv1.2', 'tlsv1.3'],
|
||||
Versions13Only = ['tlsv1.3'],
|
||||
Options = #{
|
||||
verify => "Verify",
|
||||
ciphers => "Ciphers",
|
||||
versions => VersionsAll,
|
||||
user_lookup_fun => "funfunfun",
|
||||
client_renegotiation => "client_renegotiation"
|
||||
},
|
||||
Expected1 = lists:usort(maps:keys(Options)),
|
||||
?assertEqual(
|
||||
Expected1, lists:usort(proplists:get_keys(emqx_tls_lib:to_server_opts(tls, Options)))
|
||||
),
|
||||
Expected2 = lists:usort(maps:keys(Options) -- [user_lookup_fun, client_renegotiation]),
|
||||
?assertEqual(
|
||||
Expected2,
|
||||
lists:usort(
|
||||
proplists:get_keys(
|
||||
emqx_tls_lib:to_server_opts(tls, Options#{versions := Versions13Only})
|
||||
)
|
||||
)
|
||||
).
|
||||
|
||||
bin(X) -> iolist_to_binary(X).
|
||||
|
||||
test_key() ->
|
||||
|
|
Loading…
Reference in New Issue