1 /*
2 * Copyright 2019 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 #include "security/facade.h"
17
18 #include "blueberry/facade/security/facade.grpc.pb.h"
19 #include "grpc/grpc_event_queue.h"
20 #include "hci/address_with_type.h"
21 #include "hci/le_address_manager.h"
22 #include "hci/le_advertising_manager.h"
23 #include "l2cap/classic/security_policy.h"
24 #include "l2cap/le/l2cap_le_module.h"
25 #include "os/handler.h"
26 #include "security/pairing/oob_data.h"
27 #include "security/security_manager_listener.h"
28 #include "security/security_module.h"
29 #include "security/ui.h"
30
31 using bluetooth::l2cap::le::L2capLeModule;
32
33 namespace bluetooth {
34 namespace security {
35
36 using namespace blueberry::facade::security;
37
38 namespace {
39 constexpr uint8_t AUTH_REQ_NO_BOND = 0x01;
40 constexpr uint8_t AUTH_REQ_BOND = 0x01;
41 constexpr uint8_t AUTH_REQ_MITM_MASK = 0x04;
42 constexpr uint8_t AUTH_REQ_SECURE_CONNECTIONS_MASK = 0x08;
43 constexpr uint8_t AUTH_REQ_KEYPRESS_MASK = 0x10;
44 constexpr uint8_t AUTH_REQ_CT2_MASK = 0x20;
45 constexpr uint8_t AUTH_REQ_RFU_MASK = 0xC0;
46
ToFacadeAddressWithType(hci::AddressWithType address)47 blueberry::facade::BluetoothAddressWithType ToFacadeAddressWithType(hci::AddressWithType address) {
48 blueberry::facade::BluetoothAddressWithType ret;
49
50 ret.mutable_address()->set_address(address.GetAddress().ToString());
51 ret.set_type(static_cast<blueberry::facade::BluetoothAddressTypeEnum>(address.GetAddressType()));
52
53 return ret;
54 }
55
56 } // namespace
57
58 class SecurityModuleFacadeService : public SecurityModuleFacade::Service,
59 public ISecurityManagerListener,
60 public UI,
61 public hci::AdvertisingCallback {
62 public:
SecurityModuleFacadeService(SecurityModule * security_module,L2capLeModule * l2cap_le_module,::bluetooth::os::Handler * security_handler,hci::LeAdvertisingManager * le_advertising_manager)63 SecurityModuleFacadeService(
64 SecurityModule* security_module,
65 L2capLeModule* l2cap_le_module,
66 ::bluetooth::os::Handler* security_handler,
67 hci::LeAdvertisingManager* le_advertising_manager)
68 : security_module_(security_module),
69 l2cap_le_module_(l2cap_le_module),
70 security_handler_(security_handler),
71 le_advertising_manager_(le_advertising_manager) {
72 security_module_->GetSecurityManager()->RegisterCallbackListener(this, security_handler_);
73 security_module_->GetSecurityManager()->SetUserInterfaceHandler(this, security_handler_);
74
75 /* In order to receive connect/disconenct event, we must register service */
76 l2cap_le_module_->GetFixedChannelManager()->RegisterService(
77 bluetooth::l2cap::kLastFixedChannel - 2,
78 common::BindOnce(&SecurityModuleFacadeService::OnL2capRegistrationCompleteLe, common::Unretained(this)),
79 common::Bind(&SecurityModuleFacadeService::OnConnectionOpenLe, common::Unretained(this)),
80 security_handler_);
81 }
82
OnL2capRegistrationCompleteLe(l2cap::le::FixedChannelManager::RegistrationResult result,std::unique_ptr<l2cap::le::FixedChannelService> le_smp_service)83 void OnL2capRegistrationCompleteLe(
84 l2cap::le::FixedChannelManager::RegistrationResult result,
85 std::unique_ptr<l2cap::le::FixedChannelService> le_smp_service) {
86 ASSERT_LOG(
87 result == bluetooth::l2cap::le::FixedChannelManager::RegistrationResult::SUCCESS,
88 "Failed to register to LE SMP Fixed Channel Service");
89 }
90
OnConnectionOpenLe(std::unique_ptr<l2cap::le::FixedChannel> channel)91 void OnConnectionOpenLe(std::unique_ptr<l2cap::le::FixedChannel> channel) {
92 channel->RegisterOnCloseCallback(
93 security_handler_,
94 common::BindOnce(
95 &SecurityModuleFacadeService::OnConnectionClosedLe, common::Unretained(this), channel->GetDevice()));
96 }
97
OnConnectionClosedLe(hci::AddressWithType address,hci::ErrorCode error_code)98 void OnConnectionClosedLe(hci::AddressWithType address, hci::ErrorCode error_code) {
99 SecurityHelperMsg disconnected;
100 *disconnected.mutable_peer() = ToFacadeAddressWithType(address);
101 disconnected.set_message_type(HelperMsgType::DEVICE_DISCONNECTED);
102 helper_events_.OnIncomingEvent(disconnected);
103 }
104
CreateBond(::grpc::ServerContext * context,const blueberry::facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)105 ::grpc::Status CreateBond(
106 ::grpc::ServerContext* context,
107 const blueberry::facade::BluetoothAddressWithType* request,
108 ::google::protobuf::Empty* response) override {
109 hci::Address peer;
110 ASSERT(hci::Address::FromString(request->address().address(), peer));
111 hci::AddressType peer_type = static_cast<hci::AddressType>(request->type());
112 security_module_->GetSecurityManager()->CreateBond(hci::AddressWithType(peer, peer_type));
113 return ::grpc::Status::OK;
114 }
115
CreateBondOutOfBand(::grpc::ServerContext * context,const OobDataBondMessage * request,::google::protobuf::Empty * response)116 ::grpc::Status CreateBondOutOfBand(
117 ::grpc::ServerContext* context, const OobDataBondMessage* request, ::google::protobuf::Empty* response) override {
118 hci::Address peer;
119 ASSERT(hci::Address::FromString(request->address().address().address(), peer));
120 hci::AddressType peer_type = static_cast<hci::AddressType>(request->address().type());
121 pairing::SimplePairingHash c;
122 pairing::SimplePairingRandomizer r;
123 std::copy(
124 std::begin(request->p192_data().confirmation_value()),
125 std::end(request->p192_data().confirmation_value()),
126 c.data());
127 std::copy(std::begin(request->p192_data().random_value()), std::end(request->p192_data().random_value()), r.data());
128 pairing::OobData p192_data(c, r);
129 std::copy(
130 std::begin(request->p256_data().confirmation_value()),
131 std::end(request->p256_data().confirmation_value()),
132 c.data());
133 std::copy(std::begin(request->p256_data().random_value()), std::end(request->p256_data().random_value()), r.data());
134 pairing::OobData p256_data(c, r);
135 security_module_->GetSecurityManager()->CreateBondOutOfBand(
136 hci::AddressWithType(peer, peer_type), p192_data, p256_data);
137 return ::grpc::Status::OK;
138 }
139
GetOutOfBandData(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::google::protobuf::Empty * response)140 ::grpc::Status GetOutOfBandData(
141 ::grpc::ServerContext* context,
142 const ::google::protobuf::Empty* request,
143 ::google::protobuf::Empty* response) override {
144 security_module_->GetSecurityManager()->GetOutOfBandData(
145 security_handler_->BindOnceOn(this, &SecurityModuleFacadeService::OobDataEventOccurred));
146 return ::grpc::Status::OK;
147 }
148
FetchGetOutOfBandDataEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<OobDataBondMessage> * writer)149 ::grpc::Status FetchGetOutOfBandDataEvents(
150 ::grpc::ServerContext* context,
151 const ::google::protobuf::Empty* request,
152 ::grpc::ServerWriter<OobDataBondMessage>* writer) override {
153 return oob_events_.RunLoop(context, writer);
154 }
155
CreateBondLe(::grpc::ServerContext * context,const blueberry::facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)156 ::grpc::Status CreateBondLe(
157 ::grpc::ServerContext* context,
158 const blueberry::facade::BluetoothAddressWithType* request,
159 ::google::protobuf::Empty* response) override {
160 hci::Address peer;
161 ASSERT(hci::Address::FromString(request->address().address(), peer));
162 hci::AddressType peer_type = static_cast<hci::AddressType>(request->type());
163 security_module_->GetSecurityManager()->CreateBondLe(hci::AddressWithType(peer, peer_type));
164 return ::grpc::Status::OK;
165 }
166
CancelBond(::grpc::ServerContext * context,const blueberry::facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)167 ::grpc::Status CancelBond(
168 ::grpc::ServerContext* context,
169 const blueberry::facade::BluetoothAddressWithType* request,
170 ::google::protobuf::Empty* response) override {
171 hci::Address peer;
172 ASSERT(hci::Address::FromString(request->address().address(), peer));
173 hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
174 security_module_->GetSecurityManager()->CancelBond(hci::AddressWithType(peer, peer_type));
175 return ::grpc::Status::OK;
176 }
177
RemoveBond(::grpc::ServerContext * context,const blueberry::facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)178 ::grpc::Status RemoveBond(
179 ::grpc::ServerContext* context,
180 const blueberry::facade::BluetoothAddressWithType* request,
181 ::google::protobuf::Empty* response) override {
182 hci::Address peer;
183 ASSERT(hci::Address::FromString(request->address().address(), peer));
184 hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
185 security_module_->GetSecurityManager()->RemoveBond(hci::AddressWithType(peer, peer_type));
186 return ::grpc::Status::OK;
187 }
188
FetchUiEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<UiMsg> * writer)189 ::grpc::Status FetchUiEvents(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
190 ::grpc::ServerWriter<UiMsg>* writer) override {
191 return ui_events_.RunLoop(context, writer);
192 }
193
SendUiCallback(::grpc::ServerContext * context,const UiCallbackMsg * request,::google::protobuf::Empty * response)194 ::grpc::Status SendUiCallback(::grpc::ServerContext* context, const UiCallbackMsg* request,
195 ::google::protobuf::Empty* response) override {
196 hci::Address peer;
197 ASSERT(hci::Address::FromString(request->address().address().address(), peer));
198 hci::AddressType remote_type = static_cast<hci::AddressType>(request->address().type());
199
200 switch (request->message_type()) {
201 case UiCallbackType::PASSKEY:
202 security_module_->GetSecurityManager()->OnPasskeyEntry(
203 hci::AddressWithType(peer, remote_type), request->numeric_value());
204 break;
205 case UiCallbackType::YES_NO:
206 security_module_->GetSecurityManager()->OnConfirmYesNo(hci::AddressWithType(peer, remote_type),
207 request->boolean());
208 break;
209 case UiCallbackType::PAIRING_PROMPT:
210 security_module_->GetSecurityManager()->OnPairingPromptAccepted(
211 hci::AddressWithType(peer, remote_type), request->boolean());
212 break;
213 case UiCallbackType::PIN:
214 LOG_INFO("PIN Callback");
215 security_module_->GetSecurityManager()->OnPinEntry(
216 hci::AddressWithType(peer, remote_type),
217 std::vector<uint8_t>(request->pin().cbegin(), request->pin().cend()));
218 break;
219 default:
220 LOG_ERROR("Unknown UiCallbackType %d", static_cast<int>(request->message_type()));
221 return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Unknown UiCallbackType");
222 }
223 return ::grpc::Status::OK;
224 }
225
FetchBondEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<BondMsg> * writer)226 ::grpc::Status FetchBondEvents(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
227 ::grpc::ServerWriter<BondMsg>* writer) override {
228 return bond_events_.RunLoop(context, writer);
229 }
230
FetchHelperEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<SecurityHelperMsg> * writer)231 ::grpc::Status FetchHelperEvents(
232 ::grpc::ServerContext* context,
233 const ::google::protobuf::Empty* request,
234 ::grpc::ServerWriter<SecurityHelperMsg>* writer) override {
235 return helper_events_.RunLoop(context, writer);
236 }
237
FetchAdvertisingCallbackEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<AdvertisingCallbackMsg> * writer)238 ::grpc::Status FetchAdvertisingCallbackEvents(
239 ::grpc::ServerContext* context,
240 const ::google::protobuf::Empty* request,
241 ::grpc::ServerWriter<AdvertisingCallbackMsg>* writer) override {
242 le_advertising_manager_->RegisterAdvertisingCallback(this);
243 return advertising_callback_events_.RunLoop(context, writer);
244 }
245
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t tx_power,AdvertisingStatus status)246 void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power, AdvertisingStatus status) {
247 AdvertisingCallbackMsg advertising_set_started;
248 advertising_set_started.set_message_type(AdvertisingCallbackMsgType::ADVERTISING_SET_STARTED);
249 advertising_set_started.set_advertising_started(AdvertisingSetStarted::STARTED);
250 advertising_set_started.set_advertiser_id(advertiser_id);
251 advertising_callback_events_.OnIncomingEvent(advertising_set_started);
252 }
253
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)254 void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
255 // Not used yet
256 }
257
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)258 void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
259 // Not used yet
260 }
261
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t status)262 void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) {
263 // Not used yet
264 }
265
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t tx_power,uint8_t status)266 void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power, uint8_t status) {
267 // Not used yet
268 }
269
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t status)270 void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t status) {
271 // Not used yet
272 }
273
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)274 void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
275 // Not used yet
276 }
277
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)278 void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
279 // Not used yet
280 }
281
OnOwnAddressRead(uint8_t advertiser_id,uint8_t address_type,Address address)282 void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, Address address) {
283 AdvertisingCallbackMsg get_own_address;
284 get_own_address.set_message_type(AdvertisingCallbackMsgType::OWN_ADDRESS_READ);
285 get_own_address.mutable_address()->set_address(address.ToString());
286 advertising_callback_events_.OnIncomingEvent(get_own_address);
287 }
288
SetIoCapability(::grpc::ServerContext * context,const IoCapabilityMessage * request,::google::protobuf::Empty * response)289 ::grpc::Status SetIoCapability(::grpc::ServerContext* context, const IoCapabilityMessage* request,
290 ::google::protobuf::Empty* response) override {
291 security_module_->GetFacadeConfigurationApi()->SetIoCapability(
292 static_cast<hci::IoCapability>(request->capability()));
293 return ::grpc::Status::OK;
294 }
295
SetLeIoCapability(::grpc::ServerContext * context,const LeIoCapabilityMessage * request,::google::protobuf::Empty * response)296 ::grpc::Status SetLeIoCapability(
297 ::grpc::ServerContext* context,
298 const LeIoCapabilityMessage* request,
299 ::google::protobuf::Empty* response) override {
300 security_module_->GetFacadeConfigurationApi()->SetLeIoCapability(
301 static_cast<security::IoCapability>(request->capabilities()));
302 return ::grpc::Status::OK;
303 }
304
SetAuthenticationRequirements(::grpc::ServerContext * context,const AuthenticationRequirementsMessage * request,::google::protobuf::Empty * response)305 ::grpc::Status SetAuthenticationRequirements(::grpc::ServerContext* context,
306 const AuthenticationRequirementsMessage* request,
307 ::google::protobuf::Empty* response) override {
308 security_module_->GetFacadeConfigurationApi()->SetAuthenticationRequirements(
309 static_cast<hci::AuthenticationRequirements>(request->requirement()));
310 return ::grpc::Status::OK;
311 }
312
SetLeAuthRequirements(::grpc::ServerContext * context,const LeAuthRequirementsMessage * request,::google::protobuf::Empty * response)313 ::grpc::Status SetLeAuthRequirements(
314 ::grpc::ServerContext* context,
315 const LeAuthRequirementsMessage* request,
316 ::google::protobuf::Empty* response) override {
317 uint8_t auth_req = request->bond() ? AUTH_REQ_BOND : AUTH_REQ_NO_BOND;
318
319 if (request->mitm()) auth_req |= AUTH_REQ_MITM_MASK;
320 if (request->secure_connections()) auth_req |= AUTH_REQ_SECURE_CONNECTIONS_MASK;
321 if (request->keypress()) auth_req |= AUTH_REQ_KEYPRESS_MASK;
322 if (request->ct2()) auth_req |= AUTH_REQ_CT2_MASK;
323 if (request->reserved_bits()) auth_req |= (((request->reserved_bits()) << 6) & AUTH_REQ_RFU_MASK);
324
325 security_module_->GetFacadeConfigurationApi()->SetLeAuthRequirements(auth_req);
326 return ::grpc::Status::OK;
327 }
328
SetLeMaximumEncryptionKeySize(::grpc::ServerContext * context,const LeMaximumEncryptionKeySizeMessage * request,::google::protobuf::Empty * response)329 ::grpc::Status SetLeMaximumEncryptionKeySize(
330 ::grpc::ServerContext* context,
331 const LeMaximumEncryptionKeySizeMessage* request,
332 ::google::protobuf::Empty* response) override {
333 security_module_->GetFacadeConfigurationApi()->SetLeMaximumEncryptionKeySize(
334 request->maximum_encryption_key_size());
335 return ::grpc::Status::OK;
336 }
337
SetLeOobDataPresent(::grpc::ServerContext * context,const LeOobDataPresentMessage * request,::google::protobuf::Empty * response)338 ::grpc::Status SetLeOobDataPresent(
339 ::grpc::ServerContext* context,
340 const LeOobDataPresentMessage* request,
341 ::google::protobuf::Empty* response) override {
342 security_module_->GetFacadeConfigurationApi()->SetLeOobDataPresent(
343 static_cast<OobDataFlag>(request->data_present()));
344 return ::grpc::Status::OK;
345 }
346
SetLeInitiatorAddressPolicy(::grpc::ServerContext * context,const blueberry::facade::hci::PrivacyPolicy * request,::google::protobuf::Empty * response)347 ::grpc::Status SetLeInitiatorAddressPolicy(
348 ::grpc::ServerContext* context,
349 const blueberry::facade::hci::PrivacyPolicy* request,
350 ::google::protobuf::Empty* response) override {
351 Address address = Address::kEmpty;
352 hci::LeAddressManager::AddressPolicy address_policy =
353 static_cast<hci::LeAddressManager::AddressPolicy>(request->address_policy());
354 if (address_policy == hci::LeAddressManager::AddressPolicy::USE_STATIC_ADDRESS ||
355 address_policy == hci::LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS) {
356 ASSERT(Address::FromString(request->address_with_type().address().address(), address));
357 }
358 hci::AddressWithType address_with_type(address, static_cast<hci::AddressType>(request->address_with_type().type()));
359 crypto_toolbox::Octet16 irk = {};
360 auto request_irk_length = request->rotation_irk().end() - request->rotation_irk().begin();
361 if (request_irk_length == crypto_toolbox::OCTET16_LEN) {
362 std::vector<uint8_t> irk_data(request->rotation_irk().begin(), request->rotation_irk().end());
363 std::copy_n(irk_data.begin(), crypto_toolbox::OCTET16_LEN, irk.begin());
364 } else {
365 ASSERT(request_irk_length == 0);
366 }
367 auto minimum_rotation_time = std::chrono::milliseconds(request->minimum_rotation_time());
368 auto maximum_rotation_time = std::chrono::milliseconds(request->maximum_rotation_time());
369 security_module_->GetSecurityManager()->SetLeInitiatorAddressPolicyForTest(
370 address_policy, address_with_type, irk, minimum_rotation_time, maximum_rotation_time);
371 return ::grpc::Status::OK;
372 }
373
FetchEnforceSecurityPolicyEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<EnforceSecurityPolicyMsg> * writer)374 ::grpc::Status FetchEnforceSecurityPolicyEvents(
375 ::grpc::ServerContext* context,
376 const ::google::protobuf::Empty* request,
377 ::grpc::ServerWriter<EnforceSecurityPolicyMsg>* writer) override {
378 return enforce_security_policy_events_.RunLoop(context, writer);
379 }
380
EnforceSecurityPolicy(::grpc::ServerContext * context,const SecurityPolicyMessage * request,::google::protobuf::Empty * response)381 ::grpc::Status EnforceSecurityPolicy(
382 ::grpc::ServerContext* context,
383 const SecurityPolicyMessage* request,
384 ::google::protobuf::Empty* response) override {
385 hci::Address peer;
386 ASSERT(hci::Address::FromString(request->address().address().address(), peer));
387 hci::AddressType peer_type = static_cast<hci::AddressType>(request->address().type());
388 hci::AddressWithType peer_with_type(peer, peer_type);
389 l2cap::classic::SecurityEnforcementInterface::ResultCallback callback =
390 security_handler_->BindOnceOn(this, &SecurityModuleFacadeService::EnforceSecurityPolicyEvent);
391 security_module_->GetFacadeConfigurationApi()->EnforceSecurityPolicy(
392 peer_with_type, static_cast<l2cap::classic::SecurityPolicy>(request->policy()), std::move(callback));
393 return ::grpc::Status::OK;
394 }
395
GetLeOutOfBandData(::grpc::ServerContext * context,const::google::protobuf::Empty * request,OobDataMessage * response)396 ::grpc::Status GetLeOutOfBandData(
397 ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, OobDataMessage* response) override {
398 std::array<uint8_t, 16> le_sc_c;
399 std::array<uint8_t, 16> le_sc_r;
400 security_module_->GetFacadeConfigurationApi()->GetLeOutOfBandData(&le_sc_c, &le_sc_r);
401
402 std::string le_sc_c_str(17, '\0');
403 std::copy(le_sc_c.begin(), le_sc_c.end(), le_sc_c_str.data());
404 response->set_confirmation_value(le_sc_c_str);
405
406 std::string le_sc_r_str(17, '\0');
407 std::copy(le_sc_r.begin(), le_sc_r.end(), le_sc_r_str.data());
408 response->set_random_value(le_sc_r_str);
409
410 return ::grpc::Status::OK;
411 }
412
SetOutOfBandData(::grpc::ServerContext * context,const OobDataMessage * request,::google::protobuf::Empty * response)413 ::grpc::Status SetOutOfBandData(
414 ::grpc::ServerContext* context, const OobDataMessage* request, ::google::protobuf::Empty* response) override {
415 hci::Address peer;
416 ASSERT(hci::Address::FromString(request->address().address().address(), peer));
417 hci::AddressType peer_type = static_cast<hci::AddressType>(request->address().type());
418 hci::AddressWithType peer_with_type(peer, peer_type);
419
420 // We can't simply iterate till end of string, because we have an empty byte added at the end. We know confirm and
421 // random are fixed size, 16 bytes
422 std::array<uint8_t, 16> le_sc_c;
423 auto req_le_sc_c = request->confirmation_value();
424 std::copy(req_le_sc_c.begin(), req_le_sc_c.begin() + 16, le_sc_c.data());
425
426 std::array<uint8_t, 16> le_sc_r;
427 auto req_le_sc_r = request->random_value();
428 std::copy(req_le_sc_r.begin(), req_le_sc_r.begin() + 16, le_sc_r.data());
429
430 security_module_->GetFacadeConfigurationApi()->SetOutOfBandData(peer_with_type, le_sc_c, le_sc_r);
431 return ::grpc::Status::OK;
432 }
433
FetchDisconnectEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<DisconnectMsg> * writer)434 ::grpc::Status FetchDisconnectEvents(
435 ::grpc::ServerContext* context,
436 const ::google::protobuf::Empty* request,
437 ::grpc::ServerWriter<DisconnectMsg>* writer) override {
438 security_module_->GetFacadeConfigurationApi()->SetDisconnectCallback(
439 common::Bind(&SecurityModuleFacadeService::DisconnectEventOccurred, common::Unretained(this)));
440 return disconnect_events_.RunLoop(context, writer);
441 }
442
OobDataEventOccurred(bluetooth::hci::CommandCompleteView packet)443 void OobDataEventOccurred(bluetooth::hci::CommandCompleteView packet) {
444 LOG_INFO("Got OOB Data event");
445 ASSERT(packet.IsValid());
446 auto cc = bluetooth::hci::ReadLocalOobDataCompleteView::Create(packet);
447 ASSERT(cc.IsValid());
448 OobDataBondMessage msg;
449 OobDataMessage p192;
450 // Just need this to satisfy the proto message
451 bluetooth::hci::AddressWithType peer;
452 *p192.mutable_address() = ToFacadeAddressWithType(peer);
453
454 auto c = cc.GetC();
455 p192.set_confirmation_value(c.data(), c.size());
456
457 auto r = cc.GetR();
458 p192.set_random_value(r.data(), r.size());
459
460 // Only the Extended version returns 256 also.
461 // The API has a parameter for both, so we set it
462 // empty and the module and test suite will ignore it.
463 OobDataMessage p256;
464 *p256.mutable_address() = ToFacadeAddressWithType(peer);
465
466 std::array<uint8_t, 16> empty_val;
467 p256.set_confirmation_value(empty_val.data(), empty_val.size());
468 p256.set_random_value(empty_val.data(), empty_val.size());
469
470 *msg.mutable_address() = ToFacadeAddressWithType(peer);
471 *msg.mutable_p192_data() = p192;
472 *msg.mutable_p256_data() = p256;
473 oob_events_.OnIncomingEvent(msg);
474 }
475
DisconnectEventOccurred(bluetooth::hci::AddressWithType peer)476 void DisconnectEventOccurred(bluetooth::hci::AddressWithType peer) {
477 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
478 DisconnectMsg msg;
479 *msg.mutable_address() = ToFacadeAddressWithType(peer);
480 disconnect_events_.OnIncomingEvent(msg);
481 }
482
DisplayPairingPrompt(const bluetooth::hci::AddressWithType & peer,std::string name)483 void DisplayPairingPrompt(const bluetooth::hci::AddressWithType& peer, std::string name) {
484 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
485 UiMsg display_yes_no;
486 *display_yes_no.mutable_peer() = ToFacadeAddressWithType(peer);
487 display_yes_no.set_message_type(UiMsgType::DISPLAY_PAIRING_PROMPT);
488 display_yes_no.set_unique_id(unique_id++);
489 ui_events_.OnIncomingEvent(display_yes_no);
490 }
491
DisplayConfirmValue(ConfirmationData data)492 virtual void DisplayConfirmValue(ConfirmationData data) {
493 const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType();
494 std::string name = data.GetName();
495 uint32_t numeric_value = data.GetNumericValue();
496 LOG_INFO("%s value = 0x%x", ADDRESS_TO_LOGGABLE_CSTR(peer), numeric_value);
497 UiMsg display_with_value;
498 *display_with_value.mutable_peer() = ToFacadeAddressWithType(peer);
499 display_with_value.set_message_type(UiMsgType::DISPLAY_YES_NO_WITH_VALUE);
500 display_with_value.set_numeric_value(numeric_value);
501 display_with_value.set_unique_id(unique_id++);
502 ui_events_.OnIncomingEvent(display_with_value);
503 }
504
DisplayYesNoDialog(ConfirmationData data)505 void DisplayYesNoDialog(ConfirmationData data) override {
506 const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType();
507 std::string name = data.GetName();
508 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
509 UiMsg display_yes_no;
510 *display_yes_no.mutable_peer() = ToFacadeAddressWithType(peer);
511 display_yes_no.set_message_type(UiMsgType::DISPLAY_YES_NO);
512 display_yes_no.set_unique_id(unique_id++);
513 ui_events_.OnIncomingEvent(display_yes_no);
514 }
515
DisplayPasskey(ConfirmationData data)516 void DisplayPasskey(ConfirmationData data) override {
517 const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType();
518 std::string name = data.GetName();
519 uint32_t passkey = data.GetNumericValue();
520 LOG_INFO("%s value = 0x%x", ADDRESS_TO_LOGGABLE_CSTR(peer), passkey);
521 UiMsg display_passkey;
522 *display_passkey.mutable_peer() = ToFacadeAddressWithType(peer);
523 display_passkey.set_message_type(UiMsgType::DISPLAY_PASSKEY);
524 display_passkey.set_numeric_value(passkey);
525 display_passkey.set_unique_id(unique_id++);
526 ui_events_.OnIncomingEvent(display_passkey);
527 }
528
DisplayEnterPasskeyDialog(ConfirmationData data)529 void DisplayEnterPasskeyDialog(ConfirmationData data) override {
530 const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType();
531 std::string name = data.GetName();
532 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
533 UiMsg display_passkey_input;
534 *display_passkey_input.mutable_peer() = ToFacadeAddressWithType(peer);
535 display_passkey_input.set_message_type(UiMsgType::DISPLAY_PASSKEY_ENTRY);
536 display_passkey_input.set_unique_id(unique_id++);
537 ui_events_.OnIncomingEvent(display_passkey_input);
538 }
539
DisplayEnterPinDialog(ConfirmationData data)540 void DisplayEnterPinDialog(ConfirmationData data) override {
541 const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType();
542 std::string name = data.GetName();
543 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
544 UiMsg display_pin_input;
545 *display_pin_input.mutable_peer() = ToFacadeAddressWithType(peer);
546 display_pin_input.set_message_type(UiMsgType::DISPLAY_PIN_ENTRY);
547 display_pin_input.set_unique_id(unique_id++);
548 ui_events_.OnIncomingEvent(display_pin_input);
549 }
550
Cancel(const bluetooth::hci::AddressWithType & peer)551 void Cancel(const bluetooth::hci::AddressWithType& peer) override {
552 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
553 UiMsg display_cancel;
554 *display_cancel.mutable_peer() = ToFacadeAddressWithType(peer);
555 display_cancel.set_message_type(UiMsgType::DISPLAY_CANCEL);
556 display_cancel.set_unique_id(unique_id++);
557 ui_events_.OnIncomingEvent(display_cancel);
558 }
559
OnDeviceBonded(hci::AddressWithType peer)560 void OnDeviceBonded(hci::AddressWithType peer) override {
561 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
562 BondMsg bonded;
563 *bonded.mutable_peer() = ToFacadeAddressWithType(peer);
564 bonded.set_message_type(BondMsgType::DEVICE_BONDED);
565 bond_events_.OnIncomingEvent(bonded);
566 }
567
OnEncryptionStateChanged(hci::EncryptionChangeView encryption_change_view)568 void OnEncryptionStateChanged(hci::EncryptionChangeView encryption_change_view) override {}
569
OnDeviceUnbonded(hci::AddressWithType peer)570 void OnDeviceUnbonded(hci::AddressWithType peer) override {
571 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
572 BondMsg unbonded;
573 *unbonded.mutable_peer() = ToFacadeAddressWithType(peer);
574 unbonded.set_message_type(BondMsgType::DEVICE_UNBONDED);
575 bond_events_.OnIncomingEvent(unbonded);
576 }
577
OnDeviceBondFailed(hci::AddressWithType peer,PairingFailure status)578 void OnDeviceBondFailed(hci::AddressWithType peer, PairingFailure status) override {
579 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(peer));
580 BondMsg bond_failed;
581 *bond_failed.mutable_peer() = ToFacadeAddressWithType(peer);
582 bond_failed.set_message_type(BondMsgType::DEVICE_BOND_FAILED);
583 bond_failed.set_reason(static_cast<uint8_t>(status.reason));
584 bond_events_.OnIncomingEvent(bond_failed);
585 }
586
EnforceSecurityPolicyEvent(bool result)587 void EnforceSecurityPolicyEvent(bool result) {
588 EnforceSecurityPolicyMsg msg;
589 msg.set_result(result);
590 enforce_security_policy_events_.OnIncomingEvent(msg);
591 }
592
593 private:
594 SecurityModule* security_module_;
595 L2capLeModule* l2cap_le_module_;
596 ::bluetooth::os::Handler* security_handler_;
597 hci::LeAdvertisingManager* le_advertising_manager_;
598 ::bluetooth::grpc::GrpcEventQueue<UiMsg> ui_events_{"UI events"};
599 ::bluetooth::grpc::GrpcEventQueue<BondMsg> bond_events_{"Bond events"};
600 ::bluetooth::grpc::GrpcEventQueue<SecurityHelperMsg> helper_events_{"Events that don't fit any other category"};
601 ::bluetooth::grpc::GrpcEventQueue<EnforceSecurityPolicyMsg> enforce_security_policy_events_{
602 "Enforce Security Policy Events"};
603 ::bluetooth::grpc::GrpcEventQueue<DisconnectMsg> disconnect_events_{"Disconnect events"};
604 ::bluetooth::grpc::GrpcEventQueue<OobDataBondMessage> oob_events_{"OOB Data events"};
605 ::bluetooth::grpc::GrpcEventQueue<AdvertisingCallbackMsg> advertising_callback_events_{"Advertising callback events"};
606 uint32_t unique_id{1};
607 std::map<uint32_t, common::OnceCallback<void(bool)>> user_yes_no_callbacks_;
608 std::map<uint32_t, common::OnceCallback<void(uint32_t)>> user_passkey_callbacks_;
609 };
610
ListDependencies(ModuleList * list) const611 void SecurityModuleFacadeModule::ListDependencies(ModuleList* list) const {
612 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
613 list->add<SecurityModule>();
614 list->add<L2capLeModule>();
615 list->add<hci::LeAdvertisingManager>();
616 }
617
Start()618 void SecurityModuleFacadeModule::Start() {
619 ::bluetooth::grpc::GrpcFacadeModule::Start();
620 service_ = new SecurityModuleFacadeService(
621 GetDependency<SecurityModule>(),
622 GetDependency<L2capLeModule>(),
623 GetHandler(),
624 GetDependency<hci::LeAdvertisingManager>());
625 }
626
Stop()627 void SecurityModuleFacadeModule::Stop() {
628 delete service_;
629 ::bluetooth::grpc::GrpcFacadeModule::Stop();
630 }
631
GetService() const632 ::grpc::Service* SecurityModuleFacadeModule::GetService() const {
633 return service_;
634 }
635
636 const ModuleFactory SecurityModuleFacadeModule::Factory =
__anone4ce019c0202() 637 ::bluetooth::ModuleFactory([]() { return new SecurityModuleFacadeModule(); });
638
639 } // namespace security
640 } // namespace bluetooth
641