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 = &central_user_interface,
196         .user_interface_handler = handler_,
197         .le_security_interface = &central_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(&central_user_interface);
233     ::testing::Mock::VerifyAndClearExpectations(&peripheral_le_security_mock);
234     ::testing::Mock::VerifyAndClearExpectations(&central_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 = &central_user_interface,
392       .user_interface_handler = handler_,
393       .le_security_interface = &central_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