Commit 9a9f7aa1 authored by Casey Piper's avatar Casey Piper Committed by Commit Bot

Handle input size error codes when evaluating key handles

Some security keys will respond with the length of the key handle
as an error response instead of an ISO7816 error code. Handle
these errors by treating them as an invalid length error so
further key handles can still be evaluated.

Bug: 898008
Change-Id: I9d604c2012b7eb452e6476e8ced38e51ebd316d4
Reviewed-on: https://chromium-review.googlesource.com/c/1296050
Commit-Queue: Casey Piper <piperc@chromium.org>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#602039}
parent b83d06cf
......@@ -377,6 +377,8 @@ constexpr uint8_t kU2fConditionNotSatisfiedApduResponse[] = {0x69, 0x85};
constexpr uint8_t kU2fWrongDataApduResponse[] = {0x6A, 0x80};
constexpr uint8_t kU2fKeyHandleSizeApduResponse[] = {0x00, 0x01};
constexpr uint8_t kApduEncodedNoErrorRegisterResponse[] = {
// Reserved byte
0x05,
......
......@@ -137,6 +137,11 @@ void U2fSignOperation::OnCheckForKeyHandlePresence(
auto return_code = apdu_response ? apdu_response->status()
: apdu::ApduResponse::Status::SW_WRONG_DATA;
// Older U2F devices may respond with the length of the input as an error
// response if the length is unexpected.
if (return_code == static_cast<apdu::ApduResponse::Status>(it->id().size()))
return_code = apdu::ApduResponse::Status::SW_WRONG_LENGTH;
switch (return_code) {
case apdu::ApduResponse::Status::SW_NO_ERROR:
case apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED: {
......
......@@ -198,6 +198,41 @@ TEST_F(U2fSignOperationTest, MultipleHandles) {
::testing::ElementsAreArray(test_data::kU2fSignKeyHandle));
}
TEST_F(U2fSignOperationTest, MultipleHandlesLengthError) {
// One wrong key that responds with key handle length followed by a correct
// key.
auto request = CreateSignRequest(
{fido_parsing_utils::Materialize(test_data::kKeyHandleAlpha),
fido_parsing_utils::Materialize(test_data::kU2fSignKeyHandle)});
auto device = std::make_unique<MockFidoDevice>();
EXPECT_CALL(*device, GetId()).WillRepeatedly(::testing::Return("device"));
InSequence s;
// Wrong key would respond with the key handle length.
device->ExpectRequestAndRespondWith(
test_data::kU2fCheckOnlySignCommandApduWithKeyAlpha,
test_data::kU2fKeyHandleSizeApduResponse);
device->ExpectRequestAndRespondWith(
test_data::kU2fCheckOnlySignCommandApdu,
test_data::kApduEncodedNoErrorSignResponse);
device->ExpectRequestAndRespondWith(
test_data::kU2fSignCommandApdu,
test_data::kApduEncodedNoErrorSignResponse);
auto u2f_sign = std::make_unique<U2fSignOperation>(
device.get(), std::move(request), sign_callback_receiver().callback());
u2f_sign->Start();
sign_callback_receiver().WaitForCallback();
EXPECT_EQ(CtapDeviceResponseCode::kSuccess,
sign_callback_receiver().status());
EXPECT_THAT(sign_callback_receiver().value()->signature(),
::testing::ElementsAreArray(test_data::kU2fSignature));
EXPECT_THAT(sign_callback_receiver().value()->raw_credential_id(),
::testing::ElementsAreArray(test_data::kU2fSignKeyHandle));
}
// Test that Fake U2F registration is invoked when no credentials in the allowed
// list are recognized by the device.
TEST_F(U2fSignOperationTest, FakeEnroll) {
......
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