From 41239ae76649105f40225ff5430ddb652065f0d4 Mon Sep 17 00:00:00 2001 From: William Yang Date: Wed, 19 Jun 2024 17:03:05 +0200 Subject: [PATCH 1/3] fix(tls): disable partial_chain in hot config --- apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl b/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl index e858920e7..4e64a19a2 100644 --- a/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl +++ b/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl @@ -13,10 +13,13 @@ -include_lib("emqx/include/logger.hrl"). -define(CONST_MOD_V1, emqx_auth_ext_tls_const_v1). -%% @doc enable TLS partial_chain validation if set. +-define(unknown_ca, unknown_ca). +%% @doc enable TLS partial_chain validation -spec opt_partial_chain(SslOpts :: map()) -> NewSslOpts :: map(). opt_partial_chain(#{partial_chain := false} = SslOpts) -> - maps:remove(partial_chain, SslOpts); + %% For config update scenario, we must set it to override + %% the 'existing' partial_chain in the listener + SslOpts#{partial_chain := fun(_) -> ?unknown_ca end}; opt_partial_chain(#{partial_chain := true} = SslOpts) -> SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(1, SslOpts)}; opt_partial_chain(#{partial_chain := cacert_from_cacertfile} = SslOpts) -> From 8d04545f0324ee97c760c676e30129424a70e34f Mon Sep 17 00:00:00 2001 From: William Yang Date: Wed, 19 Jun 2024 17:34:04 +0200 Subject: [PATCH 2/3] test(tls): root_fun is set even when partial_chain is false --- apps/emqx_auth_ext/test/emqx_auth_ext_schema_SUITE.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/emqx_auth_ext/test/emqx_auth_ext_schema_SUITE.erl b/apps/emqx_auth_ext/test/emqx_auth_ext_schema_SUITE.erl index b47f5fa39..4461fada0 100644 --- a/apps/emqx_auth_ext/test/emqx_auth_ext_schema_SUITE.erl +++ b/apps/emqx_auth_ext/test/emqx_auth_ext_schema_SUITE.erl @@ -24,7 +24,7 @@ "\n" " listeners.ssl.auth_ext.bind = 28883\n" " listeners.ssl.auth_ext.enable = true\n" - " listeners.ssl.auth_ext.ssl_options.partial_chain = true\n" + " listeners.ssl.auth_ext.ssl_options.partial_chain = false\n" " listeners.ssl.auth_ext.ssl_options.verify = verify_peer\n" " listeners.ssl.auth_ext.ssl_options.verify_peer_ext_key_usage = \"clientAuth\"\n" " " @@ -62,5 +62,6 @@ t_conf_check_default(_Config) -> t_conf_check_auth_ext(_Config) -> Opts = esockd:get_options({'ssl:auth_ext', 28883}), SSLOpts = proplists:get_value(ssl_options, Opts), + %% Even when partial_chain is set to `false` ?assertMatch(Fun when is_function(Fun), proplists:get_value(partial_chain, SSLOpts)), ?assertMatch({Fun, _} when is_function(Fun), proplists:get_value(verify_fun, SSLOpts)). From 464a0a82f02a13032bbae617544131556915d468 Mon Sep 17 00:00:00 2001 From: William Yang Date: Thu, 20 Jun 2024 11:38:52 +0200 Subject: [PATCH 3/3] fix(tls): move default_root_fun to ?CONST_MOD_V1 --- apps/emqx_auth_ext/src/emqx_auth_ext_tls_const_v1.erl | 10 ++++++++++ apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl | 3 +-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/emqx_auth_ext/src/emqx_auth_ext_tls_const_v1.erl b/apps/emqx_auth_ext/src/emqx_auth_ext_tls_const_v1.erl index ed95b8270..1abc5c2a4 100644 --- a/apps/emqx_auth_ext/src/emqx_auth_ext_tls_const_v1.erl +++ b/apps/emqx_auth_ext/src/emqx_auth_ext_tls_const_v1.erl @@ -10,7 +10,12 @@ make_tls_verify_fun/2 ]). +-export([default_root_fun/1]). + -include_lib("public_key/include/public_key.hrl"). + +-define(unknown_ca, unknown_ca). + %% @doc Build a root fun for verify TLS partial_chain. %% The `InputChain' is composed by OTP SSL with local cert store %% AND the cert (chain if any) from the client. @@ -109,3 +114,8 @@ ext_key_opts(Str) -> end, Usages ). + +%% @doc default root fun for partial_chain 'false' +-spec default_root_fun(_) -> ?unknown_ca. +default_root_fun(_) -> + ?unknown_ca. diff --git a/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl b/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl index 4e64a19a2..a0ddba8fd 100644 --- a/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl +++ b/apps/emqx_auth_ext/src/emqx_auth_ext_tls_lib.erl @@ -13,13 +13,12 @@ -include_lib("emqx/include/logger.hrl"). -define(CONST_MOD_V1, emqx_auth_ext_tls_const_v1). --define(unknown_ca, unknown_ca). %% @doc enable TLS partial_chain validation -spec opt_partial_chain(SslOpts :: map()) -> NewSslOpts :: map(). opt_partial_chain(#{partial_chain := false} = SslOpts) -> %% For config update scenario, we must set it to override %% the 'existing' partial_chain in the listener - SslOpts#{partial_chain := fun(_) -> ?unknown_ca end}; + SslOpts#{partial_chain := fun ?CONST_MOD_V1:default_root_fun/1}; opt_partial_chain(#{partial_chain := true} = SslOpts) -> SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(1, SslOpts)}; opt_partial_chain(#{partial_chain := cacert_from_cacertfile} = SslOpts) ->