• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "security_manager.h"
18 
19 #include "log.h"
20 
21 using std::vector;
22 
23 namespace rootcanal {
24 
DeleteAllKeys()25 uint16_t SecurityManager::DeleteAllKeys() {
26   uint16_t size = key_store_.size();
27   key_store_.clear();
28   return size;
29 }
30 
DeleteKey(const Address & addr)31 uint16_t SecurityManager::DeleteKey(const Address& addr) {
32   uint16_t count = key_store_.count(addr.ToString());
33   if (count) {
34     key_store_.erase(addr.ToString());
35   }
36   return count;
37 }
38 
ReadAllKeys() const39 uint16_t SecurityManager::ReadAllKeys() const { return key_store_.size(); }
40 
ReadKey(const Address & addr) const41 uint16_t SecurityManager::ReadKey(const Address& addr) const {
42   return key_store_.count(addr.ToString());
43 }
44 
WriteKey(const Address & addr,const std::array<uint8_t,16> & key)45 uint16_t SecurityManager::WriteKey(const Address& addr,
46                                    const std::array<uint8_t, 16>& key) {
47   if (key_store_.size() >= max_keys_) {
48     return 0;
49   }
50   key_store_[addr.ToString()] = key;
51   return 1;
52 }
53 
GetKey(const Address & addr) const54 const std::array<uint8_t, 16>& SecurityManager::GetKey(
55     const Address& addr) const {
56   ASSERT_LOG(ReadKey(addr), "No such key");
57   return key_store_.at(addr.ToString());
58 }
59 
AuthenticationRequest(const Address & addr,uint16_t handle,bool initiator)60 void SecurityManager::AuthenticationRequest(const Address& addr,
61                                             uint16_t handle, bool initiator) {
62   authenticating_ = true;
63   current_handle_ = handle;
64   peer_address_ = addr;
65   initiator_ = initiator;
66   peer_pin_requested_ = false;
67   peer_pin_received_ = false;
68   host_pin_received_ = false;
69 }
70 
AuthenticationRequestFinished()71 void SecurityManager::AuthenticationRequestFinished() {
72   authenticating_ = false;
73 }
74 
AuthenticationInProgress()75 bool SecurityManager::AuthenticationInProgress() { return authenticating_; }
76 
IsInitiator()77 bool SecurityManager::IsInitiator() { return initiator_; }
78 
GetAuthenticationHandle()79 uint16_t SecurityManager::GetAuthenticationHandle() { return current_handle_; }
80 
GetAuthenticationAddress()81 Address SecurityManager::GetAuthenticationAddress() { return peer_address_; }
82 
SetPeerIoCapability(const Address & addr,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)83 void SecurityManager::SetPeerIoCapability(const Address& addr,
84                                           uint8_t io_capability,
85                                           uint8_t oob_present_flag,
86                                           uint8_t authentication_requirements) {
87   ASSERT(addr == peer_address_);
88   peer_capabilities_valid_ = true;
89   if (io_capability <=
90       static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT)) {
91     peer_io_capability_ = static_cast<IoCapabilityType>(io_capability);
92   } else {
93     peer_io_capability_ = IoCapabilityType::INVALID;
94     peer_capabilities_valid_ = false;
95   }
96   peer_oob_present_flag_ = oob_present_flag;
97   if (authentication_requirements <=
98       static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM)) {
99     peer_authentication_requirements_ =
100         static_cast<AuthenticationType>(authentication_requirements);
101   } else {
102     peer_authentication_requirements_ = AuthenticationType::INVALID;
103     peer_capabilities_valid_ = false;
104   }
105 }
106 
SetLocalIoCapability(const Address & peer,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)107 void SecurityManager::SetLocalIoCapability(
108     const Address& peer, uint8_t io_capability, uint8_t oob_present_flag,
109     uint8_t authentication_requirements) {
110   ASSERT(peer == peer_address_);
111   ASSERT_LOG(io_capability <=
112                  static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT),
113              "io_capability = %d", static_cast<int>(io_capability));
114   ASSERT_LOG(oob_present_flag <= 3, "oob_present_flag = %hhx ",
115              oob_present_flag);
116   ASSERT_LOG(authentication_requirements <=
117                  static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM),
118              "authentication_requirements = %d",
119              static_cast<int>(authentication_requirements));
120   host_io_capability_ = static_cast<IoCapabilityType>(io_capability);
121   host_oob_present_flag_ = oob_present_flag;
122   host_authentication_requirements_ =
123       static_cast<AuthenticationType>(authentication_requirements);
124   host_capabilities_valid_ = true;
125 }
126 
InvalidateIoCapabilities()127 void SecurityManager::InvalidateIoCapabilities() {
128   host_capabilities_valid_ = false;
129   peer_capabilities_valid_ = false;
130 }
131 
GetSimplePairingType()132 PairingType SecurityManager::GetSimplePairingType() {
133   if (!host_capabilities_valid_ || !peer_capabilities_valid_) {
134     return PairingType::INVALID;
135   }
136   bool host_requires_mitm = (host_authentication_requirements_ ==
137                              AuthenticationType::NO_BONDING_MITM) ||
138                             (host_authentication_requirements_ ==
139                              AuthenticationType::DEDICATED_BONDING_MITM) ||
140                             (host_authentication_requirements_ ==
141                              AuthenticationType::GENERAL_BONDING_MITM);
142   bool peer_requires_mitm = (peer_authentication_requirements_ ==
143                              AuthenticationType::NO_BONDING_MITM) ||
144                             (peer_authentication_requirements_ ==
145                              AuthenticationType::DEDICATED_BONDING_MITM) ||
146                             (peer_authentication_requirements_ ==
147                              AuthenticationType::GENERAL_BONDING_MITM);
148   if (peer_oob_present_flag_ != 0 || host_oob_present_flag_ != 0) {
149     if (host_oob_present_flag_ == 0) {
150       return PairingType::PEER_HAS_OUT_OF_BAND;
151     } else {
152       return PairingType::OUT_OF_BAND;
153     }
154   }
155   if (!(peer_requires_mitm || host_requires_mitm)) {
156     return PairingType::AUTO_CONFIRMATION;
157   }
158   LOG_INFO("%s: host does%s require peer does%s require MITM",
159            peer_address_.ToString().c_str(), host_requires_mitm ? "" : "n't",
160            peer_requires_mitm ? "" : "n't");
161   switch (peer_io_capability_) {
162     case IoCapabilityType::DISPLAY_ONLY:
163       switch (host_io_capability_) {
164         case IoCapabilityType::DISPLAY_ONLY:
165         case IoCapabilityType::DISPLAY_YES_NO:
166           return PairingType::AUTO_CONFIRMATION;
167         case IoCapabilityType::KEYBOARD_ONLY:
168           return PairingType::INPUT_PIN;
169         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
170           return PairingType::AUTO_CONFIRMATION;
171         case IoCapabilityType::INVALID:
172           return PairingType::INVALID;
173       }
174     case IoCapabilityType::DISPLAY_YES_NO:
175       switch (host_io_capability_) {
176         case IoCapabilityType::DISPLAY_ONLY:
177           return PairingType::AUTO_CONFIRMATION;
178         case IoCapabilityType::DISPLAY_YES_NO:
179           return PairingType::DISPLAY_AND_CONFIRM;
180         case IoCapabilityType::KEYBOARD_ONLY:
181           return PairingType::INPUT_PIN;
182         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
183           return PairingType::AUTO_CONFIRMATION;
184         case IoCapabilityType::INVALID:
185           return PairingType::INVALID;
186       }
187     case IoCapabilityType::KEYBOARD_ONLY:
188       switch (host_io_capability_) {
189         case IoCapabilityType::DISPLAY_ONLY:
190         case IoCapabilityType::DISPLAY_YES_NO:
191           return PairingType::DISPLAY_PIN;
192         case IoCapabilityType::KEYBOARD_ONLY:
193           return PairingType::INPUT_PIN;
194         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
195           return PairingType::AUTO_CONFIRMATION;
196         case IoCapabilityType::INVALID:
197           return PairingType::INVALID;
198       }
199     case IoCapabilityType::NO_INPUT_NO_OUTPUT:
200       return PairingType::AUTO_CONFIRMATION;
201     case IoCapabilityType::INVALID:
202       return PairingType::INVALID;
203   }
204 }
205 
SetPinRequested(const Address & addr)206 void SecurityManager::SetPinRequested(const Address& addr) {
207   ASSERT(addr == peer_address_);
208   peer_pin_requested_ = true;
209 }
210 
GetPinRequested(const Address & addr)211 bool SecurityManager::GetPinRequested(const Address& addr) {
212   ASSERT(addr == peer_address_);
213   return peer_pin_requested_;
214 }
215 
SetLocalPin(const Address & peer,const std::vector<uint8_t> & pin)216 void SecurityManager::SetLocalPin(const Address& peer,
217                                   const std::vector<uint8_t>& pin) {
218   ASSERT(peer == peer_address_);
219   host_pin_received_ = true;
220   host_pin_ = pin;
221 }
222 
SetRemotePin(const Address & peer,const std::vector<uint8_t> & pin)223 void SecurityManager::SetRemotePin(const Address& peer,
224                                    const std::vector<uint8_t>& pin) {
225   ASSERT(peer == peer_address_);
226   peer_pin_received_ = true;
227   peer_pin_ = pin;
228 }
229 
GetLocalPinResponseReceived(const Address & peer)230 bool SecurityManager::GetLocalPinResponseReceived(const Address& peer) {
231   ASSERT(peer == peer_address_);
232   return host_pin_received_;
233 }
234 
GetRemotePinResponseReceived(const Address & peer)235 bool SecurityManager::GetRemotePinResponseReceived(const Address& peer) {
236   ASSERT(peer == peer_address_);
237   return peer_pin_received_;
238 }
239 
PinCompare()240 bool SecurityManager::PinCompare() {
241   return host_pin_received_ && peer_pin_received_ && peer_pin_ == host_pin_;
242 }
243 }  // namespace rootcanal
244