Add configurable crl_check and fail_if_no_peer_cert

- Add configuration: crl_check, fail_if_no_peer_cert
- Correct configuration: hostname_verification
This commit is contained in:
Anh Thi Lan Nguyen 2021-12-13 15:27:15 +07:00 committed by Michael Klishin
parent b803f9ea75
commit 0e46c873de
No known key found for this signature in database
GPG Key ID: E80EDCFA0CDB21EE
5 changed files with 50 additions and 20 deletions

View File

@ -151,7 +151,9 @@ NOTE: `jwks_url` takes precedence over `signing_keys` if both are provided.
| `auth_oauth2.https.cacertfile` | Path to a file containing PEM-encoded CA certificates. The CA certificates are used during key server authentication
| `auth_oauth2.https.depth` | Maximum number of non-self-issued intermediate certificates that can follow the peer certificate in a valid certification path. Default is 10. Please see: https://www.erlang.org/doc/man/ssl.html#type-allowed_cert_chain_length for more details
| `auth_oauth2.https.peer_verification` | Identify if the verification should be performed towards key server. Available values: `verify_none`, `verify_peer`. Default is `verify_none`. It is recommended to configure `verify_peer`
| `auth_oauth2.https.wildcard` | Enable wildcard-aware hostname verification for key server. Available values: `true`, `false`. Default is `false`.
| `auth_oauth2.https.fail_if_no_peer_cert` | Used together with `auth_oauth2.https.peer_verification = verify_peer`. If set to `true`, the server fails if the client does not have a certificate to send, that is, sends an empty certificate. If set to `false`, it fails only if the client sends an invalid certificate (an empty certificate is considered valid). Default is `false`.
| `auth_oauth2.https.hostname_verification`| Enable wildcard-aware hostname verification for key server. Available values: `wildcard`, `none`. Default is `none`.
| `auth_oauth2.https.crl_check` | Enable certificate check against the CAs Certificate Revocation List (CRL). Available values: `true`, `false`, `peer`, `best_effort`. Default is `false`. Please refer: https://www.erlang.org/doc/man/ssl.html#type-crl_check for more details
| `auth_oauth2.algorithms` | Restrict the usable algorithms
For example:
@ -173,6 +175,7 @@ auth_oauth2.jwks_url = https://my-jwt-issuer/jwks.json
auth_oauth2.https.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
auth_oauth2.https.peer_verification = verify_peer
auth_oauth2.https.depth = 5
auth_oauth2.https.fail_if_no_peer_cert = true
auth_oauth2.https.wildcard = true
auth_oauth2.algorithms.1 = HS256
auth_oauth2.algorithms.2 = RS256

View File

@ -99,8 +99,18 @@
[{datatype, integer}]}.
{mapping,
"auth_oauth2.https.wildcard",
"rabbitmq_auth_backend_oauth2.key_config.wildcard",
"auth_oauth2.https.hostname_verification",
"rabbitmq_auth_backend_oauth2.key_config.hostname_verification",
[{datatype, {enum, [wildcard, none]}}]}.
{mapping,
"auth_oauth2.https.crl_check",
"rabbitmq_auth_backend_oauth2.key_config.crl_check",
[{datatype, {enum, [true, false, peer, best_effort]}}]}.
{mapping,
"auth_oauth2.https.fail_if_no_peer_cert",
"rabbitmq_auth_backend_oauth2.key_config.fail_if_no_peer_cert",
[{datatype, {enum, [true, false]}}]}.
{validator, "https_uri", "According to the JWT Specification, Key Server URL must be https.",

View File

@ -0,0 +1,27 @@
-module(uaa_jwks).
-export([get/1]).
-spec get(string() | binary()) -> {ok, term()} | {error, term()}.
get(JwksUrl) ->
httpc:request(get, {JwksUrl, []}, [{ssl, ssl_options()}], []).
-spec ssl_options() -> list().
ssl_options() ->
UaaEnv = application:get_env(rabbitmq_auth_backend_oauth2, key_config, []),
PeerVerification = proplists:get_value(peer_verification, UaaEnv, verify_none),
CaCertFile = proplists:get_value(cacertfile, UaaEnv),
Depth = proplists:get_value(depth, UaaEnv, 10),
FailIfNoPeerCert = proplists:get_value(fail_if_no_peer_cert, UaaEnv, false),
CrlCheck = proplists:get_value(crl_check, UaaEnv, false),
SslOpts0 = [{verify, PeerVerification},
{cacertfile, CaCertFile},
{depth, Depth},
{fail_if_no_peer_cert, FailIfNoPeerCert},
{crl_check, CrlCheck},
{crl_cache, {ssl_crl_cache, {internal, [{http, 10000}]}}}],
case proplists:get_value(hostname_verification, UaaEnv, none) of
wildcard ->
[{customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]} | SslOpts0];
none ->
SslOpts0
end.

View File

@ -58,7 +58,7 @@ update_jwks_signing_keys() ->
undefined ->
{error, no_jwks_url};
JwksUrl ->
case httpc:request(get, {JwksUrl, []}, [{ssl, ssl_options()}], []) of
case uaa_jwks:get(JwksUrl) of
{ok, {_, _, JwksBody}} ->
KeyList = maps:get(<<"keys">>, jose:decode(erlang:iolist_to_binary(JwksBody)), []),
Keys = maps:from_list(lists:map(fun(Key) -> {maps:get(<<"kid">>, Key, undefined), {json, Key}} end, KeyList)),
@ -68,20 +68,6 @@ update_jwks_signing_keys() ->
end
end.
-spec ssl_options() -> list().
ssl_options() ->
UaaEnv = application:get_env(?APP, key_config, []),
PeerVerification = proplists:get_value(peer_verification, UaaEnv, verify_none),
CaCertFile = proplists:get_value(cacertfile, UaaEnv),
Depth = proplists:get_value(depth, UaaEnv, 10),
SslOpts0 = [{verify, PeerVerification}, {cacertfile, CaCertFile}, {depth, Depth}],
case proplists:get_value(wildcard, UaaEnv, false) of
true ->
[{customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]} | SslOpts0];
false ->
SslOpts0
end.
-spec decode_and_verify(binary()) -> {boolean(), map()} | {error, term()}.
decode_and_verify(Token) ->
case uaa_jwt_jwt:get_key_id(Token) of

View File

@ -9,7 +9,9 @@
auth_oauth2.https.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
auth_oauth2.https.peer_verification = verify_none
auth_oauth2.https.depth = 5
auth_oauth2.https.wildcard = true
auth_oauth2.https.fail_if_no_peer_cert = false
auth_oauth2.https.hostname_verification = wildcard
auth_oauth2.https.crl_check = true
auth_oauth2.algorithms.1 = HS256
auth_oauth2.algorithms.2 = RS256",
[
@ -28,7 +30,9 @@
{cacertfile, "test/config_schema_SUITE_data/certs/cacert.pem"},
{peer_verification, verify_none},
{depth, 5},
{wildcard, true},
{fail_if_no_peer_cert, false},
{hostname_verification, wildcard},
{crl_check, true},
{algorithms, [<<"HS256">>, <<"RS256">>]}
]
}