• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_bluetooth_sapphire/internal/host/sm/test_security_manager.h"
15 
16 #include <pw_assert/check.h>
17 
18 #include <memory>
19 
20 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
21 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
22 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
23 
24 namespace bt::sm::testing {
25 
26 namespace {
RoleFromLinks(hci::LowEnergyConnection::WeakPtr link,hci::BrEdrConnection::WeakPtr bredr_link)27 Role RoleFromLinks(hci::LowEnergyConnection::WeakPtr link,
28                    hci::BrEdrConnection::WeakPtr bredr_link) {
29   pw::bluetooth::emboss::ConnectionRole conn_role =
30       pw::bluetooth::emboss::ConnectionRole::CENTRAL;
31   if (link.is_alive()) {
32     conn_role = link->role();
33   }
34   if (bredr_link.is_alive()) {
35     conn_role = bredr_link->role();
36   }
37   return conn_role == pw::bluetooth::emboss::ConnectionRole::CENTRAL
38              ? Role::kInitiator
39              : Role::kResponder;
40 }
41 }  // namespace
42 
TestSecurityManager(hci::LowEnergyConnection::WeakPtr link,hci::BrEdrConnection::WeakPtr bredr_link,l2cap::Channel::WeakPtr,IOCapability,Delegate::WeakPtr delegate,BondableMode bondable_mode,gap::LESecurityMode security_mode,gap::Peer::WeakPtr peer)43 TestSecurityManager::TestSecurityManager(
44     hci::LowEnergyConnection::WeakPtr link,
45     hci::BrEdrConnection::WeakPtr bredr_link,
46     l2cap::Channel::WeakPtr,
47     IOCapability,
48     Delegate::WeakPtr delegate,
49     BondableMode bondable_mode,
50     gap::LESecurityMode security_mode,
51     gap::Peer::WeakPtr peer)
52     : SecurityManager(bondable_mode, security_mode),
53       role_(RoleFromLinks(link, bredr_link)),
54       delegate_(std::move(delegate)),
55       peer_(std::move(peer)),
56       weak_self_(this) {
57   if (link.is_alive()) {
58     if (peer_->le() && peer_->le()->bond_data()) {
59       current_ltk_ =
60           (link->role() == pw::bluetooth::emboss::ConnectionRole::CENTRAL)
61               ? peer_->le()->bond_data()->peer_ltk
62               : peer_->le()->bond_data()->local_ltk;
63     }
64     if (current_ltk_) {
65       if (role_ == Role::kInitiator) {
66         set_security(current_ltk_->security());
67       }
68     }
69   }
70 }
71 
UpgradeSecurity(SecurityLevel level,PairingCallback callback)72 void TestSecurityManager::UpgradeSecurity(SecurityLevel level,
73                                           PairingCallback callback) {
74   last_requested_upgrade_ = level;
75   set_security(SecurityProperties(
76       level, kMaxEncryptionKeySize, /*secure_connections=*/true));
77   callback(fit::ok(), security());
78 }
79 
InitiateBrEdrCrossTransportKeyDerivation(CrossTransportKeyDerivationResultCallback callback)80 void TestSecurityManager::InitiateBrEdrCrossTransportKeyDerivation(
81     CrossTransportKeyDerivationResultCallback callback) {
82   if (!pairing_data_) {
83     callback(ToResult(HostError::kFailed));
84     return;
85   }
86   last_identity_info_ = delegate_->OnIdentityInformationRequest();
87   delegate_->OnPairingComplete(fit::ok());
88   peer_->MutLe().StoreBond(pairing_data_.value());
89   callback(fit::ok());
90 }
91 
TriggerPairingComplete(sm::PairingData data)92 void TestSecurityManager::TriggerPairingComplete(sm::PairingData data) {
93   last_identity_info_ = delegate_->OnIdentityInformationRequest();
94   delegate_->OnPairingComplete(fit::ok());
95   peer_->MutLe().StoreBond(data);
96 }
97 
Reset(IOCapability)98 void TestSecurityManager::Reset(IOCapability) {}
Abort(ErrorCode)99 void TestSecurityManager::Abort(ErrorCode) {}
100 
CreateSm(hci::LowEnergyConnection::WeakPtr link,l2cap::Channel::WeakPtr smp,IOCapability io_capability,Delegate::WeakPtr delegate,BondableMode bondable_mode,gap::LESecurityMode security_mode,pw::async::Dispatcher &,gap::Peer::WeakPtr peer)101 std::unique_ptr<SecurityManager> TestSecurityManagerFactory::CreateSm(
102     hci::LowEnergyConnection::WeakPtr link,
103     l2cap::Channel::WeakPtr smp,
104     IOCapability io_capability,
105     Delegate::WeakPtr delegate,
106     BondableMode bondable_mode,
107     gap::LESecurityMode security_mode,
108     pw::async::Dispatcher&,
109     gap::Peer::WeakPtr peer) {
110   hci_spec::ConnectionHandle conn = link->handle();
111   auto test_sm = std::unique_ptr<TestSecurityManager>(
112       new TestSecurityManager(std::move(link),
113                               hci::BrEdrConnection::WeakPtr(),
114                               std::move(smp),
115                               io_capability,
116                               std::move(delegate),
117                               bondable_mode,
118                               security_mode,
119                               std::move(peer)));
120   test_sms_[conn] = test_sm->GetWeakPtr();
121   return test_sm;
122 }
123 
CreateBrEdr(hci::BrEdrConnection::WeakPtr link,l2cap::Channel::WeakPtr smp,Delegate::WeakPtr delegate,bool,pw::async::Dispatcher &,bt::gap::Peer::WeakPtr peer)124 std::unique_ptr<SecurityManager> TestSecurityManagerFactory::CreateBrEdr(
125     hci::BrEdrConnection::WeakPtr link,
126     l2cap::Channel::WeakPtr smp,
127     Delegate::WeakPtr delegate,
128     bool /*is_controller_remote_public_key_validation_supported*/,
129     pw::async::Dispatcher&,
130     bt::gap::Peer::WeakPtr peer) {
131   PW_CHECK(smp.is_alive());
132   hci_spec::ConnectionHandle conn = link->handle();
133   auto test_sm = std::unique_ptr<TestSecurityManager>(
134       new TestSecurityManager(hci::LowEnergyConnection::WeakPtr(),
135                               std::move(link),
136                               std::move(smp),
137                               IOCapability::kNoInputNoOutput,
138                               std::move(delegate),
139                               BondableMode::Bondable,
140                               gap::LESecurityMode::SecureConnectionsOnly,
141                               std::move(peer)));
142   test_sms_[conn] = test_sm->GetWeakPtr();
143   return test_sm;
144 }
145 
GetTestSm(hci_spec::ConnectionHandle conn_handle)146 WeakSelf<TestSecurityManager>::WeakPtr TestSecurityManagerFactory::GetTestSm(
147     hci_spec::ConnectionHandle conn_handle) {
148   auto iter = test_sms_.find(conn_handle);
149   PW_CHECK(iter != test_sms_.end());
150   return iter->second;
151 }
152 
153 }  // namespace bt::sm::testing
154