• 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 
15 #pragma once
16 #include <memory>
17 #include <unordered_map>
18 
19 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
20 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
21 #include "pw_bluetooth_sapphire/internal/host/hci-spec/link_key.h"
22 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
23 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connection.h"
24 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel.h"
25 #include "pw_bluetooth_sapphire/internal/host/sm/delegate.h"
26 #include "pw_bluetooth_sapphire/internal/host/sm/error.h"
27 #include "pw_bluetooth_sapphire/internal/host/sm/security_manager.h"
28 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
29 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
30 
31 namespace bt::sm::testing {
32 
33 // TestSecurityManager implements the public interface of the SM library. The
34 // intended use is in unit tests of code directly dependent on SM (currently,
35 // GAP). The implementation is currently limited to a basic test spy, with
36 // stubbed out responses and request tracking for a few functions and empty
37 // implementations for others.
38 class TestSecurityManager final : public SecurityManager {
39  public:
40   ~TestSecurityManager() override = default;
41 
42   // SecurityManager overrides:
43   void UpgradeSecurity(SecurityLevel level, PairingCallback callback) override;
44   void InitiateBrEdrCrossTransportKeyDerivation(
45       CrossTransportKeyDerivationResultCallback) override;
46   void Reset(IOCapability io_capability) override;
47   void Abort(ErrorCode ecode) override;
48 
49   // Returns the most recent security upgrade request received by this SM, if
50   // one has been made.
last_requested_upgrade()51   std::optional<SecurityLevel> last_requested_upgrade() const {
52     return last_requested_upgrade_;
53   }
54 
last_identity_info()55   std::optional<sm::IdentityInfo> last_identity_info() const {
56     return last_identity_info_;
57   }
58 
59   // Set pairing data to return to InitiateBrEdrCrossTransportKeyDerivation().
60   // If not set, CTKD will fail.
set_pairing_data(std::optional<sm::PairingData> data)61   void set_pairing_data(std::optional<sm::PairingData> data) {
62     pairing_data_ = std::move(data);
63   }
64 
65   void TriggerPairingComplete(sm::PairingData data);
66 
67   using WeakPtr = WeakSelf<TestSecurityManager>::WeakPtr;
GetWeakPtr()68   WeakPtr GetWeakPtr() { return weak_self_.GetWeakPtr(); }
69 
70  private:
71   friend class TestSecurityManagerFactory;
72   TestSecurityManager(hci::LowEnergyConnection::WeakPtr link,
73                       hci::BrEdrConnection::WeakPtr bredr_link,
74                       l2cap::Channel::WeakPtr smp,
75                       IOCapability io_capability,
76                       Delegate::WeakPtr delegate,
77                       BondableMode bondable_mode,
78                       gap::LESecurityMode security_mode,
79                       gap::Peer::WeakPtr peer);
80   Role role_;
81   std::optional<LTK> current_ltk_;
82   std::optional<SecurityLevel> last_requested_upgrade_;
83   Delegate::WeakPtr delegate_;
84   std::optional<sm::IdentityInfo> last_identity_info_;
85   std::optional<sm::PairingData> pairing_data_;
86   gap::Peer::WeakPtr peer_;
87   WeakSelf<TestSecurityManager> weak_self_;
88 };
89 
90 // TestSecurityManagerFactory provides a public factory method to create
91 // TestSecurityManagers for dependency injection. It stores these TestSMs so
92 // test code can access them to set and verify expectations. A separate storage
93 // object is needed because SecurityManagers cannot be directly injected, e.g.
94 // during construction, as they are created on demand upon connection creation.
95 // Storing the TestSMs in a factory object is preferable to a static member of
96 // TestSM itself so that each test is sandboxed from TestSMs in other tests.
97 // This is done by tying the lifetime of the factory to the test.
98 class TestSecurityManagerFactory {
99  public:
100   TestSecurityManagerFactory() = default;
101   // Code which uses TestSecurityManagers should create these objects through
102   // `CreateSm`. |link|: The LE logical link over which pairing procedures
103   // occur. |smp|: The L2CAP LE SMP fixed channel that operates over |link|.
104   // |io_capability|: The initial I/O capability.
105   // |delegate|: Delegate which handles SMP interactions with the rest of the
106   // Bluetooth stack. |bondable_mode|: the operating bondable mode of the device
107   // (see v5.2, Vol. 3, Part C 9.4). |security_mode|: the security mode this
108   // SecurityManager is in (see v5.2, Vol. 3, Part C 10.2).
109   std::unique_ptr<SecurityManager> CreateSm(
110       hci::LowEnergyConnection::WeakPtr link,
111       l2cap::Channel::WeakPtr smp,
112       IOCapability io_capability,
113       Delegate::WeakPtr delegate,
114       BondableMode bondable_mode,
115       gap::LESecurityMode security_mode,
116       pw::async::Dispatcher& dispatcher,
117       gap::Peer::WeakPtr peer);
118 
119   std::unique_ptr<SecurityManager> CreateBrEdr(
120       hci::BrEdrConnection::WeakPtr link,
121       l2cap::Channel::WeakPtr smp,
122       Delegate::WeakPtr delegate,
123       bool is_controller_remote_public_key_validation_supported,
124       pw::async::Dispatcher& dispatcher,
125       bt::gap::Peer::WeakPtr peer);
126 
127   // Obtain a reference to the TestSecurityManager associated with
128   // |conn_handle|'s connection for use in test code.
129   testing::TestSecurityManager::WeakPtr GetTestSm(
130       hci_spec::ConnectionHandle conn_handle);
131 
132  private:
133   std::unordered_map<hci_spec::ConnectionHandle,
134                      testing::TestSecurityManager::WeakPtr>
135       test_sms_;
136 };
137 
138 }  // namespace bt::sm::testing
139