Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit defede36 authored by Martin Brabham's avatar Martin Brabham
Browse files

SM: Implement an attempt to upgrade the link security

When an profile/application registers with L2CAP it will define
a required security level.  L2CAP will call in to enforce the level
and we will attempt to achieve this level if we have not already
obtained the level of security required.

Bug: 145638034
Test: cert/run --host --test_filter=SecurityTest
Tag: #gd-refactor
Change-Id: I895fe2722bd74460ab5bd52e37bc0e9cbb9b4c0f
parent 8932ab7f
Loading
Loading
Loading
Loading
+32 −7
Original line number Diff line number Diff line
@@ -313,10 +313,16 @@ void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address, Pairing
    pairing_handler_map_.erase(entry);
    security_manager_channel_->Release(address);
  }
  auto remote = hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS);
  auto cb_entry = enforce_security_policy_callback_map_.find(remote);
  if (cb_entry != enforce_security_policy_callback_map_.end()) {
    this->InternalEnforceSecurityPolicy(remote, cb_entry->second.first, std::move(cb_entry->second.second), false);
    enforce_security_policy_callback_map_.erase(cb_entry);
  }
  if (!std::holds_alternative<PairingFailure>(status)) {
    NotifyDeviceBonded(hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS));
    NotifyDeviceBonded(remote);
  } else {
    NotifyDeviceBondFailed(hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS), status);
    NotifyDeviceBondFailed(remote, status);
  }
}

@@ -565,9 +571,11 @@ void SecurityManagerImpl::SetOobDataPresent(hci::OobDataPresent data_present) {
  this->local_oob_data_present_ = data_present;
}

void SecurityManagerImpl::EnforceSecurityPolicy(
    hci::AddressWithType remote, l2cap::classic::SecurityPolicy policy,
    l2cap::classic::SecurityEnforcementInterface::ResultCallback result_callback) {
void SecurityManagerImpl::InternalEnforceSecurityPolicy(
    hci::AddressWithType remote,
    l2cap::classic::SecurityPolicy policy,
    l2cap::classic::SecurityEnforcementInterface::ResultCallback result_callback,
    bool try_meet_requirements) {
  bool result = false;
  auto record = this->security_database_.FindOrCreate(remote);
  switch (policy) {
@@ -582,12 +590,29 @@ void SecurityManagerImpl::EnforceSecurityPolicy(
      result = true;
      break;
  }
  if (!result) {
    // TODO(optedoblivion): Start pairing process to meet requirements
  if (!result && try_meet_requirements) {
    auto entry = enforce_security_policy_callback_map_.find(remote);
    if (entry != enforce_security_policy_callback_map_.end()) {
      LOG_WARN("Callback already pending for remote: '%s' !", remote.ToString().c_str());
    } else {
      enforce_security_policy_callback_map_.emplace(
          remote,
          std::pair<l2cap::classic::SecurityPolicy, l2cap::classic::SecurityEnforcementInterface::ResultCallback>(
              policy, std::move(result_callback)));
      DispatchPairingHandler(record, true);
    }
    return;
  }
  result_callback.Invoke(result);
}

void SecurityManagerImpl::EnforceSecurityPolicy(
    hci::AddressWithType remote,
    l2cap::classic::SecurityPolicy policy,
    l2cap::classic::SecurityEnforcementInterface::ResultCallback result_callback) {
  this->InternalEnforceSecurityPolicy(remote, policy, std::move(result_callback), true);
}

void SecurityManagerImpl::EnforceLeSecurityPolicy(
    hci::AddressWithType remote, l2cap::le::SecurityPolicy policy,
    l2cap::le::SecurityEnforcementInterface::ResultCallback result_callback) {
+9 −0
Original line number Diff line number Diff line
@@ -201,6 +201,11 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub
  void OnHciLeEvent(hci::LeMetaEventView event);
  LeFixedChannelEntry* FindStoredLeChannel(const hci::AddressWithType& device);
  bool EraseStoredLeChannel(const hci::AddressWithType& device);
  void InternalEnforceSecurityPolicy(
      hci::AddressWithType remote,
      l2cap::classic::SecurityPolicy policy,
      l2cap::classic::SecurityEnforcementInterface::ResultCallback result_callback,
      bool try_meet_requirements);

  os::Handler* security_handler_ __attribute__((unused));
  l2cap::le::L2capLeModule* l2cap_le_module_ __attribute__((unused));
@@ -215,6 +220,10 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub
  hci::OobDataPresent local_oob_data_present_ = kDefaultOobDataPresent;
  security::IoCapability local_le_io_capability_ = security::IoCapability::NO_INPUT_NO_OUTPUT;
  uint8_t local_le_auth_req_ = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc;
  std::unordered_map<
      hci::AddressWithType,
      std::pair<l2cap::classic::SecurityPolicy, l2cap::classic::SecurityEnforcementInterface::ResultCallback>>
      enforce_security_policy_callback_map_;

  struct {
    hci::AddressWithType address_;