blob: 70cade80893f13cb293e34eb8d4688af020c705d [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/fido/credential_management_handler.h"
#include "base/bind.h"
#include "base/test/scoped_task_environment.h"
#include "device/fido/credential_management.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_request_handler_base.h"
#include "device/fido/scoped_virtual_fido_device.h"
#include "device/fido/test_callback_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace device {
namespace {
using test::ScopedVirtualFidoDevice;
constexpr char kPIN[] = "1234";
constexpr uint8_t kCredentialID[] = {0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa};
constexpr char kRPID[] = "example.com";
constexpr uint8_t kUserID[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
constexpr char kUserName[] = "alice@example.com";
constexpr char kUserDisplayName[] = "Alice Example <alice@example.com>";
class TestObserver : public FidoRequestHandlerBase::Observer {
public:
TestObserver() {}
~TestObserver() override {}
private:
// FidoRequestHandlerBase::Observer:
void OnTransportAvailabilityEnumerated(
FidoRequestHandlerBase::TransportAvailabilityInfo data) override {}
bool EmbedderControlsAuthenticatorDispatch(
const FidoAuthenticator&) override {
return false;
}
void BluetoothAdapterPowerChanged(bool is_powered_on) override {}
void FidoAuthenticatorAdded(const FidoAuthenticator& authenticator) override {
}
void FidoAuthenticatorRemoved(base::StringPiece device_id) override {}
void FidoAuthenticatorIdChanged(base::StringPiece old_authenticator_id,
std::string new_authenticator_id) override {}
void FidoAuthenticatorPairingModeChanged(base::StringPiece authenticator_id,
bool is_in_pairing_mode) override {}
bool SupportsPIN() const override { return true; }
void CollectPIN(
base::Optional<int> attempts,
base::OnceCallback<void(std::string)> provide_pin_cb) override {
std::move(provide_pin_cb).Run(kPIN);
}
void FinishCollectPIN() override {}
void SetMightCreateResidentCredential(bool v) override {}
};
class TestDelegate : public CredentialManagementHandler::Delegate {
public:
TestDelegate() {}
~TestDelegate() {}
test::StatusAndValuesCallbackReceiver<CtapDeviceResponseCode, size_t, size_t>
on_credential_metadata;
test::StatusAndValuesCallbackReceiver<
std::vector<AggregatedEnumerateCredentialsResponse>>
on_credentials_enumerated;
test::ValueCallbackReceiver<FidoReturnCode> on_error;
private:
// CredentialManagementHandler::Delegate
void OnCredentialMetadata(size_t num_existing,
size_t num_remaining) override {
on_credential_metadata.callback().Run(CtapDeviceResponseCode::kSuccess,
num_existing, num_remaining);
}
void OnCredentialsEnumerated(
std::vector<AggregatedEnumerateCredentialsResponse> credentials)
override {
on_credentials_enumerated.callback().Run(std::move(credentials));
}
void OnError(FidoReturnCode error) override {
on_error.callback().Run(error);
}
};
TEST(CredentialManagementHandlerTest, Test) {
base::test::ScopedTaskEnvironment scoped_task_environment(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
ScopedVirtualFidoDevice virtual_device;
VirtualCtap2Device::Config ctap_config;
ctap_config.pin_support = true;
ctap_config.resident_key_support = true;
ctap_config.credential_management_support = true;
ctap_config.resident_credential_storage = 100;
virtual_device.SetCtap2Config(ctap_config);
virtual_device.SetSupportedProtocol(device::ProtocolVersion::kCtap);
virtual_device.mutable_state()->pin = kPIN;
virtual_device.mutable_state()->retries = 8;
ASSERT_TRUE(virtual_device.mutable_state()->InjectResidentKey(
kCredentialID, kRPID, kUserID, kUserName, kUserDisplayName));
TestDelegate delegate;
CredentialManagementHandler handler(
/*connector=*/nullptr, {FidoTransportProtocol::kUsbHumanInterfaceDevice},
&delegate);
TestObserver observer;
handler.set_observer(&observer);
scoped_task_environment.FastForwardUntilNoTasksRemain();
EXPECT_FALSE(delegate.on_error.was_called())
<< "error " << static_cast<int>(delegate.on_error.value());
EXPECT_TRUE(delegate.on_credential_metadata.was_called());
EXPECT_EQ(delegate.on_credential_metadata.value<0>(), 1u);
EXPECT_EQ(delegate.on_credential_metadata.value<1>(), 99u);
// TODO(martinkr): This should be true but is not yet implemented.
EXPECT_FALSE(delegate.on_credentials_enumerated.was_called());
}
} // namespace
} // namespace device