introduce SecurityManager
This commit is contained in:
parent
db2de9114e
commit
ebd6bbceb5
5 changed files with 372 additions and 274 deletions
|
@ -38,10 +38,8 @@ public:
|
|||
virtual GattServer& getGattServer() = 0;
|
||||
virtual const GattServer& getGattServer() const = 0;
|
||||
virtual GattClient& getGattClient() = 0;
|
||||
virtual ble_error_t initializeSecurity(bool enableBonding = true,
|
||||
bool requireMITM = true,
|
||||
Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE,
|
||||
const Gap::Passkey_t passkey = NULL) = 0;
|
||||
virtual SecurityManager& getSecurityManager() = 0;
|
||||
virtual const SecurityManager& getSecurityManager() const = 0;
|
||||
virtual void waitForEvent(void) = 0;
|
||||
};
|
||||
|
||||
|
|
283
public/BLE.h
283
public/BLE.h
|
@ -96,6 +96,18 @@ public:
|
|||
return transport->getGattClient();
|
||||
}
|
||||
|
||||
/*
|
||||
* Accessors to Security Manager. Please refer to SecurityManager.h. All
|
||||
* SecurityManager related functionality requires going through this
|
||||
* accessor.
|
||||
*/
|
||||
const SecurityManager& securityManager() const {
|
||||
return transport->getSecurityManager();
|
||||
}
|
||||
SecurityManager& securityManager() {
|
||||
return transport->getSecurityManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Yield control to the BLE stack or to other tasks waiting for events. This
|
||||
* is a sleep function which will return when there is an application
|
||||
|
@ -107,88 +119,6 @@ public:
|
|||
transport->waitForEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the BLE stack's Security Manager. The Security Manager implements
|
||||
* the actual cryptographic algorithms and protocol exchanges that allow two
|
||||
* devices to securely exchange data and privately detect each other.
|
||||
* Calling this API is a prerequisite for encryption and pairing (bonding).
|
||||
*
|
||||
* @param[in] enableBonding Allow for bonding.
|
||||
* @param[in] requireMITM Require protection for man-in-the-middle attacks.
|
||||
* @param[in] iocaps To specify IO capabilities of this peripheral,
|
||||
* such as availability of a display or keyboard to
|
||||
* support out-of-band exchanges of security data.
|
||||
* @param[in] passkey To specify a static passkey.
|
||||
*
|
||||
* @return BLE_ERROR_NONE on success.
|
||||
*/
|
||||
ble_error_t initializeSecurity(bool enableBonding = true,
|
||||
bool requireMITM = true,
|
||||
Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE,
|
||||
const Gap::Passkey_t passkey = NULL);
|
||||
|
||||
/**
|
||||
* Setup a callback for when the security setup procedure (key generation
|
||||
* and exchange) for a link has started. This will be skipped for bonded
|
||||
* devices. The callback is passed in parameters received from the peer's
|
||||
* security request: bool allowBonding, bool requireMITM, and
|
||||
* SecurityIOCapabilities_t.
|
||||
*/
|
||||
void onSecuritySetupInitiated(Gap::SecuritySetupInitiatedCallback_t callback);
|
||||
|
||||
/**
|
||||
* Setup a callback for when the security setup procedure (key generation
|
||||
* and exchange) for a link has completed. This will be skipped for bonded
|
||||
* devices. The callback is passed in the success/failure status of the
|
||||
* security setup procedure.
|
||||
*/
|
||||
void onSecuritySetupCompleted(Gap::SecuritySetupCompletedCallback_t callback);
|
||||
|
||||
/**
|
||||
* Setup a callback for when a link with the peer is secured. For bonded
|
||||
* devices, subsequent reconnections with bonded peer will result only in
|
||||
* this callback when the link is secured and setup procedures will not
|
||||
* occur unless the bonding information is either lost or deleted on either
|
||||
* or both sides. The callback is passed in a Gap::SecurityMode_t according
|
||||
* to the level of security in effect for the secured link.
|
||||
*/
|
||||
void onLinkSecured(Gap::LinkSecuredCallback_t callback);
|
||||
|
||||
/**
|
||||
* Setup a callback for successful bonding; i.e. that link-specific security
|
||||
* context is stored persistently for a peer device.
|
||||
*/
|
||||
void onSecurityContextStored(Gap::HandleSpecificEvent_t callback);
|
||||
|
||||
/**
|
||||
* Setup a callback for when the passkey needs to be displayed on a
|
||||
* peripheral with DISPLAY capability. This happens when security is
|
||||
* configured to prevent Man-In-The-Middle attacks, and a PIN (or passkey)
|
||||
* needs to be exchanged between the peers to authenticate the connection
|
||||
* attempt.
|
||||
*/
|
||||
void onPasskeyDisplay(Gap::PasskeyDisplayCallback_t callback);
|
||||
|
||||
/**
|
||||
* Get the security status of a connection.
|
||||
*
|
||||
* @param[in] connectionHandle Handle to identify the connection.
|
||||
* @param[out] securityStatusP security status.
|
||||
*
|
||||
* @return BLE_SUCCESS Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, Gap::LinkSecurityStatus_t *securityStatusP);
|
||||
|
||||
/**
|
||||
* Delete all peer device context and all related bonding information from
|
||||
* the database within the security manager.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure.
|
||||
* @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
||||
* application registration.
|
||||
*/
|
||||
ble_error_t purgeAllBondingState(void);
|
||||
|
||||
/*
|
||||
* Deprecation alert!
|
||||
* All of the following are deprecated and may be dropped in a future
|
||||
|
@ -1053,6 +983,67 @@ public:
|
|||
return gattServer().write(connectionHandle, attributeHandle, value, size, localOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the BLE stack's Security Manager. The Security Manager implements
|
||||
* the actual cryptographic algorithms and protocol exchanges that allow two
|
||||
* devices to securely exchange data and privately detect each other.
|
||||
* Calling this API is a prerequisite for encryption and pairing (bonding).
|
||||
*
|
||||
* @param[in] enableBonding Allow for bonding.
|
||||
* @param[in] requireMITM Require protection for man-in-the-middle attacks.
|
||||
* @param[in] iocaps To specify IO capabilities of this peripheral,
|
||||
* such as availability of a display or keyboard to
|
||||
* support out-of-band exchanges of security data.
|
||||
* @param[in] passkey To specify a static passkey.
|
||||
*
|
||||
* @return BLE_ERROR_NONE on success.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.initializeSecurity(...) should be replaced with
|
||||
* ble.securityManager().init(...).
|
||||
*/
|
||||
ble_error_t initializeSecurity(bool enableBonding = true,
|
||||
bool requireMITM = true,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE,
|
||||
const SecurityManager::Passkey_t passkey = NULL) {
|
||||
return securityManager().init(enableBonding, requireMITM, iocaps, passkey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the security status of a connection.
|
||||
*
|
||||
* @param[in] connectionHandle Handle to identify the connection.
|
||||
* @param[out] securityStatusP security status.
|
||||
*
|
||||
* @return BLE_SUCCESS Or appropriate error code indicating reason for failure.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.getLinkSecurity(...) should be replaced with
|
||||
* ble.securityManager().getLinkSecurity(...).
|
||||
*/
|
||||
ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP) {
|
||||
return securityManager().getLinkSecurity(connectionHandle, securityStatusP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all peer device context and all related bonding information from
|
||||
* the database within the security manager.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure.
|
||||
* @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
||||
* application registration.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.purgeAllBondingState() should be replaced with
|
||||
* ble.securityManager().purgeAllBondingState().
|
||||
*/
|
||||
ble_error_t purgeAllBondingState(void) {
|
||||
return securityManager().purgeAllBondingState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a callback for timeout events. Refer to Gap::TimeoutSource_t for
|
||||
* possible event types.
|
||||
|
@ -1184,6 +1175,83 @@ public:
|
|||
void onUpdatesDisabled(GattServer::EventCallback_t callback);
|
||||
void onConfirmationReceived(GattServer::EventCallback_t callback);
|
||||
|
||||
/**
|
||||
* Setup a callback for when the security setup procedure (key generation
|
||||
* and exchange) for a link has started. This will be skipped for bonded
|
||||
* devices. The callback is passed in parameters received from the peer's
|
||||
* security request: bool allowBonding, bool requireMITM, and
|
||||
* SecurityIOCapabilities_t.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.onSecuritySetupInitiated(callback) should be replaced with
|
||||
* ble.securityManager().onSecuritySetupInitiated(callback).
|
||||
*/
|
||||
void onSecuritySetupInitiated(SecurityManager::SecuritySetupInitiatedCallback_t callback) {
|
||||
securityManager().onSecuritySetupInitiated(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a callback for when the security setup procedure (key generation
|
||||
* and exchange) for a link has completed. This will be skipped for bonded
|
||||
* devices. The callback is passed in the success/failure status of the
|
||||
* security setup procedure.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.onSecuritySetupCompleted(callback) should be replaced with
|
||||
* ble.securityManager().onSecuritySetupCompleted(callback).
|
||||
*/
|
||||
void onSecuritySetupCompleted(SecurityManager::SecuritySetupCompletedCallback_t callback) {
|
||||
securityManager().onSecuritySetupCompleted(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a callback for when a link with the peer is secured. For bonded
|
||||
* devices, subsequent reconnections with bonded peer will result only in
|
||||
* this callback when the link is secured and setup procedures will not
|
||||
* occur unless the bonding information is either lost or deleted on either
|
||||
* or both sides. The callback is passed in a SecurityManager::SecurityMode_t according
|
||||
* to the level of security in effect for the secured link.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.onLinkSecured(callback) should be replaced with
|
||||
* ble.securityManager().onLinkSecured(callback).
|
||||
*/
|
||||
void onLinkSecured(SecurityManager::LinkSecuredCallback_t callback) {
|
||||
securityManager().onLinkSecured(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a callback for successful bonding; i.e. that link-specific security
|
||||
* context is stored persistently for a peer device.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.onSecurityContextStored(callback) should be replaced with
|
||||
* ble.securityManager().onSecurityContextStored(callback).
|
||||
*/
|
||||
void onSecurityContextStored(SecurityManager::HandleSpecificEvent_t callback) {
|
||||
securityManager().onSecurityContextStored(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a callback for when the passkey needs to be displayed on a
|
||||
* peripheral with DISPLAY capability. This happens when security is
|
||||
* configured to prevent Man-In-The-Middle attacks, and a PIN (or passkey)
|
||||
* needs to be exchanged between the peers to authenticate the connection
|
||||
* attempt.
|
||||
*
|
||||
* @note: This API is now *deprecated* and will be dropped in the future.
|
||||
* You should use the parallel API from SecurityManager directly. A former
|
||||
* call to ble.onPasskeyDisplay(callback) should be replaced with
|
||||
* ble.securityManager().onPasskeyDisplay(callback).
|
||||
*/
|
||||
void onPasskeyDisplay(SecurityManager::PasskeyDisplayCallback_t callback) {
|
||||
return securityManager().onPasskeyDisplay(callback);
|
||||
}
|
||||
|
||||
public:
|
||||
BLE() : transport(createBLEInstance()) {
|
||||
/* empty */
|
||||
|
@ -1247,55 +1315,4 @@ BLE::onConfirmationReceived(GattServer::EventCallback_t callback)
|
|||
transport->getGattServer().setOnConfirmationReceived(callback);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLE::initializeSecurity(bool enableBonding,
|
||||
bool requireMITM,
|
||||
Gap::SecurityIOCapabilities_t iocaps,
|
||||
const Gap::Passkey_t passkey)
|
||||
{
|
||||
return transport->initializeSecurity(enableBonding, requireMITM, iocaps, passkey);
|
||||
}
|
||||
|
||||
inline void
|
||||
BLE::onSecuritySetupInitiated(Gap::SecuritySetupInitiatedCallback_t callback)
|
||||
{
|
||||
gap().setOnSecuritySetupInitiated(callback);
|
||||
}
|
||||
|
||||
inline void
|
||||
BLE::onSecuritySetupCompleted(Gap::SecuritySetupCompletedCallback_t callback)
|
||||
{
|
||||
gap().setOnSecuritySetupCompleted(callback);
|
||||
}
|
||||
|
||||
inline void
|
||||
BLE::onLinkSecured(Gap::LinkSecuredCallback_t callback)
|
||||
{
|
||||
gap().setOnLinkSecured(callback);
|
||||
}
|
||||
|
||||
inline void
|
||||
BLE::onSecurityContextStored(Gap::HandleSpecificEvent_t callback)
|
||||
{
|
||||
gap().setOnSecurityContextStored(callback);
|
||||
}
|
||||
|
||||
inline void
|
||||
BLE::onPasskeyDisplay(Gap::PasskeyDisplayCallback_t callback)
|
||||
{
|
||||
return gap().setOnPasskeyDisplay(callback);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLE::getLinkSecurity(Gap::Handle_t connectionHandle, Gap::LinkSecurityStatus_t *securityStatusP)
|
||||
{
|
||||
return gap().getLinkSecurity(connectionHandle, securityStatusP);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLE::purgeAllBondingState(void)
|
||||
{
|
||||
return gap().purgeAllBondingState();
|
||||
}
|
||||
|
||||
#endif // ifndef __BLE_H__
|
||||
|
|
129
public/Gap.h
129
public/Gap.h
|
@ -126,58 +126,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
enum SecurityMode_t {
|
||||
SECURITY_MODE_NO_ACCESS,
|
||||
SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */
|
||||
SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */
|
||||
SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */
|
||||
SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */
|
||||
SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines possible security status/states.
|
||||
*
|
||||
* @details Defines possible security status/states of a link when requested by getLinkSecurity().
|
||||
*/
|
||||
enum LinkSecurityStatus_t {
|
||||
NOT_ENCRYPTED, /**< The link is not secured. */
|
||||
ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/
|
||||
ENCRYPTED /**< The link is secure.*/
|
||||
};
|
||||
|
||||
enum SecurityIOCapabilities_t {
|
||||
IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */
|
||||
IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */
|
||||
IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */
|
||||
IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */
|
||||
IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */
|
||||
};
|
||||
|
||||
enum SecurityCompletionStatus_t {
|
||||
SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */
|
||||
SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */
|
||||
SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */
|
||||
SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */
|
||||
SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */
|
||||
SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */
|
||||
SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */
|
||||
SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */
|
||||
SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */
|
||||
SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */
|
||||
SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */
|
||||
SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */
|
||||
SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Declaration of type containing a passkey to be used during pairing. This
|
||||
* is passed into initializeSecurity() to specify a pre-programmed passkey
|
||||
* for authentication instead of generating a random one.
|
||||
*/
|
||||
static const unsigned PASSKEY_LEN = 6;
|
||||
typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
|
||||
|
||||
static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */
|
||||
static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */
|
||||
static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) {
|
||||
|
@ -192,13 +140,8 @@ public:
|
|||
|
||||
typedef void (*TimeoutEventCallback_t)(TimeoutSource_t source);
|
||||
typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params);
|
||||
typedef void (*HandleSpecificEvent_t)(Handle_t handle);
|
||||
typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t);
|
||||
typedef void (*RadioNotificationEventCallback_t) (bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */
|
||||
typedef void (*SecuritySetupInitiatedCallback_t)(Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps);
|
||||
typedef void (*SecuritySetupCompletedCallback_t)(Handle_t, SecurityCompletionStatus_t status);
|
||||
typedef void (*LinkSecuredCallback_t)(Handle_t handle, SecurityMode_t securityMode);
|
||||
typedef void (*PasskeyDisplayCallback_t)(Handle_t handle, const Passkey_t passkey);
|
||||
|
||||
/*
|
||||
* These functions must be defined in the platform-specific sub-class.
|
||||
|
@ -309,9 +252,6 @@ public:
|
|||
*/
|
||||
virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) = 0;
|
||||
|
||||
virtual ble_error_t purgeAllBondingState(void) = 0;
|
||||
virtual ble_error_t getLinkSecurity(Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) = 0;
|
||||
|
||||
/**
|
||||
* Set the device name characteristic in the GAP service.
|
||||
* @param[in] deviceName
|
||||
|
@ -802,35 +742,6 @@ public:
|
|||
*/
|
||||
virtual void onRadioNotification(RadioNotificationEventCallback_t callback) {radioNotificationCallback = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that security procedure for link has started.
|
||||
*/
|
||||
virtual void setOnSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {onSecuritySetupInitiated = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that security procedure for link has completed.
|
||||
*/
|
||||
virtual void setOnSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {onSecuritySetupCompleted = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that link with the peer is secured. For bonded devices,
|
||||
* subsequent re-connections with bonded peer will result only in this callback
|
||||
* when the link is secured and setup procedures will not occur unless the
|
||||
* bonding information is either lost or deleted on either or both sides.
|
||||
*/
|
||||
virtual void setOnLinkSecured(LinkSecuredCallback_t callback) {onLinkSecured = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that device context is stored persistently.
|
||||
*/
|
||||
virtual void setOnSecurityContextStored(HandleSpecificEvent_t callback) {onSecurityContextStored = callback;}
|
||||
|
||||
/**
|
||||
* To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability.
|
||||
*/
|
||||
virtual void setOnPasskeyDisplay(PasskeyDisplayCallback_t callback) {onPasskeyDisplay = callback;}
|
||||
|
||||
|
||||
protected:
|
||||
Gap() :
|
||||
_advParams(),
|
||||
|
@ -842,11 +753,6 @@ protected:
|
|||
connectionCallback(NULL),
|
||||
disconnectionCallback(NULL),
|
||||
radioNotificationCallback(),
|
||||
onSecuritySetupInitiated(),
|
||||
onSecuritySetupCompleted(),
|
||||
onLinkSecured(),
|
||||
onSecurityContextStored(),
|
||||
onPasskeyDisplay(),
|
||||
onAdvertisementReport(),
|
||||
disconnectionCallChain() {
|
||||
_advPayload.clear();
|
||||
|
@ -876,36 +782,6 @@ public:
|
|||
disconnectionCallChain.call();
|
||||
}
|
||||
|
||||
void processSecuritySetupInitiatedEvent(Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) {
|
||||
if (onSecuritySetupInitiated) {
|
||||
onSecuritySetupInitiated(handle, allowBonding, requireMITM, iocaps);
|
||||
}
|
||||
}
|
||||
|
||||
void processSecuritySetupCompletedEvent(Handle_t handle, SecurityCompletionStatus_t status) {
|
||||
if (onSecuritySetupCompleted) {
|
||||
onSecuritySetupCompleted(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
void processLinkSecuredEvent(Handle_t handle, SecurityMode_t securityMode) {
|
||||
if (onLinkSecured) {
|
||||
onLinkSecured(handle, securityMode);
|
||||
}
|
||||
}
|
||||
|
||||
void processSecurityContextStoredEvent(Handle_t handle) {
|
||||
if (onSecurityContextStored) {
|
||||
onSecurityContextStored(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void processPasskeyDisplayEvent(Handle_t handle, const Passkey_t passkey) {
|
||||
if (onPasskeyDisplay) {
|
||||
onPasskeyDisplay(handle, passkey);
|
||||
}
|
||||
}
|
||||
|
||||
void processAdvertisementReport(const Address_t peerAddr,
|
||||
int8_t rssi,
|
||||
bool isScanResponse,
|
||||
|
@ -941,11 +817,6 @@ protected:
|
|||
ConnectionEventCallback_t connectionCallback;
|
||||
DisconnectionEventCallback_t disconnectionCallback;
|
||||
RadioNotificationEventCallback_t radioNotificationCallback;
|
||||
SecuritySetupInitiatedCallback_t onSecuritySetupInitiated;
|
||||
SecuritySetupCompletedCallback_t onSecuritySetupCompleted;
|
||||
LinkSecuredCallback_t onLinkSecured;
|
||||
HandleSpecificEvent_t onSecurityContextStored;
|
||||
PasskeyDisplayCallback_t onPasskeyDisplay;
|
||||
AdvertisementReportCallback_t onAdvertisementReport;
|
||||
CallChain disconnectionCallChain;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define __GATT_CHARACTERISTIC_H__
|
||||
|
||||
#include "Gap.h"
|
||||
#include "SecurityManager.h"
|
||||
#include "GattAttribute.h"
|
||||
#include "GattCallbackParamTypes.h"
|
||||
#include "FunctionPointerWithContext.h"
|
||||
|
@ -331,7 +332,7 @@ public:
|
|||
unsigned numDescriptors = 0) :
|
||||
_valueAttribute(uuid, valuePtr, initialLen, maxLen),
|
||||
_properties(props),
|
||||
_requiredSecurity(Gap::SECURITY_MODE_ENCRYPTION_OPEN_LINK),
|
||||
_requiredSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK),
|
||||
_descriptors(descriptors),
|
||||
_descriptorCount(numDescriptors),
|
||||
enabledReadAuthorization(false),
|
||||
|
@ -347,7 +348,7 @@ public:
|
|||
*
|
||||
* @param securityMode Can be one of encryption or signing, with or without protection for MITM (man in the middle attacks).
|
||||
*/
|
||||
void requireSecurity(Gap::SecurityMode_t securityMode) {
|
||||
void requireSecurity(SecurityManager::SecurityMode_t securityMode) {
|
||||
_requiredSecurity = securityMode;
|
||||
}
|
||||
|
||||
|
@ -422,7 +423,7 @@ public:
|
|||
const GattAttribute& getValueAttribute() const {return _valueAttribute; }
|
||||
GattAttribute::Handle_t getValueHandle(void) const {return getValueAttribute().getHandle();}
|
||||
uint8_t getProperties(void) const {return _properties; }
|
||||
Gap::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity; }
|
||||
SecurityManager::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity; }
|
||||
uint8_t getDescriptorCount(void) const {return _descriptorCount; }
|
||||
bool isReadAuthorizationEnabled() const {return enabledReadAuthorization; }
|
||||
bool isWriteAuthorizationEnabled() const {return enabledWriteAuthorization; }
|
||||
|
@ -436,11 +437,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
GattAttribute _valueAttribute;
|
||||
uint8_t _properties;
|
||||
Gap::SecurityMode_t _requiredSecurity;
|
||||
GattAttribute **_descriptors;
|
||||
uint8_t _descriptorCount;
|
||||
GattAttribute _valueAttribute;
|
||||
uint8_t _properties;
|
||||
SecurityManager::SecurityMode_t _requiredSecurity;
|
||||
GattAttribute **_descriptors;
|
||||
uint8_t _descriptorCount;
|
||||
|
||||
bool enabledReadAuthorization;
|
||||
bool enabledWriteAuthorization;
|
||||
|
|
211
public/SecurityManager.h
Normal file
211
public/SecurityManager.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2015 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SECURITY_MANAGER_H__
|
||||
#define __SECURITY_MANAGER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Gap.h"
|
||||
|
||||
class SecurityManager {
|
||||
public:
|
||||
enum SecurityMode_t {
|
||||
SECURITY_MODE_NO_ACCESS,
|
||||
SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */
|
||||
SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */
|
||||
SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */
|
||||
SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */
|
||||
SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines possible security status/states.
|
||||
*
|
||||
* @details Defines possible security status/states of a link when requested by getLinkSecurity().
|
||||
*/
|
||||
enum LinkSecurityStatus_t {
|
||||
NOT_ENCRYPTED, /**< The link is not secured. */
|
||||
ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/
|
||||
ENCRYPTED /**< The link is secure.*/
|
||||
};
|
||||
|
||||
enum SecurityIOCapabilities_t {
|
||||
IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */
|
||||
IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */
|
||||
IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */
|
||||
IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */
|
||||
IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */
|
||||
};
|
||||
|
||||
enum SecurityCompletionStatus_t {
|
||||
SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */
|
||||
SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */
|
||||
SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */
|
||||
SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */
|
||||
SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */
|
||||
SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */
|
||||
SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */
|
||||
SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */
|
||||
SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */
|
||||
SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */
|
||||
SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */
|
||||
SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */
|
||||
SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Declaration of type containing a passkey to be used during pairing. This
|
||||
* is passed into initializeSecurity() to specify a pre-programmed passkey
|
||||
* for authentication instead of generating a random one.
|
||||
*/
|
||||
static const unsigned PASSKEY_LEN = 6;
|
||||
typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
|
||||
|
||||
public:
|
||||
typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle);
|
||||
typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps);
|
||||
typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status);
|
||||
typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode);
|
||||
typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Enable the BLE stack's Security Manager. The Security Manager implements
|
||||
* the actual cryptographic algorithms and protocol exchanges that allow two
|
||||
* devices to securely exchange data and privately detect each other.
|
||||
* Calling this API is a prerequisite for encryption and pairing (bonding).
|
||||
*
|
||||
* @param[in] enableBonding Allow for bonding.
|
||||
* @param[in] requireMITM Require protection for man-in-the-middle attacks.
|
||||
* @param[in] iocaps To specify IO capabilities of this peripheral,
|
||||
* such as availability of a display or keyboard to
|
||||
* support out-of-band exchanges of security data.
|
||||
* @param[in] passkey To specify a static passkey.
|
||||
*
|
||||
* @return BLE_ERROR_NONE on success.
|
||||
*/
|
||||
virtual ble_error_t init(bool enableBonding = true,
|
||||
bool requireMITM = true,
|
||||
SecurityIOCapabilities_t iocaps = IO_CAPS_NONE,
|
||||
const Passkey_t passkey = NULL) {
|
||||
return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the security status of a connection.
|
||||
*
|
||||
* @param[in] connectionHandle Handle to identify the connection.
|
||||
* @param[out] securityStatusP security status.
|
||||
*
|
||||
* @return BLE_SUCCESS Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
|
||||
return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all peer device context and all related bonding information from
|
||||
* the database within the security manager.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure.
|
||||
* @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
||||
* application registration.
|
||||
*/
|
||||
virtual ble_error_t purgeAllBondingState(void) {
|
||||
return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* To indicate that security procedure for link has started.
|
||||
*/
|
||||
virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that security procedure for link has completed.
|
||||
*/
|
||||
virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that link with the peer is secured. For bonded devices,
|
||||
* subsequent re-connections with bonded peer will result only in this callback
|
||||
* when the link is secured and setup procedures will not occur unless the
|
||||
* bonding information is either lost or deleted on either or both sides.
|
||||
*/
|
||||
virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;}
|
||||
|
||||
/**
|
||||
* To indicate that device context is stored persistently.
|
||||
*/
|
||||
virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;}
|
||||
|
||||
/**
|
||||
* To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability.
|
||||
*/
|
||||
virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;}
|
||||
|
||||
public:
|
||||
void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) {
|
||||
if (securitySetupInitiatedCallback) {
|
||||
securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps);
|
||||
}
|
||||
}
|
||||
|
||||
void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) {
|
||||
if (securitySetupCompletedCallback) {
|
||||
securitySetupCompletedCallback(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) {
|
||||
if (linkSecuredCallback) {
|
||||
linkSecuredCallback(handle, securityMode);
|
||||
}
|
||||
}
|
||||
|
||||
void processSecurityContextStoredEvent(Gap::Handle_t handle) {
|
||||
if (securityContextStoredCallback) {
|
||||
securityContextStoredCallback(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) {
|
||||
if (passkeyDisplayCallback) {
|
||||
passkeyDisplayCallback(handle, passkey);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
SecurityManager() :
|
||||
securitySetupInitiatedCallback(),
|
||||
securitySetupCompletedCallback(),
|
||||
linkSecuredCallback(),
|
||||
securityContextStoredCallback(),
|
||||
passkeyDisplayCallback() {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback;
|
||||
SecuritySetupCompletedCallback_t securitySetupCompletedCallback;
|
||||
LinkSecuredCallback_t linkSecuredCallback;
|
||||
HandleSpecificEvent_t securityContextStoredCallback;
|
||||
PasskeyDisplayCallback_t passkeyDisplayCallback;
|
||||
};
|
||||
|
||||
#endif /*__SECURITY_MANAGER_H__*/
|
Loading…
Reference in a new issue