blob: 7e64dc72d9d8f76634f4d86ca471ce7cd1b44ecf [file] [log] [blame]
Martin Brabham80854c22019-11-12 14:52:42 -08001/*
Martin Brabham605d6f12019-03-29 12:02:30 -07002 *
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 *
Martin Brabham80854c22019-11-12 14:52:42 -080017 */
Martin Brabham605d6f12019-03-29 12:02:30 -070018#include "security_manager_impl.h"
19
20#include <iostream>
Martin Brabham605d6f12019-03-29 12:02:30 -070021
Martin Brabham80854c22019-11-12 14:52:42 -080022#include "hci/address_with_type.h"
Martin Brabham605d6f12019-03-29 12:02:30 -070023#include "os/log.h"
Jakub Pawlowski5a67e402019-11-18 16:14:22 +010024#include "security/security_manager.h"
Martin Brabham605d6f12019-03-29 12:02:30 -070025
Martin Brabham80854c22019-11-12 14:52:42 -080026namespace bluetooth {
27namespace security {
28namespace internal {
Martin Brabham605d6f12019-03-29 12:02:30 -070029
Martin Brabham80854c22019-11-12 14:52:42 -080030std::shared_ptr<bluetooth::security::record::SecurityRecord> SecurityManagerImpl::CreateSecurityRecord(
31 hci::Address address) {
32 hci::AddressWithType device(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS);
33 // Security record check
34 auto entry = security_record_map_.find(device.GetAddress());
35 if (entry == security_record_map_.end()) {
36 LOG_INFO("No security record for device: %s ", device.ToString().c_str());
37 // Create one
38 std::shared_ptr<security::record::SecurityRecord> record =
39 std::make_shared<security::record::SecurityRecord>(device);
40 auto new_entry = std::pair<hci::Address, std::shared_ptr<security::record::SecurityRecord>>(
41 record->GetDevice().GetAddress(), record);
42 // Keep track of it
43 security_record_map_.insert(new_entry);
44 return record;
45 }
46 return entry->second;
47}
Martin Brabham605d6f12019-03-29 12:02:30 -070048
Martin Brabham80854c22019-11-12 14:52:42 -080049void SecurityManagerImpl::DispatchPairingHandler(std::shared_ptr<security::record::SecurityRecord> record,
50 bool locally_initiated) {
51 common::OnceCallback<void(hci::Address)> callback =
52 common::BindOnce(&SecurityManagerImpl::OnPairingHandlerComplete, common::Unretained(this));
53 auto entry = pairing_handler_map_.find(record->GetDevice().GetAddress());
Martin Brabham605d6f12019-03-29 12:02:30 -070054 if (entry != pairing_handler_map_.end()) {
55 LOG_WARN("Device already has a pairing handler, and is in the middle of pairing!");
56 return;
57 }
Martin Brabham80854c22019-11-12 14:52:42 -080058 std::shared_ptr<pairing::PairingHandler> pairing_handler = nullptr;
59 switch (record->GetDevice().GetAddressType()) {
60 case hci::AddressType::PUBLIC_DEVICE_ADDRESS:
61 pairing_handler = std::make_shared<security::pairing::ClassicPairingHandler>(
62 l2cap_classic_module_->GetFixedChannelManager(), security_manager_channel_, record, security_handler_,
63 std::move(callback));
Martin Brabham605d6f12019-03-29 12:02:30 -070064 break;
65 default:
Martin Brabham80854c22019-11-12 14:52:42 -080066 ASSERT_LOG(false, "Pairing type %hhu not implemented!", record->GetDevice().GetAddressType());
Martin Brabham605d6f12019-03-29 12:02:30 -070067 }
Martin Brabham80854c22019-11-12 14:52:42 -080068 auto new_entry = std::pair<hci::Address, std::shared_ptr<pairing::PairingHandler>>(record->GetDevice().GetAddress(),
69 pairing_handler);
Martin Brabham605d6f12019-03-29 12:02:30 -070070 pairing_handler_map_.insert(std::move(new_entry));
Martin Brabham80854c22019-11-12 14:52:42 -080071 pairing_handler->Initiate(locally_initiated, pairing::kDefaultIoCapability, pairing::kDefaultOobDataPresent,
72 pairing::kDefaultAuthenticationRequirements);
Martin Brabham605d6f12019-03-29 12:02:30 -070073}
Martin Brabham605d6f12019-03-29 12:02:30 -070074
75void SecurityManagerImpl::Init() {
Martin Brabham80854c22019-11-12 14:52:42 -080076 security_manager_channel_->SetChannelListener(this);
77 security_manager_channel_->SendCommand(hci::WriteSimplePairingModeBuilder::Create(hci::Enable::ENABLED));
78 security_manager_channel_->SendCommand(hci::WriteSecureConnectionsHostSupportBuilder::Create(hci::Enable::ENABLED));
Martin Brabham605d6f12019-03-29 12:02:30 -070079 // TODO(optedoblivion): Populate security record memory map from disk
Martin Brabham605d6f12019-03-29 12:02:30 -070080}
81
Martin Brabham80854c22019-11-12 14:52:42 -080082void SecurityManagerImpl::CreateBond(hci::AddressWithType device) {
83 auto record = CreateSecurityRecord(device.GetAddress());
84 if (record->IsBonded()) {
85 NotifyDeviceBonded(device);
86 } else {
87 // Dispatch pairing handler, if we are calling create we are the initiator
88 DispatchPairingHandler(record, true);
Martin Brabham605d6f12019-03-29 12:02:30 -070089 }
Martin Brabham605d6f12019-03-29 12:02:30 -070090}
91
Martin Brabham80854c22019-11-12 14:52:42 -080092void SecurityManagerImpl::CancelBond(hci::AddressWithType device) {
93 auto entry = pairing_handler_map_.find(device.GetAddress());
94 if (entry != pairing_handler_map_.end()) {
Greg Kaiserf98cc3d2019-11-27 07:08:14 -080095 auto cancel_me = entry->second;
Martin Brabham80854c22019-11-12 14:52:42 -080096 pairing_handler_map_.erase(entry);
Greg Kaiserf98cc3d2019-11-27 07:08:14 -080097 cancel_me->Cancel();
Martin Brabham80854c22019-11-12 14:52:42 -080098 }
99}
100
101void SecurityManagerImpl::RemoveBond(hci::AddressWithType device) {
Martin Brabham605d6f12019-03-29 12:02:30 -0700102 CancelBond(device);
Martin Brabham80854c22019-11-12 14:52:42 -0800103 auto entry = security_record_map_.find(device.GetAddress());
104 if (entry != security_record_map_.end()) {
105 security_record_map_.erase(entry);
106 }
Martin Brabham605d6f12019-03-29 12:02:30 -0700107 // Signal disconnect
Martin Brabham605d6f12019-03-29 12:02:30 -0700108 // Remove security record
109 // Signal Remove from database
110}
111
Jakub Pawlowski24d5f352019-11-18 18:54:09 +0100112void SecurityManagerImpl::RegisterCallbackListener(ISecurityManagerListener* listener, os::Handler* handler) {
Jakub Pawlowskif7cd6562019-11-18 19:27:06 +0100113 for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
114 if (it->first == listener) {
115 LOG_ALWAYS_FATAL("Listener has already been registered!");
Martin Brabham605d6f12019-03-29 12:02:30 -0700116 }
117 }
Jakub Pawlowskif7cd6562019-11-18 19:27:06 +0100118
119 listeners_.push_back({listener, handler});
Martin Brabham605d6f12019-03-29 12:02:30 -0700120}
121
122void SecurityManagerImpl::UnregisterCallbackListener(ISecurityManagerListener* listener) {
Jakub Pawlowskif7cd6562019-11-18 19:27:06 +0100123 for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
124 if (it->first == listener) {
Martin Brabham605d6f12019-03-29 12:02:30 -0700125 listeners_.erase(it);
Jakub Pawlowskif7cd6562019-11-18 19:27:06 +0100126 return;
Martin Brabham605d6f12019-03-29 12:02:30 -0700127 }
128 }
Jakub Pawlowskif7cd6562019-11-18 19:27:06 +0100129
130 LOG_ALWAYS_FATAL("Listener has not been registered!");
Martin Brabham605d6f12019-03-29 12:02:30 -0700131}
132
Jakub Pawlowskid2c82f52019-11-22 15:33:12 +0100133void SecurityManagerImpl::NotifyDeviceBonded(hci::AddressWithType device) {
Martin Brabham605d6f12019-03-29 12:02:30 -0700134 for (auto& iter : listeners_) {
Jakub Pawlowski24d5f352019-11-18 18:54:09 +0100135 iter.second->Post(common::Bind(&ISecurityManagerListener::OnDeviceBonded, common::Unretained(iter.first), device));
Martin Brabham605d6f12019-03-29 12:02:30 -0700136 }
137}
138
Jakub Pawlowskid2c82f52019-11-22 15:33:12 +0100139void SecurityManagerImpl::NotifyDeviceBondFailed(hci::AddressWithType device) {
Martin Brabham605d6f12019-03-29 12:02:30 -0700140 for (auto& iter : listeners_) {
Jakub Pawlowski24d5f352019-11-18 18:54:09 +0100141 iter.second->Post(
142 common::Bind(&ISecurityManagerListener::OnDeviceBondFailed, common::Unretained(iter.first), device));
Martin Brabham605d6f12019-03-29 12:02:30 -0700143 }
144}
145
Jakub Pawlowskid2c82f52019-11-22 15:33:12 +0100146void SecurityManagerImpl::NotifyDeviceUnbonded(hci::AddressWithType device) {
Martin Brabham605d6f12019-03-29 12:02:30 -0700147 for (auto& iter : listeners_) {
Jakub Pawlowski24d5f352019-11-18 18:54:09 +0100148 iter.second->Post(
149 common::Bind(&ISecurityManagerListener::OnDeviceUnbonded, common::Unretained(iter.first), device));
Martin Brabham605d6f12019-03-29 12:02:30 -0700150 }
151}
Martin Brabham80854c22019-11-12 14:52:42 -0800152
153template <class T>
154void SecurityManagerImpl::HandleEvent(T packet) {
155 ASSERT(packet.IsValid());
156 auto entry = pairing_handler_map_.find(packet.GetBdAddr());
157 if (entry != pairing_handler_map_.end()) {
158 entry->second->OnReceive(packet);
159 } else {
160 auto event = hci::EventPacketView::Create(std::move(packet));
161 ASSERT_LOG(event.IsValid(), "Received invalid packet");
162 const hci::EventCode code = event.GetEventCode();
163 auto record = CreateSecurityRecord(packet.GetBdAddr());
164 switch (code) {
165 case hci::EventCode::LINK_KEY_REQUEST:
166 DispatchPairingHandler(record, true);
167 break;
168 default:
169 LOG_ERROR("No classic pairing handler for device '%s' ready for command '%hhx' ",
170 packet.GetBdAddr().ToString().c_str(), packet.GetEventCode());
171 break;
172 }
173 }
174}
175
176void SecurityManagerImpl::OnHciEventReceived(hci::EventPacketView packet) {
177 auto event = hci::EventPacketView::Create(packet);
178 ASSERT_LOG(event.IsValid(), "Received invalid packet");
179 const hci::EventCode code = event.GetEventCode();
180 switch (code) {
181 case hci::EventCode::PIN_CODE_REQUEST:
182 HandleEvent<hci::PinCodeRequestView>(hci::PinCodeRequestView::Create(event));
183 break;
184 case hci::EventCode::LINK_KEY_REQUEST:
185 HandleEvent(hci::LinkKeyRequestView::Create(event));
186 break;
187 case hci::EventCode::LINK_KEY_NOTIFICATION:
188 HandleEvent(hci::LinkKeyNotificationView::Create(event));
189 break;
190 case hci::EventCode::IO_CAPABILITY_REQUEST:
191 HandleEvent(hci::IoCapabilityRequestView::Create(event));
192 break;
193 case hci::EventCode::IO_CAPABILITY_RESPONSE:
194 HandleEvent(hci::IoCapabilityResponseView::Create(event));
195 break;
196 case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
197 HandleEvent(hci::SimplePairingCompleteView::Create(event));
198 break;
199 case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
200 HandleEvent(hci::RemoteOobDataRequestView::Create(event));
201 break;
202 case hci::EventCode::USER_PASSKEY_NOTIFICATION:
203 HandleEvent<hci::UserPasskeyNotificationView>(hci::UserPasskeyNotificationView::Create(event));
204 break;
205 case hci::EventCode::KEYPRESS_NOTIFICATION:
206 HandleEvent(hci::KeypressNotificationView::Create(event));
207 break;
208 case hci::EventCode::USER_CONFIRMATION_REQUEST:
209 HandleEvent(hci::UserConfirmationRequestView::Create(event));
210 break;
211 case hci::EventCode::USER_PASSKEY_REQUEST:
212 HandleEvent(hci::UserPasskeyRequestView::Create(event));
213 break;
214 default:
215 ASSERT_LOG(false, "Cannot handle received packet: %s", hci::EventCodeText(code).c_str());
216 break;
217 }
218}
219
220void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address) {
221 auto entry = pairing_handler_map_.find(address);
222 if (entry != pairing_handler_map_.end()) {
223 pairing_handler_map_.erase(entry);
224 }
225 NotifyDeviceBonded(hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS));
226}
227
228} // namespace internal
229} // namespace security
230} // namespace bluetooth