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 <bluetooth/log.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include <memory>
24
25 #include "common/testing/wired_pair_of_bidi_queues.h"
26 #include "hci/le_security_interface.h"
27 #include "hci/octets.h"
28 #include "packet/raw_builder.h"
29 #include "security/pairing_handler_le.h"
30 #include "security/test/mocks.h"
31
32 using namespace std::chrono_literals;
33 using testing::_;
34 using testing::Invoke;
35 using testing::InvokeWithoutArgs;
36 using testing::Matcher;
37 using testing::SaveArg;
38
39 using bluetooth::hci::Address;
40 using bluetooth::hci::AddressType;
41 using bluetooth::hci::CommandCompleteView;
42 using bluetooth::hci::CommandStatusView;
43 using bluetooth::hci::EncryptionChangeBuilder;
44 using bluetooth::hci::EncryptionEnabled;
45 using bluetooth::hci::ErrorCode;
46 using bluetooth::hci::EventBuilder;
47 using bluetooth::hci::EventView;
48 using bluetooth::hci::LeSecurityCommandBuilder;
49
50 // run:
51 // out/host/linux-x86/nativetest/bluetooth_test_gd/bluetooth_test_gd --gtest_filter=Pairing*
52 // adb shell /data/nativetest/bluetooth_test_gd/bluetooth_test_gd --gtest_filter=PairingHandlerPairTest.*
53 // --gtest_repeat=10 --gtest_shuffle
54
55 namespace bluetooth {
56 namespace security {
CommandBuilderToView(std::unique_ptr<BasePacketBuilder> builder)57 CommandView CommandBuilderToView(std::unique_ptr<BasePacketBuilder> builder) {
58 std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
59 BitInserter it(*packet_bytes);
60 builder->Serialize(it);
61 PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
62 auto temp_cmd_view = CommandView::Create(packet_bytes_view);
63 return CommandView::Create(temp_cmd_view);
64 }
65
EventBuilderToView(std::unique_ptr<EventBuilder> builder)66 EventView EventBuilderToView(std::unique_ptr<EventBuilder> builder) {
67 std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
68 BitInserter it(*packet_bytes);
69 builder->Serialize(it);
70 PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
71 auto temp_evt_view = EventView::Create(packet_bytes_view);
72 return EventView::Create(temp_evt_view);
73 }
74 } // namespace security
75 } // namespace bluetooth
76
77 namespace {
78
79 constexpr uint16_t CONN_HANDLE_CENTRAL = 0x31, CONN_HANDLE_PERIPHERAL = 0x32;
80 std::unique_ptr<bluetooth::security::PairingHandlerLe> pairing_handler_a, pairing_handler_b;
81
82 } // namespace
83
84 namespace bluetooth {
85 namespace security {
86
87 namespace {
88 Address ADDRESS_CENTRAL{{0x26, 0x64, 0x76, 0x86, 0xab, 0xba}};
89 AddressType ADDRESS_TYPE_CENTRAL = AddressType::RANDOM_DEVICE_ADDRESS;
90 Address IDENTITY_ADDRESS_CENTRAL{{0x12, 0x34, 0x56, 0x78, 0x90, 0xaa}};
91 AddressType IDENTITY_ADDRESS_TYPE_CENTRAL = AddressType::PUBLIC_DEVICE_ADDRESS;
92 hci::Octet16 IRK_CENTRAL = {
93 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
94
95 Address ADDRESS_PERIPHERAL{{0x33, 0x58, 0x24, 0x76, 0x11, 0x89}};
96 AddressType ADDRESS_TYPE_PERIPHERAL = AddressType::RANDOM_DEVICE_ADDRESS;
97 Address IDENTITY_ADDRESS_PERIPHERAL{{0x21, 0x43, 0x65, 0x87, 0x09, 0x44}};
98 AddressType IDENTITY_ADDRESS_TYPE_PERIPHERAL = AddressType::PUBLIC_DEVICE_ADDRESS;
99 hci::Octet16 IRK_PERIPHERAL = {
100 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
101
102 std::optional<PairingResultOrFailure> pairing_result_central;
103 std::optional<PairingResultOrFailure> pairing_result_peripheral;
104
OnPairingFinishedCentral(PairingResultOrFailure r)105 void OnPairingFinishedCentral(PairingResultOrFailure r) {
106 pairing_result_central = r;
107 if (std::holds_alternative<PairingResult>(r)) {
108 log::info(
109 "pairing finished successfully with {}", std::get<PairingResult>(r).connection_address);
110 } else {
111 log::info("pairing with ... failed: {}", std::get<PairingFailure>(r).message);
112 }
113 }
114
OnPairingFinishedPeripheral(PairingResultOrFailure r)115 void OnPairingFinishedPeripheral(PairingResultOrFailure r) {
116 pairing_result_peripheral = r;
117 if (std::holds_alternative<PairingResult>(r)) {
118 log::info(
119 "pairing finished successfully with {}", std::get<PairingResult>(r).connection_address);
120 } else {
121 log::info("pairing with ... failed: {}", std::get<PairingFailure>(r).message);
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::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::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(_, _))
255 .Times(1)
256 .WillOnce(InvokeWithoutArgs([handler]() {
257 log::info("UI mock received pairing prompt");
258
259 {
260 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
261 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
262 }
263
264 if (!(*handler)) log::fatal("handler not initalized yet!");
265 // Simulate user accepting the pairing in UI
266 (*handler)->OnUiAction(
267 PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
268 }));
269 }
270
RecordSuccessfulEncryptionComplete()271 void RecordSuccessfulEncryptionComplete() {
272 // For now, all tests are succeeding to go through Encryption. Record that in the setup.
273 // Once we test failure cases, move this to each test
274 EXPECT_CALL(
275 central_le_security_mock,
276 EnqueueCommand(_, Matcher<common::ContextualOnceCallback<void(CommandStatusView)>>(_)))
277 .Times(1)
278 .WillOnce([](std::unique_ptr<LeSecurityCommandBuilder> command,
279 common::ContextualOnceCallback<void(CommandStatusView)> on_status) {
280 // TODO: on_status.Run();
281
282 pairing_handler_a->OnHciEvent(EventBuilderToView(
283 EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_CENTRAL, EncryptionEnabled::ON)));
284
285 pairing_handler_b->OnHciEvent(EventBuilderToView(
286 hci::LeLongTermKeyRequestBuilder::Create(CONN_HANDLE_PERIPHERAL, {0, 0, 0, 0, 0, 0, 0, 0}, 0)));
287
288 pairing_handler_b->OnHciEvent(EventBuilderToView(
289 EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_PERIPHERAL, EncryptionEnabled::ON)));
290 });
291 }
292
293 public:
WaitFirstL2capCommand()294 std::unique_ptr<bluetooth::security::CommandView> WaitFirstL2capCommand() {
295 while (!first_command_sent) {
296 std::this_thread::sleep_for(1ms);
297 log::info("waiting for first command...");
298 }
299
300 return std::move(first_command);
301 }
302
303 InitialInformations central_setup;
304 InitialInformations peripheral_setup;
305 UIMock central_user_interface;
306 UIMock peripheral_user_interface;
307 LeSecurityInterfaceMock central_le_security_mock;
308 LeSecurityInterfaceMock peripheral_le_security_mock;
309
310 uint16_t first_command_sent = false;
311 std::unique_ptr<bluetooth::security::CommandView> first_command;
312
313 os::Thread* thread_;
314 os::Handler* handler_;
315 common::testing::WiredPairOfL2capQueues* l2cap_;
316
317 std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> up_buffer_a_;
318 std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> up_buffer_b_;
319 };
320
321 /* This test verifies that Just Works pairing flow works.
322 * Both simulated devices specify capabilities as NO_INPUT_NO_OUTPUT, and secure connecitons support */
TEST_F(PairingHandlerPairTest,test_secure_connections_just_works)323 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works) {
324 central_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
325 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
326 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
327 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
328
329 {
330 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
331
332 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
333
334 auto first_pkt = WaitFirstL2capCommand();
335 peripheral_setup.pairing_request = PairingRequestView::Create(*first_pkt);
336
337 EXPECT_CALL(peripheral_user_interface, DisplayPairingPrompt(_, _))
338 .Times(1)
339 .WillOnce(InvokeWithoutArgs([] {
340 log::info("UI mock received pairing prompt");
341
342 {
343 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
344 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
345 }
346
347 if (!pairing_handler_b) log::fatal("handler not initalized yet!");
348
349 // Simulate user accepting the pairing in UI
350 pairing_handler_b->OnUiAction(
351 PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
352 }));
353
354 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
355 }
356
357 pairing_handler_a->WaitUntilPairingFinished();
358 pairing_handler_b->WaitUntilPairingFinished();
359
360 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
361 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
362
363 auto central_result = std::get<PairingResult>(pairing_result_central.value());
364 ASSERT_EQ(central_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_PERIPHERAL);
365 ASSERT_EQ(
366 central_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_PERIPHERAL);
367 ASSERT_EQ(*central_result.distributed_keys.remote_irk, IRK_PERIPHERAL);
368
369 auto peripheral_result = std::get<PairingResult>(pairing_result_peripheral.value());
370 ASSERT_EQ(peripheral_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_CENTRAL);
371 ASSERT_EQ(
372 peripheral_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_CENTRAL);
373 ASSERT_EQ(*peripheral_result.distributed_keys.remote_irk, IRK_CENTRAL);
374 }
375
TEST_F(PairingHandlerPairTest,test_secure_connections_just_works_peripheral_initiated)376 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works_peripheral_initiated) {
377 central_setup = {
378 .my_role = hci::Role::CENTRAL,
379 .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
380 .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
381 .my_identity_resolving_key = IRK_CENTRAL,
382 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
383 .oob_data_flag = OobDataFlag::NOT_PRESENT,
384 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
385 .maximum_encryption_key_size = 16,
386 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
387 .responder_key_distribution = KeyMaskId | KeyMaskSign},
388 .remotely_initiated = true,
389 .connection_handle = CONN_HANDLE_CENTRAL,
390 .remote_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
391 .user_interface = ¢ral_user_interface,
392 .user_interface_handler = handler_,
393 .le_security_interface = ¢ral_le_security_mock,
394 .proper_l2cap_interface = up_buffer_a_.get(),
395 .l2cap_handler = handler_,
396 .OnPairingFinished = OnPairingFinishedCentral,
397 };
398
399 peripheral_setup = {
400 .my_role = hci::Role::PERIPHERAL,
401 .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
402 .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
403 .my_identity_resolving_key = IRK_PERIPHERAL,
404 .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
405 .oob_data_flag = OobDataFlag::NOT_PRESENT,
406 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
407 .maximum_encryption_key_size = 16,
408 .initiator_key_distribution = KeyMaskId | KeyMaskSign,
409 .responder_key_distribution = KeyMaskId | KeyMaskSign},
410 .remotely_initiated = false,
411 .connection_handle = CONN_HANDLE_PERIPHERAL,
412 .remote_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
413 .user_interface = &peripheral_user_interface,
414 .user_interface_handler = handler_,
415 .le_security_interface = &peripheral_le_security_mock,
416 .proper_l2cap_interface = up_buffer_b_.get(),
417 .l2cap_handler = handler_,
418 .OnPairingFinished = OnPairingFinishedPeripheral,
419 };
420
421 std::unique_ptr<bluetooth::security::CommandView> first_pkt;
422 {
423 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
424 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
425
426 first_pkt = WaitFirstL2capCommand();
427
428 EXPECT_CALL(central_user_interface, DisplayPairingPrompt(_, _))
429 .Times(1)
430 .WillOnce(InvokeWithoutArgs([&first_pkt, this] {
431 log::info("UI mock received pairing prompt");
432
433 {
434 // By grabbing the lock, we ensure initialization of both pairing handlers is finished.
435 std::lock_guard<std::mutex> lock(handlers_initialization_guard);
436 }
437 if (!pairing_handler_a) log::fatal("handler not initalized yet!");
438 // Simulate user accepting the pairing in UI
439 pairing_handler_a->OnUiAction(PairingEvent::PAIRING_ACCEPTED, 0x01 /* Non-zero value means success */);
440
441 // Send the first packet from the peripheral to central
442 auto view_to_packet = std::make_unique<packet::RawBuilder>();
443 view_to_packet->AddOctets(std::vector(first_pkt->begin(), first_pkt->end()));
444 up_buffer_b_->Enqueue(std::move(view_to_packet), handler_);
445 }));
446 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
447 }
448
449 pairing_handler_a->WaitUntilPairingFinished();
450 pairing_handler_b->WaitUntilPairingFinished();
451
452 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
453 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
454 }
455
TEST_F(PairingHandlerPairTest,test_secure_connections_numeric_comparison)456 TEST_F(PairingHandlerPairTest, test_secure_connections_numeric_comparison) {
457 central_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_YES_NO;
458 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
459 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
460
461 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_YES_NO;
462 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
463 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
464
465 ConfirmationData data_peripheral;
466 {
467 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
468 // Initiator must be initialized after the responder.
469 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
470
471 while (!first_command_sent) {
472 std::this_thread::sleep_for(1ms);
473 log::info("waiting for first command...");
474 }
475 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
476
477 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
478
479 EXPECT_CALL(peripheral_user_interface, DisplayConfirmValue(_)).WillOnce(SaveArg<0>(&data_peripheral));
480 EXPECT_CALL(central_user_interface, DisplayConfirmValue(_)).WillOnce(Invoke([&](ConfirmationData data) {
481 EXPECT_EQ(data_peripheral.GetNumericValue(), data.GetNumericValue());
482 if (data_peripheral.GetNumericValue() == data.GetNumericValue()) {
483 pairing_handler_a->OnUiAction(PairingEvent::CONFIRM_YESNO, 0x01);
484 pairing_handler_b->OnUiAction(PairingEvent::CONFIRM_YESNO, 0x01);
485 }
486 }));
487
488 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
489 }
490 pairing_handler_a->WaitUntilPairingFinished();
491 pairing_handler_b->WaitUntilPairingFinished();
492
493 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
494 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
495 }
496
TEST_F(PairingHandlerPairTest,test_secure_connections_passkey_entry)497 TEST_F(PairingHandlerPairTest, test_secure_connections_passkey_entry) {
498 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
499 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
500 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
501
502 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
503 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
504 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
505
506 // In this test either central or peripheral display the UI prompt first. This variable makes sure both prompts are
507 // displayed before passkey is confirmed. Since both UI handlers are same thread, it's safe.
508 int ui_prompts_count = 0;
509 uint32_t passkey_ = std::numeric_limits<uint32_t>::max();
510 {
511 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
512 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
513
514 while (!first_command_sent) {
515 std::this_thread::sleep_for(1ms);
516 log::info("waiting for first command...");
517 }
518 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
519
520 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
521
522 EXPECT_CALL(peripheral_user_interface, DisplayPasskey(_)).WillOnce(Invoke([&](ConfirmationData data) {
523 passkey_ = data.GetNumericValue();
524 ui_prompts_count++;
525 if (ui_prompts_count == 2) {
526 pairing_handler_a->OnUiAction(PairingEvent::PASSKEY, passkey_);
527 }
528 }));
529
530 EXPECT_CALL(central_user_interface, DisplayEnterPasskeyDialog(_)).WillOnce(Invoke([&](ConfirmationData data) {
531 ui_prompts_count++;
532 if (ui_prompts_count == 2) {
533 pairing_handler_a->OnUiAction(PairingEvent::PASSKEY, passkey_);
534 }
535 }));
536
537 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
538 }
539 // Initiator must be initialized after the responder.
540 pairing_handler_a->WaitUntilPairingFinished();
541 pairing_handler_b->WaitUntilPairingFinished();
542
543 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
544 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
545 }
546
TEST_F(PairingHandlerPairTest,test_secure_connections_out_of_band)547 TEST_F(PairingHandlerPairTest, test_secure_connections_out_of_band) {
548 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
549 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
550 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
551
552 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
553 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
554 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
555
556 central_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
557 peripheral_setup.remote_oob_data =
558 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
559 .le_sc_c = central_setup.my_oob_data->c,
560 .le_sc_r = central_setup.my_oob_data->r,
561 });
562
563 {
564 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
565 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
566 while (!first_command_sent) {
567 std::this_thread::sleep_for(1ms);
568 log::info("waiting for first command...");
569 }
570 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
571
572 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
573
574 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
575 }
576 pairing_handler_a->WaitUntilPairingFinished();
577 pairing_handler_b->WaitUntilPairingFinished();
578
579 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
580 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
581 }
582
TEST_F(PairingHandlerPairTest,test_secure_connections_out_of_band_two_way)583 TEST_F(PairingHandlerPairTest, test_secure_connections_out_of_band_two_way) {
584 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
585 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
586 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
587
588 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::DISPLAY_ONLY;
589 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::PRESENT;
590 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
591
592 central_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
593 peripheral_setup.remote_oob_data =
594 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
595 .le_sc_c = central_setup.my_oob_data->c,
596 .le_sc_r = central_setup.my_oob_data->r,
597 });
598
599 peripheral_setup.my_oob_data = std::make_optional<MyOobData>(PairingHandlerLe::GenerateOobData());
600 central_setup.remote_oob_data =
601 std::make_optional<InitialInformations::out_of_band_data>(InitialInformations::out_of_band_data{
602 .le_sc_c = peripheral_setup.my_oob_data->c,
603 .le_sc_r = peripheral_setup.my_oob_data->r,
604 });
605
606 {
607 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
608 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
609 while (!first_command_sent) {
610 std::this_thread::sleep_for(1ms);
611 log::info("waiting for first command...");
612 }
613 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
614
615 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
616
617 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
618 }
619 pairing_handler_a->WaitUntilPairingFinished();
620 pairing_handler_b->WaitUntilPairingFinished();
621
622 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
623 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
624 }
625
TEST_F(PairingHandlerPairTest,test_legacy_just_works)626 TEST_F(PairingHandlerPairTest, test_legacy_just_works) {
627 central_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
628 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
629 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm,
630
631 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::NO_INPUT_NO_OUTPUT;
632 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
633 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm;
634
635 {
636 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
637 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
638 while (!first_command_sent) {
639 std::this_thread::sleep_for(1ms);
640 log::info("waiting for first command...");
641 }
642 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
643
644 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
645
646 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
647 }
648 pairing_handler_a->WaitUntilPairingFinished();
649 pairing_handler_b->WaitUntilPairingFinished();
650
651 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
652 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
653 }
654
TEST_F(PairingHandlerPairTest,test_legacy_passkey_entry)655 TEST_F(PairingHandlerPairTest, test_legacy_passkey_entry) {
656 central_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_DISPLAY;
657 central_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
658 central_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm,
659
660 peripheral_setup.myPairingCapabilities.io_capability = IoCapability::KEYBOARD_ONLY;
661 peripheral_setup.myPairingCapabilities.oob_data_flag = OobDataFlag::NOT_PRESENT;
662 peripheral_setup.myPairingCapabilities.auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm;
663
664 {
665 std::unique_lock<std::mutex> lock(handlers_initialization_guard);
666 pairing_handler_a = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, central_setup);
667 while (!first_command_sent) {
668 std::this_thread::sleep_for(1ms);
669 log::info("waiting for first command...");
670 }
671 peripheral_setup.pairing_request = PairingRequestView::Create(*first_command);
672
673 RecordPairingPromptHandling(peripheral_user_interface, &pairing_handler_b);
674
675 EXPECT_CALL(peripheral_user_interface, DisplayEnterPasskeyDialog(_));
676 EXPECT_CALL(central_user_interface, DisplayConfirmValue(_))
677 .WillOnce(Invoke([&](ConfirmationData data) {
678 log::info("Passkey prompt displayed entering passkey: {:08x}", data.GetNumericValue());
679 std::this_thread::sleep_for(1ms);
680
681 // TODO: handle case where prompts are displayed in different order in the test!
682 pairing_handler_b->OnUiAction(PairingEvent::PASSKEY, data.GetNumericValue());
683 }));
684
685 pairing_handler_b = std::make_unique<PairingHandlerLe>(PairingHandlerLe::PHASE1, peripheral_setup);
686 }
687 pairing_handler_a->WaitUntilPairingFinished();
688 pairing_handler_b->WaitUntilPairingFinished();
689
690 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
691 EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
692 }
693
694 } // namespace security
695 } // namespace bluetooth
696