1 /******************************************************************************
2 *
3 * Copyright 2019 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include <memory>
23
24 #include "common/testing/wired_pair_of_bidi_queues.h"
25 #include "hci/le_security_interface.h"
26 #include "packet/raw_builder.h"
27 #include "security/pairing_handler_le.h"
28 #include "security/test/mocks.h"
29
30 using namespace std::chrono_literals;
31 using testing::_;
32 using testing::Invoke;
33 using testing::InvokeWithoutArgs;
34 using testing::Matcher;
35 using testing::SaveArg;
36
37 using bluetooth::hci::Address;
38 using bluetooth::hci::AddressType;
39 using bluetooth::hci::CommandCompleteView;
40 using bluetooth::hci::CommandStatusView;
41 using bluetooth::hci::EncryptionChangeBuilder;
42 using bluetooth::hci::EncryptionEnabled;
43 using bluetooth::hci::ErrorCode;
44 using bluetooth::hci::EventBuilder;
45 using bluetooth::hci::EventView;
46 using bluetooth::hci::LeSecurityCommandBuilder;
47
48 // run:
49 // out/host/linux-x86/nativetest/bluetooth_test_gd/bluetooth_test_gd --gtest_filter=Pairing*
50 // adb shell /data/nativetest/bluetooth_test_gd/bluetooth_test_gd --gtest_filter=PairingHandlerPairTest.*
51 // --gtest_repeat=10 --gtest_shuffle
52
53 namespace bluetooth {
54 namespace security {
CommandBuilderToView(std::unique_ptr<BasePacketBuilder> builder)55 CommandView CommandBuilderToView(std::unique_ptr<BasePacketBuilder> builder) {
56 std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
57 BitInserter it(*packet_bytes);
58 builder->Serialize(it);
59 PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
60 auto temp_cmd_view = CommandView::Create(packet_bytes_view);
61 return CommandView::Create(temp_cmd_view);
62 }
63
EventBuilderToView(std::unique_ptr<EventBuilder> builder)64 EventView EventBuilderToView(std::unique_ptr<EventBuilder> builder) {
65 std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
66 BitInserter it(*packet_bytes);
67 builder->Serialize(it);
68 PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
69 auto temp_evt_view = EventView::Create(packet_bytes_view);
70 return EventView::Create(temp_evt_view);
71 }
72 } // namespace security
73 } // namespace bluetooth
74
75 namespace {
76
77 constexpr uint16_t CONN_HANDLE_CENTRAL = 0x31, CONN_HANDLE_PERIPHERAL = 0x32;
78 std::unique_ptr<bluetooth::security::PairingHandlerLe> pairing_handler_a, pairing_handler_b;
79
80 } // namespace
81
82 namespace bluetooth {
83 namespace security {
84
85 namespace {
86 Address ADDRESS_CENTRAL{{0x26, 0x64, 0x76, 0x86, 0xab, 0xba}};
87 AddressType ADDRESS_TYPE_CENTRAL = AddressType::RANDOM_DEVICE_ADDRESS;
88 Address IDENTITY_ADDRESS_CENTRAL{{0x12, 0x34, 0x56, 0x78, 0x90, 0xaa}};
89 AddressType IDENTITY_ADDRESS_TYPE_CENTRAL = AddressType::PUBLIC_DEVICE_ADDRESS;
90 crypto_toolbox::Octet16 IRK_CENTRAL = {
91 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
92
93 Address ADDRESS_PERIPHERAL{{0x33, 0x58, 0x24, 0x76, 0x11, 0x89}};
94 AddressType ADDRESS_TYPE_PERIPHERAL = AddressType::RANDOM_DEVICE_ADDRESS;
95 Address IDENTITY_ADDRESS_PERIPHERAL{{0x21, 0x43, 0x65, 0x87, 0x09, 0x44}};
96 AddressType IDENTITY_ADDRESS_TYPE_PERIPHERAL = AddressType::PUBLIC_DEVICE_ADDRESS;
97 crypto_toolbox::Octet16 IRK_PERIPHERAL = {
98 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
99
100 std::optional<PairingResultOrFailure> pairing_result_central;
101 std::optional<PairingResultOrFailure> pairing_result_peripheral;
102
OnPairingFinishedCentral(PairingResultOrFailure r)103 void OnPairingFinishedCentral(PairingResultOrFailure r) {
104 pairing_result_central = r;
105 if (std::holds_alternative<PairingResult>(r)) {
106 LOG_INFO("pairing finished successfully with %s", std::get<PairingResult>(r).connection_address.ToString().c_str());
107 } else {
108 LOG_INFO("pairing with ... failed: %s", std::get<PairingFailure>(r).message.c_str());
109 }
110 }
111
OnPairingFinishedPeripheral(PairingResultOrFailure r)112 void OnPairingFinishedPeripheral(PairingResultOrFailure r) {
113 pairing_result_peripheral = r;
114 if (std::holds_alternative<PairingResult>(r)) {
115 LOG_INFO("pairing finished successfully with %s", std::get<PairingResult>(r).connection_address.ToString().c_str());
116 } else {
117 LOG_INFO("pairing with ... failed: %s", std::get<PairingFailure>(r).message.c_str());
118 }
119 }
120
121 }; // namespace
122
123 // We obtain this mutex when we start initializing the handlers, and relese it when both handlers are initialized
124 std::mutex handlers_initialization_guard;
125
126 class PairingHandlerPairTest : public testing::Test {
dequeue_callback_central()127 void dequeue_callback_central() {
128 auto packet_bytes_view = l2cap_->GetQueueAUpEnd()->TryDequeue();
129 if (!packet_bytes_view) LOG_ERROR("Received dequeue, but no data ready...");
130
131 auto temp_cmd_view = CommandView::Create(*packet_bytes_view);
132 if (!first_command_sent) {
133 first_command = std::make_unique<CommandView>(CommandView::Create(temp_cmd_view));
134 first_command_sent = true;
135 return;
136 }
137
138 if (!pairing_handler_a) LOG_ALWAYS_FATAL("Peripheral handler not initlized yet!");
139
140 pairing_handler_a->OnCommandView(CommandView::Create(temp_cmd_view));
141 }
142
dequeue_callback_peripheral()143 void dequeue_callback_peripheral() {
144 auto packet_bytes_view = l2cap_->GetQueueBUpEnd()->TryDequeue();
145 if (!packet_bytes_view) LOG_ERROR("Received dequeue, but no data ready...");
146
147 auto temp_cmd_view = CommandView::Create(*packet_bytes_view);
148 if (!first_command_sent) {
149 first_command = std::make_unique<CommandView>(CommandView::Create(temp_cmd_view));
150 first_command_sent = true;
151 return;
152 }
153
154 if (!pairing_handler_b) LOG_ALWAYS_FATAL("Central handler not initlized yet!");
155
156 pairing_handler_b->OnCommandView(CommandView::Create(temp_cmd_view));
157 }
158
159 protected:
SetUp()160 void SetUp() {
161 thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
162 handler_ = new os::Handler(thread_);
163
164 l2cap_ = new common::testing::WiredPairOfL2capQueues(handler_);
165 // central sends it's packet into l2cap->down_buffer_b_
166 // peripheral sends it's packet into l2cap->down_buffer_a_
167 l2cap_->GetQueueAUpEnd()->RegisterDequeue(
168 handler_, common::Bind(&PairingHandlerPairTest::dequeue_callback_central, common::Unretained(this)));
169 l2cap_->GetQueueBUpEnd()->RegisterDequeue(
170 handler_, common::Bind(&PairingHandlerPairTest::dequeue_callback_peripheral, common::Unretained(this)));
171
172 up_buffer_a_ = std::make_unique<os::EnqueueBuffer<packet::BasePacketBuilder>>(l2cap_->GetQueueAUpEnd());
173 up_buffer_b_ = std::make_unique<os::EnqueueBuffer<packet::BasePacketBuilder>>(l2cap_->GetQueueBUpEnd());
174
175 central_setup = {
176 .my_role = hci::Role::CENTRAL,
177 .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
178 .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
179 .my_identity_resolving_key = IRK_CENTRAL,
180
181 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
182 .oob_data_flag = OobDataFlag::NOT_PRESENT,
183 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
184 .maximum_encryption_key_size = 16,
185 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
186 .responder_key_distribution = KeyMaskId | KeyMaskSign},
187
188 .remotely_initiated = false,
189 .connection_handle = CONN_HANDLE_CENTRAL,
190 .remote_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
191 .user_interface = ¢ral_user_interface,
192 .user_interface_handler = handler_,
193 .le_security_interface = ¢ral_le_security_mock,
194 .proper_l2cap_interface = up_buffer_a_.get(),
195 .l2cap_handler = handler_,
196 .OnPairingFinished = OnPairingFinishedCentral,
197 };
198
199 peripheral_setup = {
200 .my_role = hci::Role::PERIPHERAL,
201
202 .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
203 .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
204 .my_identity_resolving_key = IRK_PERIPHERAL,
205
206 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
207 .oob_data_flag = OobDataFlag::NOT_PRESENT,
208 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
209 .maximum_encryption_key_size = 16,
210 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
211 .responder_key_distribution = KeyMaskId | KeyMaskSign},
212 .remotely_initiated = true,
213 .connection_handle = CONN_HANDLE_PERIPHERAL,
214 .remote_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
215 .user_interface = &peripheral_user_interface,
216 .user_interface_handler = handler_,
217 .le_security_interface = &peripheral_le_security_mock,
218 .proper_l2cap_interface = up_buffer_b_.get(),
219 .l2cap_handler = handler_,
220 .OnPairingFinished = OnPairingFinishedPeripheral,
221 };
222
223 RecordSuccessfulEncryptionComplete();
224 }
225
TearDown()226 void TearDown() {
227 ::testing::Mock::VerifyAndClearExpectations(&peripheral_user_interface);
228 ::testing::Mock::VerifyAndClearExpectations(¢ral_user_interface);
229 ::testing::Mock::VerifyAndClearExpectations(&peripheral_le_security_mock);
230 ::testing::Mock::VerifyAndClearExpectations(¢ral_le_security_mock);
231
232 pairing_handler_a.reset();
233 pairing_handler_b.reset();
234 pairing_result_central.reset();
235 pairing_result_peripheral.reset();
236
237 first_command_sent = false;
238 first_command.reset();
239
240 l2cap_->GetQueueAUpEnd()->UnregisterDequeue();
241 l2cap_->GetQueueBUpEnd()->UnregisterDequeue();
242
243 delete l2cap_;
244 handler_->Clear();
245 delete handler_;
246 delete thread_;
247 }
248
RecordPairingPromptHandling(UIMock & ui_mock,std::unique_ptr<PairingHandlerLe> * handler)249 void RecordPairingPromptHandling(UIMock& ui_mock, std::unique_ptr<PairingHandlerLe>* handler) {
250 EXPECT_CALL(ui_mock, DisplayPairingPrompt(_, _)).Times(1).WillOnce(InvokeWithoutArgs([handler]() {
251 LOG_INFO("UI mock received pairing prompt");
252
253 {
254 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
255 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
256 }
257
258 if (!(*handler)) LOG_ALWAYS_FATAL("handler not initalized yet!");
259 // Simulate user accepting the pairing in UI
260 (*handler)->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
261 }));
262 }
263
RecordSuccessfulEncryptionComplete()264 void RecordSuccessfulEncryptionComplete() {
265 // For now, all tests are succeeding to go through Encryption. Record that in the setup.
266 // Once we test failure cases, move this to each test
267 EXPECT_CALL(
268 central_le_security_mock,
269 EnqueueCommand(_, Matcher<common::ContextualOnceCallback<void(CommandStatusView)>>(_)))
270 .Times(1)
271 .WillOnce([](std::unique_ptr<LeSecurityCommandBuilder> command,
272 common::ContextualOnceCallback<void(CommandStatusView)> on_status) {
273 // TODO: on_status.Run();
274
275 pairing_handler_a->OnHciEvent(EventBuilderToView(
276 EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_CENTRAL, EncryptionEnabled::ON)));
277
278 pairing_handler_b->OnHciEvent(EventBuilderToView(
279 hci::LeLongTermKeyRequestBuilder::Create(CONN_HANDLE_PERIPHERAL, {0, 0, 0, 0, 0, 0, 0, 0}, 0)));
280
281 pairing_handler_b->OnHciEvent(EventBuilderToView(
282 EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_PERIPHERAL, EncryptionEnabled::ON)));
283 });
284 }
285
286 public:
WaitFirstL2capCommand()287 std::unique_ptr<bluetooth::security::CommandView> WaitFirstL2capCommand() {
288 while (!first_command_sent) {
289 std::this_thread::sleep_for(1ms);
290 LOG_INFO("waiting for first command...");
291 }
292
293 return std::move(first_command);
294 }
295
296 InitialInformations central_setup;
297 InitialInformations peripheral_setup;
298 UIMock central_user_interface;
299 UIMock peripheral_user_interface;
300 LeSecurityInterfaceMock central_le_security_mock;
301 LeSecurityInterfaceMock peripheral_le_security_mock;
302
303 uint16_t first_command_sent = false;
304 std::unique_ptr<bluetooth::security::CommandView> first_command;
305
306 os::Thread* thread_;
307 os::Handler* handler_;
308 common::testing::WiredPairOfL2capQueues* l2cap_;
309
310 std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> up_buffer_a_;
311 std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> up_buffer_b_;
312 };
313
314 /* This test verifies that Just Works pairing flow works.
315 * Both simulated devices specify capabilities as NO_INPUT_NO_OUTPUT, and secure connecitons support */
TEST_F(PairingHandlerPairTest,test_secure_connections_just_works)316 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works) {
317 central_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
318 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
319 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
320 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
321
322 {
323 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
324
325 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
326
327 auto first_pkt = WaitFirstL2capCommand();
328 peripheral_setup.pairing_request = PairingRequestView::Create(*first_pkt);
329
330 EXPECT_CALL(peripheral_user_interface, DisplayPairingPrompt(_, _)).Times(1).WillOnce(InvokeWithoutArgs([] {
331 LOG_INFO("UI mock received pairing prompt");
332
333 {
334 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
335 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
336 }
337
338 if (!pairing_handler_b) LOG_ALWAYS_FATAL("handler not initalized yet!");
339
340 // Simulate user accepting the pairing in UI
341 pairing_handler_b->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
342 }));
343
344 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
345 }
346
347 pairing_handler_a->WaitUntilPairingFinished();
348 pairing_handler_b->WaitUntilPairingFinished();
349
350 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
351 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
352
353 auto central_result = std::get<PairingResult>(pairing_result_central.value());
354 ASSERT_EQ(central_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_PERIPHERAL);
355 ASSERT_EQ(
356 central_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_PERIPHERAL);
357 ASSERT_EQ(*central_result.distributed_keys.remote_irk, IRK_PERIPHERAL);
358
359 auto peripheral_result = std::get<PairingResult>(pairing_result_peripheral.value());
360 ASSERT_EQ(peripheral_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_CENTRAL);
361 ASSERT_EQ(
362 peripheral_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_CENTRAL);
363 ASSERT_EQ(*peripheral_result.distributed_keys.remote_irk, IRK_CENTRAL);
364 }
365
TEST_F(PairingHandlerPairTest,test_secure_connections_just_works_peripheral_initiated)366 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works_peripheral_initiated) {
367 central_setup = {
368 .my_role = hci::Role::CENTRAL,
369 .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
370 .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
371 .my_identity_resolving_key = IRK_CENTRAL,
372 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
373 .oob_data_flag = OobDataFlag::NOT_PRESENT,
374 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
375 .maximum_encryption_key_size = 16,
376 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
377 .responder_key_distribution = KeyMaskId | KeyMaskSign},
378 .remotely_initiated = true,
379 .connection_handle = CONN_HANDLE_CENTRAL,
380 .remote_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
381 .user_interface = ¢ral_user_interface,
382 .user_interface_handler = handler_,
383 .le_security_interface = ¢ral_le_security_mock,
384 .proper_l2cap_interface = up_buffer_a_.get(),
385 .l2cap_handler = handler_,
386 .OnPairingFinished = OnPairingFinishedCentral,
387 };
388
389 peripheral_setup = {
390 .my_role = hci::Role::PERIPHERAL,
391 .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
392 .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
393 .my_identity_resolving_key = IRK_PERIPHERAL,
394 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
395 .oob_data_flag = OobDataFlag::NOT_PRESENT,
396 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
397 .maximum_encryption_key_size = 16,
398 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
399 .responder_key_distribution = KeyMaskId | KeyMaskSign},
400 .remotely_initiated = false,
401 .connection_handle = CONN_HANDLE_PERIPHERAL,
402 .remote_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
403 .user_interface = &peripheral_user_interface,
404 .user_interface_handler = handler_,
405 .le_security_interface = &peripheral_le_security_mock,
406 .proper_l2cap_interface = up_buffer_b_.get(),
407 .l2cap_handler = handler_,
408 .OnPairingFinished = OnPairingFinishedPeripheral,
409 };
410
411 std::unique_ptr<bluetooth::security::CommandView> first_pkt;
412 {
413 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
414 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
415
416 first_pkt = WaitFirstL2capCommand();
417
418 EXPECT_CALL(central_user_interface, DisplayPairingPrompt(_, _))
419 .Times(1)
420 .WillOnce(InvokeWithoutArgs([&first_pkt, this] {
421 LOG_INFO("UI mock received pairing prompt");
422
423 {
424 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
425 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
426 }
427 if (!pairing_handler_a) LOG_ALWAYS_FATAL("handler not initalized yet!");
428 // Simulate user accepting the pairing in UI
429 pairing_handler_a->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
430
431 // Send the first packet from the peripheral to central
432 auto view_to_packet = std::make_unique<packet::RawBuilder>();
433 view_to_packet->AddOctets(std::vector(first_pkt->begin(), first_pkt->end()));
434 up_buffer_b_->Enqueue(std::move(view_to_packet), handler_);
435 }));
436 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
437 }
438
439 pairing_handler_a->WaitUntilPairingFinished();
440 pairing_handler_b->WaitUntilPairingFinished();
441
442 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
443 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
444 }
445
TEST_F(PairingHandlerPairTest,test_secure_connections_numeric_comparison)446 TEST_F(PairingHandlerPairTest, test_secure_connections_numeric_comparison) {
447 central_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_YES_NO;
448 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
449 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
450
451 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_YES_NO;
452 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
453 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
454
455 ConfirmationData data_peripheral;
456 {
457 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
458 // Initiator must be initialized after the responder.
459 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
460
461 while (!first_command_sent) {
462 std::this_thread::sleep_for(1ms);
463 LOG_INFO("waiting for first command...");
464 }
465 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
466
467 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
468
469 EXPECT_CALL(peripheral_user_interface, DisplayConfirmValue(_)).WillOnce(SaveArg<0>(&data_peripheral));
470 EXPECT_CALL(central_user_interface, DisplayConfirmValue(_)).WillOnce(Invoke([&](ConfirmationData data) {
471 EXPECT_EQ(data_peripheral.GetNumericValue(), data.GetNumericValue());
472 if (data_peripheral.GetNumericValue() == data.GetNumericValue()) {
473 pairing_handler_a->OnUiAction(PairingEvent::CONFIRM_YESNO, 0x01);
474 pairing_handler_b->OnUiAction(PairingEvent::CONFIRM_YESNO, 0x01);
475 }
476 }));
477
478 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
479 }
480 pairing_handler_a->WaitUntilPairingFinished();
481 pairing_handler_b->WaitUntilPairingFinished();
482
483 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
484 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
485 }
486
TEST_F(PairingHandlerPairTest,test_secure_connections_passkey_entry)487 TEST_F(PairingHandlerPairTest, test_secure_connections_passkey_entry) {
488 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
489 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
490 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
491
492 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
493 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
494 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
495
496 // In this test either central or peripheral display the UI prompt first. This variable makes sure both prompts are
497 // displayed before passkey is confirmed. Since both UI handlers are same thread, it's safe.
498 int ui_prompts_count = 0;
499 uint32_t passkey_ = std::numeric_limits<uint32_t>::max();
500 {
501 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
502 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
503
504 while (!first_command_sent) {
505 std::this_thread::sleep_for(1ms);
506 LOG_INFO("waiting for first command...");
507 }
508 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
509
510 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
511
512 EXPECT_CALL(peripheral_user_interface, DisplayPasskey(_)).WillOnce(Invoke([&](ConfirmationData data) {
513 passkey_ = data.GetNumericValue();
514 ui_prompts_count++;
515 if (ui_prompts_count == 2) {
516 pairing_handler_a->OnUiAction(PairingEvent::PASSKEY, passkey_);
517 }
518 }));
519
520 EXPECT_CALL(central_user_interface, DisplayEnterPasskeyDialog(_)).WillOnce(Invoke([&](ConfirmationData data) {
521 ui_prompts_count++;
522 if (ui_prompts_count == 2) {
523 pairing_handler_a->OnUiAction(PairingEvent::PASSKEY, passkey_);
524 }
525 }));
526
527 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
528 }
529 // Initiator must be initialized after the responder.
530 pairing_handler_a->WaitUntilPairingFinished();
531 pairing_handler_b->WaitUntilPairingFinished();
532
533 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
534 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
535 }
536
TEST_F(PairingHandlerPairTest,test_secure_connections_out_of_band)537 TEST_F(PairingHandlerPairTest, test_secure_connections_out_of_band) {
538 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
539 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
540 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
541
542 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
543 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
544 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
545
546 central_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
547 peripheral_setup.remote_oob_data =
548 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
549 .le_sc_c = central_setup.my_oob_data->c,
550 .le_sc_r = central_setup.my_oob_data->r,
551 });
552
553 {
554 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
555 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
556 while (!first_command_sent) {
557 std::this_thread::sleep_for(1ms);
558 LOG_INFO("waiting for first command...");
559 }
560 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
561
562 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
563
564 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
565 }
566 pairing_handler_a->WaitUntilPairingFinished();
567 pairing_handler_b->WaitUntilPairingFinished();
568
569 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
570 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
571 }
572
TEST_F(PairingHandlerPairTest,test_secure_connections_out_of_band_two_way)573 TEST_F(PairingHandlerPairTest, test_secure_connections_out_of_band_two_way) {
574 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
575 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
576 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
577
578 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
579 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
580 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
581
582 central_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
583 peripheral_setup.remote_oob_data =
584 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
585 .le_sc_c = central_setup.my_oob_data->c,
586 .le_sc_r = central_setup.my_oob_data->r,
587 });
588
589 peripheral_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
590 central_setup.remote_oob_data =
591 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
592 .le_sc_c = peripheral_setup.my_oob_data->c,
593 .le_sc_r = peripheral_setup.my_oob_data->r,
594 });
595
596 {
597 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
598 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
599 while (!first_command_sent) {
600 std::this_thread::sleep_for(1ms);
601 LOG_INFO("waiting for first command...");
602 }
603 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
604
605 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
606
607 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
608 }
609 pairing_handler_a->WaitUntilPairingFinished();
610 pairing_handler_b->WaitUntilPairingFinished();
611
612 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
613 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
614 }
615
TEST_F(PairingHandlerPairTest,test_legacy_just_works)616 TEST_F(PairingHandlerPairTest, test_legacy_just_works) {
617 central_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
618 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
619 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm,
620
621 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
622 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
623 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm;
624
625 {
626 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
627 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
628 while (!first_command_sent) {
629 std::this_thread::sleep_for(1ms);
630 LOG_INFO("waiting for first command...");
631 }
632 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
633
634 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
635
636 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
637 }
638 pairing_handler_a->WaitUntilPairingFinished();
639 pairing_handler_b->WaitUntilPairingFinished();
640
641 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
642 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
643 }
644
TEST_F(PairingHandlerPairTest,test_legacy_passkey_entry)645 TEST_F(PairingHandlerPairTest, test_legacy_passkey_entry) {
646 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_DISPLAY;
647 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
648 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm,
649
650 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
651 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
652 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm;
653
654 {
655 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
656 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
657 while (!first_command_sent) {
658 std::this_thread::sleep_for(1ms);
659 LOG_INFO("waiting for first command...");
660 }
661 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
662
663 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
664
665 EXPECT_CALL(peripheral_user_interface, DisplayEnterPasskeyDialog(_));
666 EXPECT_CALL(central_user_interface, DisplayConfirmValue(_)).WillOnce(Invoke([&](ConfirmationData data) {
667 LOG_INFO("Passkey prompt displayed entering passkey: %08x", data.GetNumericValue());
668 std::this_thread::sleep_for(1ms);
669
670 // TODO: handle case where prompts are displayed in different order in the test!
671 pairing_handler_b->OnUiAction(PairingEvent::PASSKEY, data.GetNumericValue());
672 }));
673
674 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
675 }
676 pairing_handler_a->WaitUntilPairingFinished();
677 pairing_handler_b->WaitUntilPairingFinished();
678
679 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
680 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
681 }
682
683 } // namespace security
684 } // namespace bluetooth
685