BLE: SecurityManager PIMPL

pull/13475/head
Vincent Coubard 2020-08-21 10:00:50 +01:00
parent e3cf59e6cd
commit 2b48d4826e
4 changed files with 333 additions and 60 deletions

View File

@ -187,8 +187,11 @@ namespace ble {
*
*/
#if !defined(DOXYGEN_ONLY)
namespace interface {
namespace impl {
class SecurityManager;
}
#endif // !defined(DOXYGEN_ONLY)
class SecurityManager
{
public:
@ -895,16 +898,13 @@ public:
* @deprecated use the enum in ble namespace */
typedef ble::Keypress_t Keypress_t;
#endif // !defined(DOXYGEN_ONLY)
private:
impl::SecurityManager *impl;
};
#if !defined(DOXYGEN_ONLY)
} // namespace interface
#endif // !defined(DOXYGEN_ONLY)
} // ble
/* This includes the concrete class implementation, to provide a an alternative API implementation
* disable ble-api-implementation and place your header in a path with the same structure */
#include "ble/internal/SecurityManagerImpl.h"
} // ble
/** @deprecated Use the namespaced ble::SecurityManager instead of the global SecurityManager. */
using ble::SecurityManager;

View File

@ -36,32 +36,41 @@
#include "ble/SecurityManager.h"
namespace ble {
namespace impl {
class BLEInstanceBase;
//class BLEInstanceBase;
class SecurityManager :
public ble::interface::SecurityManager,
public ble::PalSecurityManagerEventHandler,
public ble::PalConnectionMonitorEventHandler,
public ble::PalSigningMonitorEventHandler
{
public ble::PalSigningMonitorEventHandler {
friend class ble::PalConnectionMonitorEventHandler;
friend BLEInstanceBase;
friend ::ble::BLEInstanceBase;
friend PalGenericAccessService;
friend PalSecurityManager;
using SecurityIOCapabilities_t = ble::SecurityManager::SecurityIOCapabilities_t;
using SecurityMode_t = ble::SecurityManager::SecurityMode_t;
using SecurityManagerShutdownCallback_t = ble::SecurityManager::SecurityManagerShutdownCallback_t;
using SecurityManagerShutdownCallbackChain_t = ble::SecurityManager::SecurityManagerShutdownCallbackChain_t;
using EventHandler = ble::SecurityManager::EventHandler;
using Passkey_t = ble::SecurityManager::Passkey_t ;
static auto constexpr IO_CAPS_NONE = ble::SecurityManager::IO_CAPS_NONE;
public:
////////////////////////////////////////////////////////////////////////////
// SM lifecycle management
//
ble_error_t init(
bool enableBonding = true,
bool requireMITM = true,
SecurityIOCapabilities_t iocaps = IO_CAPS_NONE,
const Passkey_t passkey = NULL,
bool signing = true,
const char *dbFilepath = NULL
bool enableBonding = true,
bool requireMITM = true,
SecurityIOCapabilities_t iocaps = IO_CAPS_NONE,
const Passkey_t passkey = NULL,
bool signing = true,
const char *dbFilepath = NULL
);
ble_error_t setDatabaseFilepath(const char *dbFilepath = NULL);
@ -115,6 +124,7 @@ public:
#if BLE_FEATURE_SIGNING
ble_error_t enableSigning(ble::connection_handle_t connectionHandle, bool enabled = true);
#endif // BLE_FEATURE_SIGNING
ble_error_t setHintFutureRoleReversal(bool enable = true);
@ -156,7 +166,11 @@ public:
ble_error_t legacyPairingOobReceived(const ble::address_t *address, const ble::oob_tk_t *tk);
ble_error_t oobReceived(const ble::address_t *address, const ble::oob_lesc_value_t *random, const ble::oob_confirm_t *confirm);
ble_error_t oobReceived(
const ble::address_t *address,
const ble::oob_lesc_value_t *random,
const ble::oob_confirm_t *confirm
);
////////////////////////////////////////////////////////////////////////////
// Keys
@ -175,14 +189,14 @@ public:
/* Event callback handlers. */
public:
void onShutdown(const SecurityManagerShutdownCallback_t& callback);
void onShutdown(const SecurityManagerShutdownCallback_t &callback);
template <typename T>
template<typename T>
void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *));
SecurityManagerShutdownCallbackChain_t& onShutdown();
SecurityManagerShutdownCallbackChain_t &onShutdown();
void setSecurityManagerEventHandler(EventHandler* handler);
void setSecurityManagerEventHandler(EventHandler *handler);
/* ===================================================================== */
/* private implementation follows */
@ -433,7 +447,8 @@ private:
private:
/* Disallow copy and assignment. */
SecurityManager(const SecurityManager &);
SecurityManager& operator=(const SecurityManager &);
SecurityManager &operator=(const SecurityManager &);
SecurityManager(
PalSecurityManager &palImpl,
@ -493,12 +508,12 @@ private:
void enable_encryption_cb(
ble::SecurityDb::entry_handle_t entry,
const SecurityEntryKeys_t* entryKeys
const SecurityEntryKeys_t *entryKeys
);
void set_ltk_cb(
SecurityDb::entry_handle_t entry,
const SecurityEntryKeys_t* entryKeys
const SecurityEntryKeys_t *entryKeys
);
void return_csrk_cb(
@ -536,11 +551,11 @@ private:
void on_security_entry_retrieved(
SecurityDb::entry_handle_t entry,
const SecurityEntryIdentity_t* identity
const SecurityEntryIdentity_t *identity
);
void on_identity_list_retrieved(
Span<SecurityEntryIdentity_t>& identity_list,
Span<SecurityEntryIdentity_t> &identity_list,
size_t count
);
@ -548,16 +563,23 @@ private:
struct ControlBlock_t {
ControlBlock_t();
KeyDistribution get_initiator_key_distribution() {
KeyDistribution get_initiator_key_distribution()
{
return KeyDistribution(initiator_key_distribution);
};
KeyDistribution get_responder_key_distribution() {
KeyDistribution get_responder_key_distribution()
{
return KeyDistribution(responder_key_distribution);
};
void set_initiator_key_distribution(KeyDistribution mask) {
void set_initiator_key_distribution(KeyDistribution mask)
{
initiator_key_distribution = mask.value();
};
void set_responder_key_distribution(KeyDistribution mask) {
void set_responder_key_distribution(KeyDistribution mask)
{
responder_key_distribution = mask.value();
};
@ -567,46 +589,46 @@ private:
address_t local_address; /**< address used for connection, possibly different from identity */
private:
uint8_t initiator_key_distribution:4;
uint8_t responder_key_distribution:4;
uint8_t initiator_key_distribution: 4;
uint8_t responder_key_distribution: 4;
public:
uint8_t connected:1;
uint8_t authenticated:1; /**< have we turned encryption on during this connection */
uint8_t is_master:1;
uint8_t connected: 1;
uint8_t authenticated: 1; /**< have we turned encryption on during this connection */
uint8_t is_master: 1;
uint8_t encryption_requested:1;
uint8_t encryption_failed:1;
uint8_t encrypted:1;
uint8_t signing_requested:1;
uint8_t signing_override_default:1;
uint8_t encryption_requested: 1;
uint8_t encryption_failed: 1;
uint8_t encrypted: 1;
uint8_t signing_requested: 1;
uint8_t signing_override_default: 1;
uint8_t mitm_requested:1;
uint8_t mitm_performed:1; /**< keys exchange will have MITM protection */
uint8_t mitm_requested: 1;
uint8_t mitm_performed: 1; /**< keys exchange will have MITM protection */
uint8_t attempt_oob:1;
uint8_t oob_mitm_protection:1;
uint8_t oob_present:1;
uint8_t legacy_pairing_oob_request_pending:1;
uint8_t attempt_oob: 1;
uint8_t oob_mitm_protection: 1;
uint8_t oob_present: 1;
uint8_t legacy_pairing_oob_request_pending: 1;
uint8_t csrk_failures:2;
uint8_t csrk_failures: 2;
};
/* list management */
ControlBlock_t* acquire_control_block(connection_handle_t connection);
ControlBlock_t *acquire_control_block(connection_handle_t connection);
ControlBlock_t* get_control_block(connection_handle_t connection);
ControlBlock_t *get_control_block(connection_handle_t connection);
ControlBlock_t* get_control_block(const address_t &peer_address);
ControlBlock_t *get_control_block(const address_t &peer_address);
ControlBlock_t* get_control_block(SecurityDb::entry_handle_t db_entry);
ControlBlock_t *get_control_block(SecurityDb::entry_handle_t db_entry);
void release_control_block(ControlBlock_t* entry);
void release_control_block(ControlBlock_t *entry);
private:
SecurityManagerShutdownCallbackChain_t shutdownCallChain;
EventHandler* eventHandler;
EventHandler defaultEventHandler;
EventHandler *eventHandler;
EventHandler defaultEventHandler;
PalSecurityManager &_pal;
PalConnectionMonitor &_connection_monitor;
@ -634,6 +656,7 @@ private:
ControlBlock_t _control_blocks[MAX_CONTROL_BLOCKS];
};
} // namespace impl
} // ble
#endif /*IMPL_SECURITY_MANAGER_H_*/

View File

@ -18,7 +18,7 @@
#include "BLERoles.h"
#include "ble/SecurityManager.h"
#include "ble/internal/SecurityManagerImpl.h"
#include "ble/internal/PalSecurityManager.h"
#include "ble/internal/MemorySecurityDb.h"
#include "ble/internal/FileSecurityDb.h"
@ -30,6 +30,33 @@ using ble::KeyDistribution;
using ble::connection_peer_address_type_t;
namespace ble {
namespace impl {
namespace {
static constexpr auto SECURITY_MODE_ENCRYPTION_OPEN_LINK =
ble::SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
static constexpr auto SECURITY_MODE_ENCRYPTION_NO_MITM =
ble::SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
static constexpr auto SECURITY_MODE_ENCRYPTION_WITH_MITM =
ble::SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
static constexpr auto SECURITY_MODE_SIGNED_NO_MITM =
ble::SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
static constexpr auto SECURITY_MODE_SIGNED_WITH_MITM =
ble::SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
using SecurityCompletionStatus_t = ble::SecurityManager::SecurityCompletionStatus_t;
static constexpr auto SEC_STATUS_TIMEOUT =
ble::SecurityManager::SEC_STATUS_TIMEOUT;
static constexpr auto SEC_STATUS_SUCCESS =
ble::SecurityManager::SEC_STATUS_SUCCESS;
}
/* Implements PalSecurityManager */
@ -95,7 +122,9 @@ ble_error_t SecurityManager::init(
_connection_monitor.set_connection_event_handler(this);
#endif
#if BLE_FEATURE_SIGNING
_signing_monitor.set_signing_event_handler(this);
// TODO: FIXME
// _signing_monitor.set_signing_event_handler(this);
_signing_monitor.set_signing_event_handler(nullptr);
#endif
_pal.set_event_handler(this);
@ -152,7 +181,9 @@ ble_error_t SecurityManager::reset(void)
_pal.reset();
/* Notify that the instance is about to shutdown */
shutdownCallChain.call(this);
// TODO: FIXME
// shutdownCallChain.call(this);
shutdownCallChain.call(nullptr);
shutdownCallChain.clear();
eventHandler = &defaultEventHandler;
@ -2026,4 +2057,5 @@ void SecurityManager::setSecurityManagerEventHandler(EventHandler* handler)
}
}
} /* namespace impl */
} /* namespace ble */

View File

@ -0,0 +1,218 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/SecurityManager.h"
#include "ble/internal/SecurityManagerImpl.h"
namespace ble {
ble_error_t SecurityManager::init(
bool enableBonding,
bool requireMITM,
SecurityIOCapabilities_t iocaps,
const Passkey_t passkey,
bool signing,
const char *dbFilepath
)
{
return impl->init(enableBonding, requireMITM, iocaps, passkey, signing, dbFilepath);
}
ble_error_t SecurityManager::setDatabaseFilepath(const char *dbFilepath)
{
return impl->setDatabaseFilepath(dbFilepath);
}
ble_error_t SecurityManager::reset()
{
return impl->reset();
}
ble_error_t SecurityManager::preserveBondingStateOnReset(bool enable)
{
return impl->preserveBondingStateOnReset(enable);
}
ble_error_t SecurityManager::purgeAllBondingState()
{
return impl->purgeAllBondingState();
}
ble_error_t SecurityManager::generateWhitelistFromBondTable(::ble::whitelist_t *whitelist) const
{
return impl->generateWhitelistFromBondTable(whitelist);
}
ble_error_t SecurityManager::requestPairing(ble::connection_handle_t connectionHandle)
{
return impl->requestPairing(connectionHandle);
}
ble_error_t SecurityManager::acceptPairingRequest(ble::connection_handle_t connectionHandle)
{
return impl->acceptPairingRequest(connectionHandle);
}
ble_error_t SecurityManager::cancelPairingRequest(ble::connection_handle_t connectionHandle)
{
return impl->cancelPairingRequest(connectionHandle);
}
ble_error_t SecurityManager::setPairingRequestAuthorisation(bool required)
{
return impl->setPairingRequestAuthorisation(required);
}
ble_error_t SecurityManager::getPeerIdentity(ble::connection_handle_t connectionHandle)
{
return impl->getPeerIdentity(connectionHandle);
}
ble_error_t SecurityManager::allowLegacyPairing(bool allow)
{
return impl->allowLegacyPairing(allow);
}
ble_error_t SecurityManager::getSecureConnectionsSupport(bool *enabled)
{
return impl->getSecureConnectionsSupport(enabled);
}
ble_error_t SecurityManager::setIoCapability(SecurityIOCapabilities_t iocaps)
{
return impl->setIoCapability(iocaps);
}
ble_error_t SecurityManager::setDisplayPasskey(const Passkey_t passkey)
{
return impl->setDisplayPasskey(passkey);
}
ble_error_t SecurityManager::setLinkSecurity(ble::connection_handle_t connectionHandle, SecurityMode_t securityMode)
{
return impl->setLinkSecurity(connectionHandle, securityMode);
}
ble_error_t SecurityManager::setKeypressNotification(bool enabled)
{
return impl->setKeypressNotification(enabled);
}
#if BLE_FEATURE_SIGNING
ble_error_t SecurityManager::enableSigning(ble::connection_handle_t connectionHandle, bool enabled)
{
return impl->enableSigning(connectionHandle, enabled);
}
#endif // BLE_FEATURE_SIGNING
ble_error_t SecurityManager::setHintFutureRoleReversal(bool enable)
{
return impl->setHintFutureRoleReversal(enable);
}
ble_error_t SecurityManager::getLinkEncryption(ble::connection_handle_t connectionHandle, ble::link_encryption_t *encryption)
{
return impl->getLinkEncryption(connectionHandle, encryption);
}
ble_error_t SecurityManager::setLinkEncryption(ble::connection_handle_t connectionHandle, ble::link_encryption_t encryption)
{
return impl->setLinkEncryption(connectionHandle, encryption);
}
ble_error_t SecurityManager::setEncryptionKeyRequirements(uint8_t minimumByteSize, uint8_t maximumByteSize)
{
return impl->setEncryptionKeyRequirements(minimumByteSize, maximumByteSize);
}
ble_error_t SecurityManager::getEncryptionKeySize(
connection_handle_t connectionHandle,
uint8_t *size
)
{
return impl->getEncryptionKeySize(connectionHandle, size);
}
ble_error_t SecurityManager::requestAuthentication(ble::connection_handle_t connectionHandle)
{
return impl->requestAuthentication(connectionHandle);
}
ble_error_t SecurityManager::generateOOB(const ble::address_t *address)
{
return impl->generateOOB(address);
}
ble_error_t SecurityManager::setOOBDataUsage(ble::connection_handle_t connectionHandle, bool useOOB, bool OOBProvidesMITM)
{
return impl->setOOBDataUsage(connectionHandle, useOOB, OOBProvidesMITM);
}
ble_error_t SecurityManager::confirmationEntered(ble::connection_handle_t connectionHandle, bool confirmation)
{
return impl->confirmationEntered(connectionHandle, confirmation);
}
ble_error_t SecurityManager::passkeyEntered(ble::connection_handle_t connectionHandle, Passkey_t passkey)
{
return impl->passkeyEntered(connectionHandle, passkey);
}
ble_error_t SecurityManager::sendKeypressNotification(ble::connection_handle_t connectionHandle, ble::Keypress_t keypress)
{
return impl->sendKeypressNotification(connectionHandle, keypress);
}
ble_error_t SecurityManager::legacyPairingOobReceived(const ble::address_t *address, const ble::oob_tk_t *tk)
{
return impl->legacyPairingOobReceived(address, tk);
}
ble_error_t SecurityManager::oobReceived(const ble::address_t *address, const ble::oob_lesc_value_t *random, const ble::oob_confirm_t *confirm)
{
return impl->oobReceived(address, random, confirm);
}
ble_error_t SecurityManager::getSigningKey(ble::connection_handle_t connectionHandle, bool authenticated)
{
return impl->getSigningKey(connectionHandle, authenticated);
}
ble_error_t SecurityManager::setPrivateAddressTimeout(
uint16_t timeout_in_seconds
)
{
return impl->setPrivateAddressTimeout(timeout_in_seconds);
}
void SecurityManager::onShutdown(const SecurityManagerShutdownCallback_t& callback)
{
return impl->onShutdown(callback);
}
SecurityManager::SecurityManagerShutdownCallbackChain_t& SecurityManager::onShutdown()
{
return impl->onShutdown();
}
void SecurityManager::setSecurityManagerEventHandler(EventHandler* handler)
{
return impl->setSecurityManagerEventHandler(handler);
}
} // ble