blob: 5399484af4fc0bcf0c914ea0e336003c4e090c4f [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
Jun Choi0e56e5dd2018-06-08 21:27:348#include "base/test/scoped_feature_list.h"
Jun Choi4fc8b7812018-04-05 07:39:079#include "base/test/scoped_task_environment.h"
Jun Choi0e56e5dd2018-06-08 21:27:3410#include "device/base/features.h"
Jun Choi4fc8b7812018-04-05 07:39:0711#include "device/fido/authenticator_get_assertion_response.h"
12#include "device/fido/ctap_get_assertion_request.h"
13#include "device/fido/fake_fido_discovery.h"
14#include "device/fido/fido_constants.h"
Jun Choi19b944e92018-04-23 20:20:2015#include "device/fido/fido_parsing_utils.h"
Jun Choi22af8b372018-04-09 04:29:1816#include "device/fido/fido_test_data.h"
Jun Choib60937e2018-04-12 17:02:3817#include "device/fido/fido_transport_protocol.h"
Jun Choi4fc8b7812018-04-05 07:39:0718#include "device/fido/get_assertion_request_handler.h"
19#include "device/fido/mock_fido_device.h"
20#include "device/fido/test_callback_receiver.h"
Jun Choi4fc8b7812018-04-05 07:39:0721#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace device {
25
26namespace {
27
Jun Choif7ab0df2018-04-05 21:48:1628using TestGetAssertionRequestCallback = test::StatusAndValueCallbackReceiver<
29 FidoReturnCode,
30 base::Optional<AuthenticatorGetAssertionResponse>>;
Jun Choi4fc8b7812018-04-05 07:39:0731
32} // namespace
33
34class FidoGetAssertionHandlerTest : public ::testing::Test {
35 public:
36 void ForgeNextHidDiscovery() {
37 discovery_ = scoped_fake_discovery_factory_.ForgeNextHidDiscovery();
38 }
39
40 std::unique_ptr<GetAssertionRequestHandler> CreateGetAssertionHandler() {
41 ForgeNextHidDiscovery();
42
43 CtapGetAssertionRequest request_param(
Jun Choi03ba9b32018-05-25 18:33:3944 test_data::kRelyingPartyId,
45 fido_parsing_utils::Materialize(test_data::kClientDataHash));
Jun Choi4fc8b7812018-04-05 07:39:0746 request_param.SetAllowList(
Jan Wilken Doerrie726e197e2018-05-14 12:53:2547 {{CredentialType::kPublicKey,
Jun Choi0e56e5dd2018-06-08 21:27:3448 fido_parsing_utils::Materialize(test_data::kU2fSignKeyHandle)}});
Jun Choi4fc8b7812018-04-05 07:39:0749
50 return std::make_unique<GetAssertionRequestHandler>(
51 nullptr /* connector */,
Jun Choib60937e2018-04-12 17:02:3852 base::flat_set<FidoTransportProtocol>(
53 {FidoTransportProtocol::kUsbHumanInterfaceDevice}),
Jun Choi4fc8b7812018-04-05 07:39:0754 std::move(request_param), get_assertion_cb_.callback());
55 }
56
Jun Choi0e56e5dd2018-06-08 21:27:3457 void InitFeatureListWithCtapFlag() {
58 scoped_feature_list_.InitAndEnableFeature(kNewCtap2Device);
59 }
Jun Choi4fc8b7812018-04-05 07:39:0760
Jun Choi0e56e5dd2018-06-08 21:27:3461 test::FakeFidoDiscovery* discovery() const { return discovery_; }
Jun Choi4fc8b7812018-04-05 07:39:0762 TestGetAssertionRequestCallback& get_assertion_callback() {
63 return get_assertion_cb_;
64 }
65
66 protected:
67 base::test::ScopedTaskEnvironment scoped_task_environment_{
68 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME};
Jun Choi0e56e5dd2018-06-08 21:27:3469 base::test::ScopedFeatureList scoped_feature_list_;
Jun Choi4fc8b7812018-04-05 07:39:0770 test::ScopedFakeFidoDiscoveryFactory scoped_fake_discovery_factory_;
71 test::FakeFidoDiscovery* discovery_;
72 TestGetAssertionRequestCallback get_assertion_cb_;
73};
74
75TEST_F(FidoGetAssertionHandlerTest, TestGetAssertionRequestOnSingleDevice) {
Jun Choi0e56e5dd2018-06-08 21:27:3476 InitFeatureListWithCtapFlag();
Jun Choi4fc8b7812018-04-05 07:39:0777 auto request_handler = CreateGetAssertionHandler();
78 discovery()->WaitForCallToStartAndSimulateSuccess();
79 auto device = std::make_unique<MockFidoDevice>();
80
81 EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
82 device->ExpectCtap2CommandAndRespondWith(
83 CtapRequestCommand::kAuthenticatorGetInfo,
84 test_data::kTestAuthenticatorGetInfoResponse);
85 device->ExpectCtap2CommandAndRespondWith(
86 CtapRequestCommand::kAuthenticatorGetAssertion,
87 test_data::kTestGetAssertionResponse);
88
89 discovery()->AddDevice(std::move(device));
90 get_assertion_callback().WaitForCallback();
91
92 EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
93 EXPECT_TRUE(get_assertion_callback().value());
94 EXPECT_TRUE(request_handler->is_complete());
95}
96
Jun Choi0e56e5dd2018-06-08 21:27:3497// Test a scenario where the connected authenticator is a U2F device.
98TEST_F(FidoGetAssertionHandlerTest, TestU2fSign) {
99 InitFeatureListWithCtapFlag();
Jun Choi4fc8b7812018-04-05 07:39:07100 auto request_handler = CreateGetAssertionHandler();
101 discovery()->WaitForCallToStartAndSimulateSuccess();
102
103 auto device = std::make_unique<MockFidoDevice>();
104 EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
105 device->ExpectCtap2CommandAndRespondWith(
106 CtapRequestCommand::kAuthenticatorGetInfo, base::nullopt);
Jun Choi0e56e5dd2018-06-08 21:27:34107 device->ExpectRequestAndRespondWith(
108 test_data::kU2fCheckOnlySignCommandApdu,
109 test_data::kApduEncodedNoErrorSignResponse);
110 device->ExpectRequestAndRespondWith(
111 test_data::kU2fSignCommandApdu,
112 test_data::kApduEncodedNoErrorSignResponse);
Jun Choi4fc8b7812018-04-05 07:39:07113
114 discovery()->AddDevice(std::move(device));
115 scoped_task_environment_.FastForwardUntilNoTasksRemain();
Jun Choi0e56e5dd2018-06-08 21:27:34116 EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
117 EXPECT_TRUE(get_assertion_callback().value());
118 EXPECT_TRUE(request_handler->is_complete());
119}
120
121// Test a scenario where the connected authenticator is a U2F device and
122// "WebAuthenticationCtap2" flag is not enabled.
123TEST_F(FidoGetAssertionHandlerTest, TestU2fSignWithoutCtapFlag) {
124 auto request_handler = CreateGetAssertionHandler();
125 discovery()->WaitForCallToStartAndSimulateSuccess();
126
127 auto device = std::make_unique<MockFidoDevice>();
128 EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
129 device->ExpectRequestAndRespondWith(
130 test_data::kU2fCheckOnlySignCommandApdu,
131 test_data::kApduEncodedNoErrorSignResponse);
132 device->ExpectRequestAndRespondWith(
133 test_data::kU2fSignCommandApdu,
134 test_data::kApduEncodedNoErrorSignResponse);
135
136 discovery()->AddDevice(std::move(device));
137 scoped_task_environment_.FastForwardUntilNoTasksRemain();
138 EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
139 EXPECT_TRUE(get_assertion_callback().value());
140 EXPECT_TRUE(request_handler->is_complete());
Jun Choi4fc8b7812018-04-05 07:39:07141}
142
143} // namespace device