blob: 7dba2d677be0d0aba1b6f966586856aafa931dc1 [file] [log] [blame]
Jun Choi4fc8b7812018-04-05 07:39:071// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <memory>
6#include <utility>
7
8#include "base/test/scoped_task_environment.h"
9#include "device/fido/authenticator_get_assertion_response.h"
10#include "device/fido/ctap_get_assertion_request.h"
11#include "device/fido/fake_fido_discovery.h"
12#include "device/fido/fido_constants.h"
Jun Choi19b944e92018-04-23 20:20:2013#include "device/fido/fido_parsing_utils.h"
Jun Choi22af8b372018-04-09 04:29:1814#include "device/fido/fido_test_data.h"
Jun Choib60937e2018-04-12 17:02:3815#include "device/fido/fido_transport_protocol.h"
Jun Choi4fc8b7812018-04-05 07:39:0716#include "device/fido/get_assertion_request_handler.h"
17#include "device/fido/mock_fido_device.h"
18#include "device/fido/test_callback_receiver.h"
Jun Choi4fc8b7812018-04-05 07:39:0719#include "testing/gmock/include/gmock/gmock.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22namespace device {
23
24namespace {
25
26constexpr uint8_t kClientDataHash[] = {0x01, 0x02, 0x03};
Jun Choi23bef1a2018-04-18 19:49:4227constexpr char kRpId[] = "acme.com";
Jun Choi4fc8b7812018-04-05 07:39:0728
Jun Choif7ab0df2018-04-05 21:48:1629using TestGetAssertionRequestCallback = test::StatusAndValueCallbackReceiver<
30 FidoReturnCode,
31 base::Optional<AuthenticatorGetAssertionResponse>>;
Jun Choi4fc8b7812018-04-05 07:39:0732
33} // namespace
34
35class FidoGetAssertionHandlerTest : public ::testing::Test {
36 public:
37 void ForgeNextHidDiscovery() {
38 discovery_ = scoped_fake_discovery_factory_.ForgeNextHidDiscovery();
39 }
40
41 std::unique_ptr<GetAssertionRequestHandler> CreateGetAssertionHandler() {
42 ForgeNextHidDiscovery();
43
44 CtapGetAssertionRequest request_param(
Jun Choi19b944e92018-04-23 20:20:2045 kRpId, fido_parsing_utils::Materialize(kClientDataHash));
Jun Choi4fc8b7812018-04-05 07:39:0746 request_param.SetAllowList(
Jan Wilken Doerrie726e197e2018-05-14 12:53:2547 {{CredentialType::kPublicKey,
Jun Choi19b944e92018-04-23 20:20:2048 fido_parsing_utils::Materialize(
Jun Choif7be8a72018-04-07 02:59:3249 test_data::kTestGetAssertionCredentialId)}});
Jun Choi4fc8b7812018-04-05 07:39:0750
51 return std::make_unique<GetAssertionRequestHandler>(
52 nullptr /* connector */,
Jun Choib60937e2018-04-12 17:02:3853 base::flat_set<FidoTransportProtocol>(
54 {FidoTransportProtocol::kUsbHumanInterfaceDevice}),
Jun Choi4fc8b7812018-04-05 07:39:0755 std::move(request_param), get_assertion_cb_.callback());
56 }
57
58 test::FakeFidoDiscovery* discovery() const { return discovery_; }
59
60 TestGetAssertionRequestCallback& get_assertion_callback() {
61 return get_assertion_cb_;
62 }
63
64 protected:
65 base::test::ScopedTaskEnvironment scoped_task_environment_{
66 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME};
67 test::ScopedFakeFidoDiscoveryFactory scoped_fake_discovery_factory_;
68 test::FakeFidoDiscovery* discovery_;
69 TestGetAssertionRequestCallback get_assertion_cb_;
70};
71
72TEST_F(FidoGetAssertionHandlerTest, TestGetAssertionRequestOnSingleDevice) {
73 auto request_handler = CreateGetAssertionHandler();
74 discovery()->WaitForCallToStartAndSimulateSuccess();
75 auto device = std::make_unique<MockFidoDevice>();
76
77 EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
78 device->ExpectCtap2CommandAndRespondWith(
79 CtapRequestCommand::kAuthenticatorGetInfo,
80 test_data::kTestAuthenticatorGetInfoResponse);
81 device->ExpectCtap2CommandAndRespondWith(
82 CtapRequestCommand::kAuthenticatorGetAssertion,
83 test_data::kTestGetAssertionResponse);
84
85 discovery()->AddDevice(std::move(device));
86 get_assertion_callback().WaitForCallback();
87
88 EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
89 EXPECT_TRUE(get_assertion_callback().value());
90 EXPECT_TRUE(request_handler->is_complete());
91}
92
93// Test a scenario where the connected authenticator is a U2F device. Request
94// be silently dropped and request should remain in incomplete state.
95TEST_F(FidoGetAssertionHandlerTest, TestGetAssertionIncorrectGetInfoResponse) {
96 auto request_handler = CreateGetAssertionHandler();
97 discovery()->WaitForCallToStartAndSimulateSuccess();
98
99 auto device = std::make_unique<MockFidoDevice>();
100 EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
101 device->ExpectCtap2CommandAndRespondWith(
102 CtapRequestCommand::kAuthenticatorGetInfo, base::nullopt);
103
104 discovery()->AddDevice(std::move(device));
105 scoped_task_environment_.FastForwardUntilNoTasksRemain();
106 EXPECT_FALSE(request_handler->is_complete());
107}
108
109} // namespace device