feat(tls): automatically add `cacerts` to client opts
`public_key:cacerts_get/0` was introduced in OTP 25 and allows us to load the system trusted CA certificates. https://www.erlang.org/doc/man/public_key.html#cacerts_get-0
This commit is contained in:
parent
1874cd1223
commit
d3d52695d5
|
@ -2017,6 +2017,14 @@ common_ssl_opts_schema(Defaults, Type) ->
|
|||
desc => ?DESC(common_ssl_opts_schema_cacertfile)
|
||||
}
|
||||
)},
|
||||
{"cacerts",
|
||||
sc(
|
||||
boolean(),
|
||||
#{
|
||||
default => false,
|
||||
desc => ?DESC(common_ssl_opts_schema_cacerts)
|
||||
}
|
||||
)},
|
||||
{"certfile",
|
||||
sc(
|
||||
binary(),
|
||||
|
|
|
@ -478,11 +478,13 @@ to_server_opts(Type, Opts) ->
|
|||
Versions = integral_versions(Type, maps:get(versions, 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,
|
||||
CACerts = get_cacerts(maps:get(cacerts, Opts, false)),
|
||||
ensure_valid_options(
|
||||
maps:to_list(Opts#{
|
||||
keyfile => Path(keyfile),
|
||||
certfile => Path(certfile),
|
||||
cacertfile => Path(cacertfile),
|
||||
cacerts => CACerts,
|
||||
ciphers => Ciphers,
|
||||
versions => Versions
|
||||
}),
|
||||
|
@ -511,11 +513,13 @@ to_client_opts(Type, Opts) ->
|
|||
SNI = ensure_sni(Get(server_name_indication)),
|
||||
Versions = integral_versions(Type, Get(versions)),
|
||||
Ciphers = integral_ciphers(Versions, Get(ciphers)),
|
||||
CACerts = get_cacerts(GetD(cacerts, false)),
|
||||
ensure_valid_options(
|
||||
[
|
||||
{keyfile, KeyFile},
|
||||
{certfile, CertFile},
|
||||
{cacertfile, CAFile},
|
||||
{cacerts, CACerts},
|
||||
{verify, Verify},
|
||||
{server_name_indication, SNI},
|
||||
{versions, Versions},
|
||||
|
@ -661,3 +665,13 @@ ensure_ssl_file_key(SSL, RequiredKeyPaths) ->
|
|||
[] -> ok;
|
||||
Miss -> {error, #{reason => ssl_file_option_not_found, which_options => Miss}}
|
||||
end.
|
||||
|
||||
get_cacerts(true = _UseSystemCACerts) ->
|
||||
try
|
||||
public_key:cacerts_get()
|
||||
catch
|
||||
_:_ ->
|
||||
undefined
|
||||
end;
|
||||
get_cacerts(false = _UseSystemCACerts) ->
|
||||
undefined.
|
||||
|
|
|
@ -229,6 +229,7 @@ to_client_opts_test() ->
|
|||
Versions13Only = ['tlsv1.3'],
|
||||
Options = #{
|
||||
enable => true,
|
||||
cacerts => true,
|
||||
verify => "Verify",
|
||||
server_name_indication => "SNI",
|
||||
ciphers => "Ciphers",
|
||||
|
@ -263,6 +264,28 @@ to_client_opts_test() ->
|
|||
emqx_tls_lib:to_client_opts(tls, Options#{depth := undefined, password := ""})
|
||||
)
|
||||
)
|
||||
),
|
||||
Expected4 = lists:usort(maps:keys(Options) -- [enable, cacerts]),
|
||||
?assertEqual(
|
||||
Expected4,
|
||||
lists:usort(
|
||||
proplists:get_keys(
|
||||
emqx_tls_lib:to_client_opts(tls, Options#{cacerts := false})
|
||||
)
|
||||
)
|
||||
),
|
||||
emqx_common_test_helpers:with_mock(
|
||||
public_key,
|
||||
cacerts_get,
|
||||
fun() -> ok = {error, enoent} end,
|
||||
fun() ->
|
||||
?assertNot(
|
||||
lists:member(
|
||||
cacerts,
|
||||
proplists:get_keys(emqx_tls_lib:to_client_opts(tls, Options))
|
||||
)
|
||||
)
|
||||
end
|
||||
).
|
||||
|
||||
to_server_opts_test() ->
|
||||
|
|
|
@ -262,6 +262,12 @@ already established connections."""
|
|||
common_ssl_opts_schema_cacertfile.label:
|
||||
"""CACertfile"""
|
||||
|
||||
common_ssl_opts_schema_cacerts.desc:
|
||||
"""When enabled, uses the system trusted CA certificates for establishing to TLS connections."""
|
||||
|
||||
common_ssl_opts_schema_cacerts.label:
|
||||
"""Use System CA Certificates"""
|
||||
|
||||
fields_ws_opts_mqtt_path.desc:
|
||||
"""WebSocket's MQTT protocol path. So the address of EMQX Broker's WebSocket is:
|
||||
<code>ws://{ip}:{port}/mqtt</code>"""
|
||||
|
|
Loading…
Reference in New Issue