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(
107 "pairing finished successfully with %s",
108 ADDRESS_TO_LOGGABLE_CSTR(std::get<PairingResult>(r).connection_address));
109 } else {
110 LOG_INFO("pairing with ... failed: %s", std::get<PairingFailure>(r).message.c_str());
111 }
112 }
113
OnPairingFinishedPeripheral(PairingResultOrFailure r)114 void OnPairingFinishedPeripheral(PairingResultOrFailure r) {
115 pairing_result_peripheral = r;
116 if (std::holds_alternative<PairingResult>(r)) {
117 LOG_INFO(
118 "pairing finished successfully with %s",
119 ADDRESS_TO_LOGGABLE_CSTR(std::get<PairingResult>(r).connection_address));
120 } else {
121 LOG_INFO("pairing with ... failed: %s", std::get<PairingFailure>(r).message.c_str());
122 }
123 }
124
125 }; // namespace
126
127 // We obtain this mutex when we start initializing the handlers, and relese it when both handlers are initialized
128 std::mutex handlers_initialization_guard;
129
130 class PairingHandlerPairTest : public testing::Test {
dequeue_callback_central()131 void dequeue_callback_central() {
132 auto packet_bytes_view = l2cap_->GetQueueAUpEnd()->TryDequeue();
133 if (!packet_bytes_view) LOG_ERROR("Received dequeue, but no data ready...");
134
135 auto temp_cmd_view = CommandView::Create(*packet_bytes_view);
136 if (!first_command_sent) {
137 first_command = std::make_unique<CommandView>(CommandView::Create(temp_cmd_view));
138 first_command_sent = true;
139 return;
140 }
141
142 if (!pairing_handler_a) LOG_ALWAYS_FATAL("Peripheral handler not initlized yet!");
143
144 pairing_handler_a->OnCommandView(CommandView::Create(temp_cmd_view));
145 }
146
dequeue_callback_peripheral()147 void dequeue_callback_peripheral() {
148 auto packet_bytes_view = l2cap_->GetQueueBUpEnd()->TryDequeue();
149 if (!packet_bytes_view) LOG_ERROR("Received dequeue, but no data ready...");
150
151 auto temp_cmd_view = CommandView::Create(*packet_bytes_view);
152 if (!first_command_sent) {
153 first_command = std::make_unique<CommandView>(CommandView::Create(temp_cmd_view));
154 first_command_sent = true;
155 return;
156 }
157
158 if (!pairing_handler_b) LOG_ALWAYS_FATAL("Central handler not initlized yet!");
159
160 pairing_handler_b->OnCommandView(CommandView::Create(temp_cmd_view));
161 }
162
163 protected:
SetUp()164 void SetUp() {
165 thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
166 handler_ = new os::Handler(thread_);
167
168 l2cap_ = new common::testing::WiredPairOfL2capQueues(handler_);
169 // central sends it's packet into l2cap->down_buffer_b_
170 // peripheral sends it's packet into l2cap->down_buffer_a_
171 l2cap_->GetQueueAUpEnd()->RegisterDequeue(
172 handler_, common::Bind(&PairingHandlerPairTest::dequeue_callback_central, common::Unretained(this)));
173 l2cap_->GetQueueBUpEnd()->RegisterDequeue(
174 handler_, common::Bind(&PairingHandlerPairTest::dequeue_callback_peripheral, common::Unretained(this)));
175
176 up_buffer_a_ = std::make_unique<os::EnqueueBuffer<packet::BasePacketBuilder>>(l2cap_->GetQueueAUpEnd());
177 up_buffer_b_ = std::make_unique<os::EnqueueBuffer<packet::BasePacketBuilder>>(l2cap_->GetQueueBUpEnd());
178
179 central_setup = {
180 .my_role = hci::Role::CENTRAL,
181 .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
182 .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
183 .my_identity_resolving_key = IRK_CENTRAL,
184
185 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
186 .oob_data_flag = OobDataFlag::NOT_PRESENT,
187 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
188 .maximum_encryption_key_size = 16,
189 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
190 .responder_key_distribution = KeyMaskId | KeyMaskSign},
191
192 .remotely_initiated = false,
193 .connection_handle = CONN_HANDLE_CENTRAL,
194 .remote_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
195 .user_interface = ¢ral_user_interface,
196 .user_interface_handler = handler_,
197 .le_security_interface = ¢ral_le_security_mock,
198 .proper_l2cap_interface = up_buffer_a_.get(),
199 .l2cap_handler = handler_,
200 .OnPairingFinished = OnPairingFinishedCentral,
201 };
202
203 peripheral_setup = {
204 .my_role = hci::Role::PERIPHERAL,
205
206 .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
207 .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
208 .my_identity_resolving_key = IRK_PERIPHERAL,
209
210 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
211 .oob_data_flag = OobDataFlag::NOT_PRESENT,
212 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
213 .maximum_encryption_key_size = 16,
214 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
215 .responder_key_distribution = KeyMaskId | KeyMaskSign},
216 .remotely_initiated = true,
217 .connection_handle = CONN_HANDLE_PERIPHERAL,
218 .remote_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
219 .user_interface = &peripheral_user_interface,
220 .user_interface_handler = handler_,
221 .le_security_interface = &peripheral_le_security_mock,
222 .proper_l2cap_interface = up_buffer_b_.get(),
223 .l2cap_handler = handler_,
224 .OnPairingFinished = OnPairingFinishedPeripheral,
225 };
226
227 RecordSuccessfulEncryptionComplete();
228 }
229
TearDown()230 void TearDown() {
231 ::testing::Mock::VerifyAndClearExpectations(&peripheral_user_interface);
232 ::testing::Mock::VerifyAndClearExpectations(¢ral_user_interface);
233 ::testing::Mock::VerifyAndClearExpectations(&peripheral_le_security_mock);
234 ::testing::Mock::VerifyAndClearExpectations(¢ral_le_security_mock);
235
236 pairing_handler_a.reset();
237 pairing_handler_b.reset();
238 pairing_result_central.reset();
239 pairing_result_peripheral.reset();
240
241 first_command_sent = false;
242 first_command.reset();
243
244 l2cap_->GetQueueAUpEnd()->UnregisterDequeue();
245 l2cap_->GetQueueBUpEnd()->UnregisterDequeue();
246
247 delete l2cap_;
248 handler_->Clear();
249 delete handler_;
250 delete thread_;
251 }
252
RecordPairingPromptHandling(UIMock & ui_mock,std::unique_ptr<PairingHandlerLe> * handler)253 void RecordPairingPromptHandling(UIMock& ui_mock, std::unique_ptr<PairingHandlerLe>* handler) {
254 EXPECT_CALL(ui_mock, DisplayPairingPrompt(_, _)).Times(1).WillOnce(InvokeWithoutArgs([handler]() {
255 LOG_INFO("UI mock received pairing prompt");
256
257 {
258 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
259 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
260 }
261
262 if (!(*handler)) LOG_ALWAYS_FATAL("handler not initalized yet!");
263 // Simulate user accepting the pairing in UI
264 (*handler)->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
265 }));
266 }
267
RecordSuccessfulEncryptionComplete()268 void RecordSuccessfulEncryptionComplete() {
269 // For now, all tests are succeeding to go through Encryption. Record that in the setup.
270 // Once we test failure cases, move this to each test
271 EXPECT_CALL(
272 central_le_security_mock,
273 EnqueueCommand(_, Matcher<common::ContextualOnceCallback<void(CommandStatusView)>>(_)))
274 .Times(1)
275 .WillOnce([](std::unique_ptr<LeSecurityCommandBuilder> command,
276 common::ContextualOnceCallback<void(CommandStatusView)> on_status) {
277 // TODO: on_status.Run();
278
279 pairing_handler_a->OnHciEvent(EventBuilderToView(
280 EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_CENTRAL, EncryptionEnabled::ON)));
281
282 pairing_handler_b->OnHciEvent(EventBuilderToView(
283 hci::LeLongTermKeyRequestBuilder::Create(CONN_HANDLE_PERIPHERAL, {0, 0, 0, 0, 0, 0, 0, 0}, 0)));
284
285 pairing_handler_b->OnHciEvent(EventBuilderToView(
286 EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_PERIPHERAL, EncryptionEnabled::ON)));
287 });
288 }
289
290 public:
WaitFirstL2capCommand()291 std::unique_ptr<bluetooth::security::CommandView> WaitFirstL2capCommand() {
292 while (!first_command_sent) {
293 std::this_thread::sleep_for(1ms);
294 LOG_INFO("waiting for first command...");
295 }
296
297 return std::move(first_command);
298 }
299
300 InitialInformations central_setup;
301 InitialInformations peripheral_setup;
302 UIMock central_user_interface;
303 UIMock peripheral_user_interface;
304 LeSecurityInterfaceMock central_le_security_mock;
305 LeSecurityInterfaceMock peripheral_le_security_mock;
306
307 uint16_t first_command_sent = false;
308 std::unique_ptr<bluetooth::security::CommandView> first_command;
309
310 os::Thread* thread_;
311 os::Handler* handler_;
312 common::testing::WiredPairOfL2capQueues* l2cap_;
313
314 std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> up_buffer_a_;
315 std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> up_buffer_b_;
316 };
317
318 /* This test verifies that Just Works pairing flow works.
319 * Both simulated devices specify capabilities as NO_INPUT_NO_OUTPUT, and secure connecitons support */
TEST_F(PairingHandlerPairTest,test_secure_connections_just_works)320 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works) {
321 central_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
322 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
323 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
324 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
325
326 {
327 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
328
329 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
330
331 auto first_pkt = WaitFirstL2capCommand();
332 peripheral_setup.pairing_request = PairingRequestView::Create(*first_pkt);
333
334 EXPECT_CALL(peripheral_user_interface, DisplayPairingPrompt(_, _)).Times(1).WillOnce(InvokeWithoutArgs([] {
335 LOG_INFO("UI mock received pairing prompt");
336
337 {
338 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
339 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
340 }
341
342 if (!pairing_handler_b) LOG_ALWAYS_FATAL("handler not initalized yet!");
343
344 // Simulate user accepting the pairing in UI
345 pairing_handler_b->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
346 }));
347
348 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
349 }
350
351 pairing_handler_a->WaitUntilPairingFinished();
352 pairing_handler_b->WaitUntilPairingFinished();
353
354 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
355 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
356
357 auto central_result = std::get<PairingResult>(pairing_result_central.value());
358 ASSERT_EQ(central_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_PERIPHERAL);
359 ASSERT_EQ(
360 central_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_PERIPHERAL);
361 ASSERT_EQ(*central_result.distributed_keys.remote_irk, IRK_PERIPHERAL);
362
363 auto peripheral_result = std::get<PairingResult>(pairing_result_peripheral.value());
364 ASSERT_EQ(peripheral_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_CENTRAL);
365 ASSERT_EQ(
366 peripheral_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_CENTRAL);
367 ASSERT_EQ(*peripheral_result.distributed_keys.remote_irk, IRK_CENTRAL);
368 }
369
TEST_F(PairingHandlerPairTest,test_secure_connections_just_works_peripheral_initiated)370 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works_peripheral_initiated) {
371 central_setup = {
372 .my_role = hci::Role::CENTRAL,
373 .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
374 .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
375 .my_identity_resolving_key = IRK_CENTRAL,
376 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
377 .oob_data_flag = OobDataFlag::NOT_PRESENT,
378 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
379 .maximum_encryption_key_size = 16,
380 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
381 .responder_key_distribution = KeyMaskId | KeyMaskSign},
382 .remotely_initiated = true,
383 .connection_handle = CONN_HANDLE_CENTRAL,
384 .remote_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
385 .user_interface = ¢ral_user_interface,
386 .user_interface_handler = handler_,
387 .le_security_interface = ¢ral_le_security_mock,
388 .proper_l2cap_interface = up_buffer_a_.get(),
389 .l2cap_handler = handler_,
390 .OnPairingFinished = OnPairingFinishedCentral,
391 };
392
393 peripheral_setup = {
394 .my_role = hci::Role::PERIPHERAL,
395 .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
396 .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
397 .my_identity_resolving_key = IRK_PERIPHERAL,
398 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
399 .oob_data_flag = OobDataFlag::NOT_PRESENT,
400 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
401 .maximum_encryption_key_size = 16,
402 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
403 .responder_key_distribution = KeyMaskId | KeyMaskSign},
404 .remotely_initiated = false,
405 .connection_handle = CONN_HANDLE_PERIPHERAL,
406 .remote_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
407 .user_interface = &peripheral_user_interface,
408 .user_interface_handler = handler_,
409 .le_security_interface = &peripheral_le_security_mock,
410 .proper_l2cap_interface = up_buffer_b_.get(),
411 .l2cap_handler = handler_,
412 .OnPairingFinished = OnPairingFinishedPeripheral,
413 };
414
415 std::unique_ptr<bluetooth::security::CommandView> first_pkt;
416 {
417 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
418 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
419
420 first_pkt = WaitFirstL2capCommand();
421
422 EXPECT_CALL(central_user_interface, DisplayPairingPrompt(_, _))
423 .Times(1)
424 .WillOnce(InvokeWithoutArgs([&first_pkt, this] {
425 LOG_INFO("UI mock received pairing prompt");
426
427 {
428 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
429 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
430 }
431 if (!pairing_handler_a) LOG_ALWAYS_FATAL("handler not initalized yet!");
432 // Simulate user accepting the pairing in UI
433 pairing_handler_a->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
434
435 // Send the first packet from the peripheral to central
436 auto view_to_packet = std::make_unique<packet::RawBuilder>();
437 view_to_packet->AddOctets(std::vector(first_pkt->begin(), first_pkt->end()));
438 up_buffer_b_->Enqueue(std::move(view_to_packet), handler_);
439 }));
440 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
441 }
442
443 pairing_handler_a->WaitUntilPairingFinished();
444 pairing_handler_b->WaitUntilPairingFinished();
445
446 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
447 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
448 }
449
TEST_F(PairingHandlerPairTest,test_secure_connections_numeric_comparison)450 TEST_F(PairingHandlerPairTest, test_secure_connections_numeric_comparison) {
451 central_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_YES_NO;
452 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
453 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
454
455 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_YES_NO;
456 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
457 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
458
459 ConfirmationData data_peripheral;
460 {
461 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
462 // Initiator must be initialized after the responder.
463 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
464
465 while (!first_command_sent) {
466 std::this_thread::sleep_for(1ms);
467 LOG_INFO("waiting for first command...");
468 }
469 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
470
471 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
472
473 EXPECT_CALL(peripheral_user_interface, DisplayConfirmValue(_)).WillOnce(SaveArg<0>(&data_peripheral));
474 EXPECT_CALL(central_user_interface, DisplayConfirmValue(_)).WillOnce(Invoke([&](ConfirmationData data) {
475 EXPECT_EQ(data_peripheral.GetNumericValue(), data.GetNumericValue());
476 if (data_peripheral.GetNumericValue() == data.GetNumericValue()) {
477 pairing_handler_a->OnUiAction(PairingEvent::CONFIRM_YESNO, 0x01);
478 pairing_handler_b->OnUiAction(PairingEvent::CONFIRM_YESNO, 0x01);
479 }
480 }));
481
482 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
483 }
484 pairing_handler_a->WaitUntilPairingFinished();
485 pairing_handler_b->WaitUntilPairingFinished();
486
487 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
488 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
489 }
490
TEST_F(PairingHandlerPairTest,test_secure_connections_passkey_entry)491 TEST_F(PairingHandlerPairTest, test_secure_connections_passkey_entry) {
492 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
493 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
494 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
495
496 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
497 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
498 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
499
500 // In this test either central or peripheral display the UI prompt first. This variable makes sure both prompts are
501 // displayed before passkey is confirmed. Since both UI handlers are same thread, it's safe.
502 int ui_prompts_count = 0;
503 uint32_t passkey_ = std::numeric_limits<uint32_t>::max();
504 {
505 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
506 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
507
508 while (!first_command_sent) {
509 std::this_thread::sleep_for(1ms);
510 LOG_INFO("waiting for first command...");
511 }
512 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
513
514 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
515
516 EXPECT_CALL(peripheral_user_interface, DisplayPasskey(_)).WillOnce(Invoke([&](ConfirmationData data) {
517 passkey_ = data.GetNumericValue();
518 ui_prompts_count++;
519 if (ui_prompts_count == 2) {
520 pairing_handler_a->OnUiAction(PairingEvent::PASSKEY, passkey_);
521 }
522 }));
523
524 EXPECT_CALL(central_user_interface, DisplayEnterPasskeyDialog(_)).WillOnce(Invoke([&](ConfirmationData data) {
525 ui_prompts_count++;
526 if (ui_prompts_count == 2) {
527 pairing_handler_a->OnUiAction(PairingEvent::PASSKEY, passkey_);
528 }
529 }));
530
531 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
532 }
533 // Initiator must be initialized after the responder.
534 pairing_handler_a->WaitUntilPairingFinished();
535 pairing_handler_b->WaitUntilPairingFinished();
536
537 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
538 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
539 }
540
TEST_F(PairingHandlerPairTest,test_secure_connections_out_of_band)541 TEST_F(PairingHandlerPairTest, test_secure_connections_out_of_band) {
542 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
543 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
544 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
545
546 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
547 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
548 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
549
550 central_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
551 peripheral_setup.remote_oob_data =
552 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
553 .le_sc_c = central_setup.my_oob_data->c,
554 .le_sc_r = central_setup.my_oob_data->r,
555 });
556
557 {
558 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
559 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
560 while (!first_command_sent) {
561 std::this_thread::sleep_for(1ms);
562 LOG_INFO("waiting for first command...");
563 }
564 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
565
566 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
567
568 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
569 }
570 pairing_handler_a->WaitUntilPairingFinished();
571 pairing_handler_b->WaitUntilPairingFinished();
572
573 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
574 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
575 }
576
TEST_F(PairingHandlerPairTest,test_secure_connections_out_of_band_two_way)577 TEST_F(PairingHandlerPairTest, test_secure_connections_out_of_band_two_way) {
578 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
579 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
580 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
581
582 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
583 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
584 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
585
586 central_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
587 peripheral_setup.remote_oob_data =
588 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
589 .le_sc_c = central_setup.my_oob_data->c,
590 .le_sc_r = central_setup.my_oob_data->r,
591 });
592
593 peripheral_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
594 central_setup.remote_oob_data =
595 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
596 .le_sc_c = peripheral_setup.my_oob_data->c,
597 .le_sc_r = peripheral_setup.my_oob_data->r,
598 });
599
600 {
601 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
602 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
603 while (!first_command_sent) {
604 std::this_thread::sleep_for(1ms);
605 LOG_INFO("waiting for first command...");
606 }
607 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
608
609 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
610
611 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
612 }
613 pairing_handler_a->WaitUntilPairingFinished();
614 pairing_handler_b->WaitUntilPairingFinished();
615
616 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
617 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
618 }
619
TEST_F(PairingHandlerPairTest,test_legacy_just_works)620 TEST_F(PairingHandlerPairTest, test_legacy_just_works) {
621 central_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
622 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
623 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm,
624
625 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
626 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
627 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm;
628
629 {
630 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
631 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
632 while (!first_command_sent) {
633 std::this_thread::sleep_for(1ms);
634 LOG_INFO("waiting for first command...");
635 }
636 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
637
638 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
639
640 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
641 }
642 pairing_handler_a->WaitUntilPairingFinished();
643 pairing_handler_b->WaitUntilPairingFinished();
644
645 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
646 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
647 }
648
TEST_F(PairingHandlerPairTest,test_legacy_passkey_entry)649 TEST_F(PairingHandlerPairTest, test_legacy_passkey_entry) {
650 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_DISPLAY;
651 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
652 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm,
653
654 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
655 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
656 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm;
657
658 {
659 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
660 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
661 while (!first_command_sent) {
662 std::this_thread::sleep_for(1ms);
663 LOG_INFO("waiting for first command...");
664 }
665 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
666
667 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
668
669 EXPECT_CALL(peripheral_user_interface, DisplayEnterPasskeyDialog(_));
670 EXPECT_CALL(central_user_interface, DisplayConfirmValue(_)).WillOnce(Invoke([&](ConfirmationData data) {
671 LOG_INFO("Passkey prompt displayed entering passkey: %08x", data.GetNumericValue());
672 std::this_thread::sleep_for(1ms);
673
674 // TODO: handle case where prompts are displayed in different order in the test!
675 pairing_handler_b->OnUiAction(PairingEvent::PASSKEY, data.GetNumericValue());
676 }));
677
678 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
679 }
680 pairing_handler_a->WaitUntilPairingFinished();
681 pairing_handler_b->WaitUntilPairingFinished();
682
683 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
684 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
685 }
686
687 } // namespace security
688 } // namespace bluetooth
689