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