BLE: Factorize peripheral privacy applied when connected

pull/13759/head
Vincent Coubard 2020-09-25 17:22:16 +01:00
parent e4b317c1b1
commit 76f89f6f89
2 changed files with 68 additions and 35 deletions

View File

@ -2365,6 +2365,9 @@ void Gap::signal_connection_complete(
/* if successful then proceed to call the handler immediately same as for when privacy is disabled */
if (address_resolved) {
if (!apply_peripheral_privacy_connection_policy(event)) {
return;
}
report_internal_connection_complete(event);
_event_handler->onConnectionComplete(event);
} else {
@ -2398,15 +2401,64 @@ void Gap::signal_connection_complete(
}
#if BLE_FEATURE_PRIVACY
bool Gap::apply_peripheral_privacy_connection_policy(
const ConnectionCompleteEvent &event
)
{
#if BLE_ROLE_PERIPHERAL
if (event.getOwnRole() != connection_role_t::PERIPHERAL) {
return true;
}
if (event.getPeerAddressType() != peer_address_type_t::RANDOM) {
return true;
}
if (!is_random_private_resolvable_address(event.getPeerAddress())) {
return true;
}
auto connection_handle = event.getConnectionHandle();
switch (_peripheral_privacy_configuration.resolution_strategy) {
case peripheral_privacy_configuration_t::REJECT_NON_RESOLVED_ADDRESS:
_pal_gap.disconnect(
connection_handle,
local_disconnection_reason_t::AUTHENTICATION_FAILURE
);
return false;
case peripheral_privacy_configuration_t::PERFORM_PAIRING_PROCEDURE:
_event_queue.post([connection_handle] {
BLE::Instance().securityManager().requestAuthentication(connection_handle);
});
return true;
case peripheral_privacy_configuration_t::PERFORM_AUTHENTICATION_PROCEDURE:
_event_queue.post([connection_handle] {
BLE::Instance().securityManager().setLinkSecurity(
connection_handle,
ble::SecurityManager::SecurityMode_t::SECURITY_MODE_ENCRYPTION_WITH_MITM
);
});
return true;
default:
return true;
}
#else
return true;
#endif
}
void Gap::conclude_signal_connection_complete_after_address_resolution(
ConnectionCompleteEvent &event,
target_peer_address_type_t identity_address_type,
const address_t *identity_address
)
{
#if BLE_ROLE_PERIPHERAL
bool resolvable_address_not_known = false;
#endif // BLE_ROLE_PERIPHERAL
/* fix the event addresses */
if (identity_address) {
/* move old address to resolvable address */
@ -2418,42 +2470,13 @@ void Gap::conclude_signal_connection_complete_after_address_resolution(
peer_address_type_t::RANDOM_STATIC_IDENTITY
: peer_address_type_t::PUBLIC_IDENTITY);
}
#if BLE_ROLE_PERIPHERAL
if (!identity_address) {
if (_peripheral_privacy_configuration.resolution_strategy ==
peripheral_privacy_configuration_t::REJECT_NON_RESOLVED_ADDRESS) {
// Reject connection request - the user will get notified through a callback
_pal_gap.disconnect(
event.getConnectionHandle(),
local_disconnection_reason_t::AUTHENTICATION_FAILURE
);
return;
}
resolvable_address_not_known = true;
if (!apply_peripheral_privacy_connection_policy(event)) {
return;
}
#endif // BLE_ROLE_PERIPHERAL
report_internal_connection_complete(event);
_event_handler->onConnectionComplete(event);
#if BLE_ROLE_PERIPHERAL
#if BLE_FEATURE_SECURITY
if (resolvable_address_not_known) {
ble::SecurityManager &sm = BLE::Instance().securityManager();
if (_peripheral_privacy_configuration.resolution_strategy ==
peripheral_privacy_configuration_t::PERFORM_PAIRING_PROCEDURE) {
// Request authentication to start pairing procedure
sm.requestAuthentication(event.getConnectionHandle());
} else if (_peripheral_privacy_configuration.resolution_strategy ==
peripheral_privacy_configuration_t::PERFORM_AUTHENTICATION_PROCEDURE) {
sm.setLinkSecurity(
event.getConnectionHandle(),
ble::SecurityManager::SecurityMode_t::SECURITY_MODE_ENCRYPTION_WITH_MITM
);
}
}
#endif // BLE_FEATURE_SECURITY
#endif // BLE_ROLE_PERIPHERAL
}
#endif // BLE_FEATURE_PRIVACY
#endif // BLE_FEATURE_CONNECTABLE

View File

@ -611,6 +611,16 @@ private:
void signal_connection_complete(ConnectionCompleteEvent& report);
#if BLE_FEATURE_PRIVACY
/**
* Apply the privacy policies when the local peripheral is connected.
* @param event The connection event
* @return true if the policy process has been successful and false if the
* it fails meaning the process connection shouldn't continue.
*/
bool apply_peripheral_privacy_connection_policy(
const ConnectionCompleteEvent &event
);
/** Pass the connection complete event to the application after privacy resolution completed.
*
* @param event Event to be passed to the user application.