diff --git a/deps/rabbitmq_auth_backend_oauth2/src/Elixir.RabbitMQ.CLI.Ctl.Commands.AddUaaKeyCommand.erl b/deps/rabbitmq_auth_backend_oauth2/src/Elixir.RabbitMQ.CLI.Ctl.Commands.AddUaaKeyCommand.erl index 615a03a066..420d251e1d 100644 --- a/deps/rabbitmq_auth_backend_oauth2/src/Elixir.RabbitMQ.CLI.Ctl.Commands.AddUaaKeyCommand.erl +++ b/deps/rabbitmq_auth_backend_oauth2/src/Elixir.RabbitMQ.CLI.Ctl.Commands.AddUaaKeyCommand.erl @@ -44,19 +44,30 @@ validate([_], Options) -> validat_json(Json) -> case rabbit_json:try_decode(Json) of - {ok, _} -> ok; - error -> {validation_failure, {bad_argument, "Invalid JSON"}} + {ok, _} -> + case 'Elixir.UaaJWT':verify_signing_key(json, Json) of + ok -> ok; + {error, unknown_kty} -> + {validation_failure, + {bad_argument, <<"JSON key should contain \"kty\" field">>}}; + {error, Err} -> + {validation_failure, {bad_argument, Err}} + end; + error -> + {validation_failure, {bad_argument, <<"Invalid JSON">>}} end. validate_pem_file(Pem) -> - {ok, PemBin} = file:read_file(Pem), - case public_key:pem_decode(PemBin) of - [] -> {validation_failure, "Unable to read certificate from PEM file"}; - [_] -> ok; - _ -> {validation_failure, "PEM file should contain a single key"} + case 'Elixir.UaaJWT':verify_signing_key(pem, Pem) of + ok -> ok; + {error, enoent} -> + {validation_failure, {bad_argument, <<"PEM file not found">>}}; + {error, invalid_pem_file} -> + {validation_failure, <<"Unable to read a key from the PEM file">>}; + {error, Err} -> + {validation_failure, Err} end. - merge_defaults(Args, #{pem := FileName} = Options) -> AbsFileName = filename:absname(FileName), {Args, Options#{pem := AbsFileName}}; diff --git a/deps/rabbitmq_auth_backend_oauth2/test/add_uaa_key_command_SUITE.erl b/deps/rabbitmq_auth_backend_oauth2/test/add_uaa_key_command_SUITE.erl new file mode 100644 index 0000000000..6c9ffc3671 --- /dev/null +++ b/deps/rabbitmq_auth_backend_oauth2/test/add_uaa_key_command_SUITE.erl @@ -0,0 +1,55 @@ +-module(add_uaa_key_command_SUITE). + +-compile(export_all). + +-include_lib("rabbit_common/include/rabbit.hrl"). +-include_lib("common_test/include/ct.hrl"). + +-define(COMMAND, 'Elixir.RabbitMQ.CLI.Ctl.Commands.AddUaaKeyCommand'). + +all() -> + [validate_arguments, + validate_json_key, + validate_pem_key + ]. + + +init_per_suite(Config) -> + rabbit_ct_helpers:run_setup_steps(Config, []). + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config, []). + + +validate_arguments(_) -> + {validation_failure, {bad_argument, too_many_args}} = + ?COMMAND:validate([<<"one">>, <<"two">>], #{json => <<"{}">>}), + {validation_failure, {bad_argument, not_enough_args}} = + ?COMMAND:validate([], #{json => <<"{}">>}), + {validation_failure, {bad_argument, <<"No key specified">>}} = + ?COMMAND:validate([<<"foo">>], #{}), + {validation_failure, {bad_argument, <<"Key type should be either json or pem">>}} = + ?COMMAND:validate([<<"foo">>], , #{json => <<"{}">>, pem => "/tmp/key.pem"}). + +validate_json_key(_) -> + {validation_failure, {bad_argument, <<"Invalid JSON">>}} = + ?COMMAND:validate([<<"foo">>, #{json => <<"foobar">>}]), + {validation_failure, {bad_argument, <<"JSON key should contain \"kty\" field">>}} = + ?COMMAND:validate([<<"foo">>, #{json => <<"{}">>}]), + {validation_failure, {bad_argument, _}} = + ?COMMAND:validate([<<"foo">>, #{json => <<"{\"kty\": \"oct\"}">>}]), + VlidJson = <<"{\"alg\":\"HS256\",\"k\":\"dG9rZW5rZXk\",\"kid\":\"token-key\",\"kty\":\"oct\",\"use\":\"sig\",\"value\":\"tokenkey\"}">>, + ok = ?COMMAND:validate([<<"foo">>], #{json => ValidJson}). + +validate_pem_key(_) -> + {validation_failure, {bad_argument, <<"PEM file not found">>}} = + ?COMMAND:validate([<<"foo">>], #{pem => <<"non_existent_file">>}), + file:write_file("empty.pem", <<"">>), + {validation_failure, <<"Unable to read a key from the PEM file">>} = + ?COMMAND:validate([<<"foo">>], #{pem => <<"empty.pem">>}), + file:write_file("not_pem.pem", <<"">>), + {validation_failure, _} = + ?COMMAND:validate([<<"foo">>], #{pem => <<"not_pem.pem">>}), + Keyfile = filename:join([CertsDir, "client", "key.pem"]), + ok = ?COMMAND:validate([<<"foo">>], #{pem => Keyfile}). +