Commit efd3551e authored by Nina Satragno's avatar Nina Satragno Committed by Commit Bot

[webauthn] Handle CTAP2_ERR_PIN_AUTH_INVALID

According to the CTAP2 spec, devices may return
CTAP2_ERR_PIN_AUTH_INVALID if internal User Verification fails on
MakeCredential requests or if the PIN token is not valid on either
MakeCredential or GetAssertion requests. This patch handles this code
treating it as a permission denied error.

Bug: 974876
Change-Id: I7565b17a98bb4cc46da086c5412be8b19b7b269d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1661486Reviewed-by: default avatarAdam Langley <agl@chromium.org>
Commit-Queue: Nina Satragno <nsatragno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#669834}
parent 329bb5b4
......@@ -89,6 +89,12 @@ class FidoRequestHandler : public FidoRequestHandlerBase {
case CtapDeviceResponseCode::kCtap2ErrOperationDenied:
return FidoReturnCode::kUserConsentDenied;
// External authenticators may return this error if internal user
// verification fails for a make credential request or if the pin token is
// not valid.
case CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid:
return FidoReturnCode::kUserConsentDenied;
case CtapDeviceResponseCode::kCtap2ErrKeyStoreFull:
return FidoReturnCode::kStorageFull;
......
......@@ -722,6 +722,24 @@ TEST_F(FidoGetAssertionHandlerTest,
get_assertion_callback().status());
}
// If a device returns CTAP2_ERR_PIN_AUTH_INVALID, the request should complete
// with FidoReturnCode::kUserConsentDenied.
TEST_F(FidoGetAssertionHandlerTest, TestRequestWithPinAuthInvalid) {
auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation();
device->ExpectCtap2CommandAndRespondWithError(
CtapRequestCommand::kAuthenticatorGetAssertion,
CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid);
auto request_handler = CreateGetAssertionHandlerCtap();
discovery()->WaitForCallToStartAndSimulateSuccess();
discovery()->AddDevice(std::move(device));
scoped_task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_TRUE(get_assertion_callback().was_called());
EXPECT_EQ(FidoReturnCode::kUserConsentDenied,
get_assertion_callback().status());
}
MATCHER_P(IsCtap2Command, expected_command, "") {
return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command);
}
......
......@@ -684,6 +684,28 @@ TEST_F(FidoMakeCredentialHandlerTest,
EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status());
}
// If a device returns CTAP2_ERR_PIN_AUTH_INVALID, the request should complete
// with FidoReturnCode::kUserConsentDenied.
TEST_F(FidoMakeCredentialHandlerTest, TestRequestWithPinAuthInvalid) {
auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation();
device->ExpectCtap2CommandAndRespondWithError(
CtapRequestCommand::kAuthenticatorMakeCredential,
CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid);
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorAttachment::kAny, /*require_resident_key=*/false,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
discovery()->AddDevice(std::move(device));
scoped_task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_TRUE(callback().was_called());
EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status());
}
MATCHER_P(IsCtap2Command, expected_command, "") {
return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment