shared types in common header, connected up the events in handlers

pull/6188/head
paul-szczepanek-arm 2018-01-17 21:22:48 +00:00
parent 2fb67d2c7d
commit 2f04aece23
4 changed files with 260 additions and 173 deletions

View File

@ -19,6 +19,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "ble/SafeEnum.h"
/** /**
* @addtogroup ble * @addtogroup ble
@ -117,6 +118,54 @@ static inline attribute_handle_range_t attribute_handle_range(
return result; return result;
} }
/**
* Type that describe a pairing failure.
*/
struct pairing_failure_t : SafeEnum<pairing_failure_t, uint8_t> {
enum type {
PASSKEY_ENTRY_FAILED = 0x01,
OOB_NOT_AVAILABLE = 0x02,
AUTHENTICATION_REQUIREMENTS = 0x03,
CONFIRM_VALUE_FAILED = 0x04,
PAIRING_NOT_SUPPORTED = 0x05,
ENCRYPTION_KEY_SIZE = 0x06,
COMMAND_NOT_SUPPORTED = 0x07,
UNSPECIFIED_REASON = 0x08,
REPEATED_ATTEMPTS = 0x09,
INVALID_PARAMETERS = 0x0A,
DHKEY_CHECK_FAILED = 0x0B,
NUMERIC_COMPARISON_FAILED = 0x0c,
BR_EDR_PAIRING_IN_PROGRESS = 0x0D,
CROSS_TRANSPORT_KEY_DERIVATION_OR_GENERATION_NOT_ALLOWED = 0x0E
};
/**
* Construct a new instance of pairing_failure_t.
*/
pairing_failure_t(type value) : SafeEnum<pairing_failure_t, uint8_t>(value) { }
};
/**
* Type that describe the IO capability of a device; it is used during Pairing
* Feature exchange.
*/
struct io_capability_t : SafeEnum<io_capability_t, uint8_t> {
enum type {
DISPLAY_ONLY = 0x00,
DISPLAY_YES_NO = 0x01,
KEYBOARD_ONLY = 0x02,
NO_INPUT_NO_OUTPUT = 0x03,
KEYBOARD_DISPLAY = 0x04
};
/**
* Construct a new instance of io_capability_t.
*/
io_capability_t(type value) : SafeEnum<io_capability_t, uint8_t>(value) { }
};
} // namespace ble } // namespace ble
/** /**

View File

@ -21,11 +21,13 @@
#include "Gap.h" #include "Gap.h"
#include "CallChainOfFunctionPointersWithContext.h" #include "CallChainOfFunctionPointersWithContext.h"
#include "ble/BLETypes.h"
class SecurityManagerEventHandler; class SecurityManagerEventHandler;
class LegacySecurityManagerEventHandler; class LegacySecurityManagerEventHandler;
using ble::connection_handle_t; using ble::connection_handle_t;
using ble::pairing_failure_t;
class SecurityManager { class SecurityManager {
public: public:
@ -109,60 +111,82 @@ public:
SecurityManagerEventHandler() {}; SecurityManagerEventHandler() {};
virtual ~SecurityManagerEventHandler() {}; virtual ~SecurityManagerEventHandler() {};
////////////////////////////////////////////////////////////////////////////
// Pairing
//
virtual void acceptPairingRequest(connection_handle_t handle) {
(void)handle;
}
virtual void pairingError(connection_handle_t handle, pairing_failure_t error) {
(void)handle;
}
virtual void pairingCompleted(connection_handle_t handle) {
(void)handle;
}
////////////////////////////////////////////////////////////////////////////
// Security
//
virtual void securitySetupInitiated(connection_handle_t handle, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) { virtual void securitySetupInitiated(connection_handle_t handle, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) {
(void)handle; (void)handle;
(void)allowBonding; (void)allowBonding;
(void)requireMITM; (void)requireMITM;
(void)iocaps; (void)iocaps;
}; }
virtual void securitySetupCompleted(connection_handle_t handle, SecurityManager::SecurityCompletionStatus_t status) {
(void)handle;
(void)status;
};
virtual void linkSecured(connection_handle_t handle, SecurityManager::SecurityMode_t securityMode) { virtual void linkSecured(connection_handle_t handle, SecurityManager::SecurityMode_t securityMode) {
(void)handle; (void)handle;
(void)securityMode; (void)securityMode;
};
virtual void securityContextStored(connection_handle_t handle) {
(void)handle;
} }
virtual void passkeyDisplay(connection_handle_t handle, const SecurityManager::Passkey_t passkey) {
(void)handle;
(void)passkey;
};
virtual void validMicTimeout(connection_handle_t handle) { virtual void validMicTimeout(connection_handle_t handle) {
(void)handle; (void)handle;
}; }
virtual void linkKeyFailure(connection_handle_t handle) {
(void)handle;
};
virtual void keypressNotification(connection_handle_t handle, SecurityManager::Keypress_t keypress) {
(void)handle;
(void)keypress;
};
virtual void legacyPairingOobRequest(connection_handle_t handle) {
(void)handle;
};
virtual void oobRequest(connection_handle_t handle) {
(void)handle;
};
virtual void pinRequest(connection_handle_t handle) {
(void)handle;
};
virtual void passkeyRequest(connection_handle_t handle) {
(void)handle;
};
virtual void confirmationRequest(connection_handle_t handle) {
(void)handle;
};
virtual void acceptPairingRequest(connection_handle_t handle) {
(void)handle;
};
virtual void whitelistFromBondTable(Gap::Whitelist_t* whitelist) { virtual void whitelistFromBondTable(Gap::Whitelist_t* whitelist) {
if (whitelist) { if (whitelist) {
delete whitelist; delete whitelist;
} }
}; }
/* TODO: this appears to be redundant */
virtual void securityContextStored(connection_handle_t handle) {
(void)handle;
}
////////////////////////////////////////////////////////////////////////////
// MITM
//
virtual void passkeyDisplay(connection_handle_t handle, const SecurityManager::Passkey_t passkey) {
(void)handle;
(void)passkey;
}
virtual void confirmationRequest(connection_handle_t handle) {
(void)handle;
}
virtual void passkeyRequest(connection_handle_t handle) {
(void)handle;
}
virtual void keypressNotification(connection_handle_t handle, SecurityManager::Keypress_t keypress) {
(void)handle;
(void)keypress;
}
virtual void legacyPairingOobRequest(connection_handle_t handle) {
(void)handle;
}
virtual void oobRequest(connection_handle_t handle) {
(void)handle;
}
}; };
private: private:
@ -176,26 +200,49 @@ private:
securityContextStoredCallback(), securityContextStoredCallback(),
passkeyDisplayCallback() { }; passkeyDisplayCallback() { };
////////////////////////////////////////////////////////////////////////////
// Pairing
//
void pairingError(connection_handle_t handle, pairing_failure_t error) {
if (securitySetupCompletedCallback) {
/* translate error codes to what the callback expects */
securitySetupCompletedCallback(handle, (SecurityManager::SecurityCompletionStatus_t)(error.value() | 0x80));
}
}
void pairingCompleted(connection_handle_t handle) {
if (securitySetupCompletedCallback) {
securitySetupCompletedCallback(handle, SecurityManager::SecurityCompletionStatus_t::SEC_STATUS_SUCCESS);
}
}
void securitySetupInitiated(connection_handle_t handle, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) { void securitySetupInitiated(connection_handle_t handle, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) {
if (securitySetupInitiatedCallback) { if (securitySetupInitiatedCallback) {
securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps);
} }
}; };
void securitySetupCompleted(connection_handle_t handle, SecurityManager::SecurityCompletionStatus_t status) {
if (securitySetupCompletedCallback) { ////////////////////////////////////////////////////////////////////////////
securitySetupCompletedCallback(handle, status); // Security
} //
};
void linkSecured(connection_handle_t handle, SecurityManager::SecurityMode_t securityMode) { void linkSecured(connection_handle_t handle, SecurityManager::SecurityMode_t securityMode) {
if (linkSecuredCallback) { if (linkSecuredCallback) {
linkSecuredCallback(handle, securityMode); linkSecuredCallback(handle, securityMode);
} }
}; };
/* TODO: this appears to be redundant */
void securityContextStored(connection_handle_t handle) { void securityContextStored(connection_handle_t handle) {
if (securityContextStoredCallback) { if (securityContextStoredCallback) {
securityContextStoredCallback(handle); securityContextStoredCallback(handle);
} }
} }
////////////////////////////////////////////////////////////////////////////
// MITM
//
void passkeyDisplay(connection_handle_t handle, const SecurityManager::Passkey_t passkey) { void passkeyDisplay(connection_handle_t handle, const SecurityManager::Passkey_t passkey) {
if (passkeyDisplayCallback) { if (passkeyDisplayCallback) {
passkeyDisplayCallback(handle, passkey); passkeyDisplayCallback(handle, passkey);
@ -604,7 +651,14 @@ public:
} }
/** @deprecated */ /** @deprecated */
void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) {
eventHandler->securitySetupCompleted(handle, status); if (status & 0x80) {
pairing_failure_t error(status & ~0x80);
eventHandler->pairingError(handle, error);
} else if (status == SecurityManager::SecurityCompletionStatus_t::SEC_STATUS_SUCCESS) {
eventHandler->pairingCompleted(handle);
} else {
eventHandler->pairingError(handle, pairing_failure_t::UNSPECIFIED_REASON);
}
} }
/** @deprecated */ /** @deprecated */
void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) {

View File

@ -20,7 +20,6 @@
#include "platform/Callback.h" #include "platform/Callback.h"
#include "platform/NonCopyable.h" #include "platform/NonCopyable.h"
#include "ble/BLETypes.h" #include "ble/BLETypes.h"
#include "ble/SafeEnum.h"
#include "ble/BLEProtocol.h" #include "ble/BLEProtocol.h"
#include "ble/SecurityManager.h" #include "ble/SecurityManager.h"
#include "ble/pal/GapTypes.h" #include "ble/pal/GapTypes.h"
@ -28,53 +27,6 @@
namespace ble { namespace ble {
namespace pal { namespace pal {
/**
* Type that describe the IO capability of a device; it is used during Pairing
* Feature exchange.
*/
struct io_capability_t : SafeEnum<io_capability_t, uint8_t> {
enum type {
DISPLAY_ONLY = 0x00,
DISPLAY_YES_NO = 0x01,
KEYBOARD_ONLY = 0x02,
NO_INPUT_NO_OUTPUT = 0x03,
KEYBOARD_DISPLAY = 0x04
};
/**
* Construct a new instance of io_capability_t.
*/
io_capability_t(type value) : SafeEnum<io_capability_t, uint8_t>(value) { }
};
/**
* Type that describe a pairing failure.
*/
struct pairing_failure_t : SafeEnum<pairing_failure_t, uint8_t> {
enum type {
PASSKEY_ENTRY_FAILED = 0x01,
OOB_NOT_AVAILABLE = 0x02,
AUTHENTICATION_REQUIREMENTS = 0x03,
CONFIRM_VALUE_FAILED = 0x04,
PAIRING_NOT_SUPPORTED = 0x05,
ENCRYPTION_KEY_SIZE = 0x06,
COMMAND_NOT_SUPPORTED = 0x07,
UNSPECIFIED_REASON = 0x08,
REPEATED_ATTEMPTS = 0x09,
INVALID_PARAMETERS = 0x0A,
DHKEY_CHECK_FAILED = 0x0B,
NUMERIC_COMPARISON_FAILED = 0x0c,
BR_EDR_PAIRING_IN_PROGRESS = 0x0D,
CROSS_TRANSPORT_KEY_DERIVATION_OR_GENERATION_NOT_ALLOWED = 0x0E
};
/**
* Construct a new instance of pairing_failure_t.
*/
pairing_failure_t(type value) : SafeEnum<pairing_failure_t, uint8_t>(value) { }
};
typedef SecurityManager::SecurityCompletionStatus_t SecurityCompletionStatus_t; typedef SecurityManager::SecurityCompletionStatus_t SecurityCompletionStatus_t;
typedef SecurityManager::SecurityMode_t SecurityMode_t; typedef SecurityManager::SecurityMode_t SecurityMode_t;
typedef SecurityManager::LinkSecurityStatus_t LinkSecurityStatus_t; typedef SecurityManager::LinkSecurityStatus_t LinkSecurityStatus_t;
@ -106,7 +58,7 @@ enum KeyDistributionFlags_t {
class AuthenticationMask { class AuthenticationMask {
public: public:
enum AuthenticationFlags_t { enum AuthenticationFlags_t {
AUTHENTICATION_BONDABLE = 0x01, AUTHENTICATION_BONDABLE = 0x01,
AUTHENTICATION_MITM = 0x04, /* 0x02 missing because bonding uses two bits */ AUTHENTICATION_MITM = 0x04, /* 0x02 missing because bonding uses two bits */
AUTHENTICATION_SECURE_CONNECTIONS = 0x08, AUTHENTICATION_SECURE_CONNECTIONS = 0x08,
AUTHENTICATION_KEYPRESS_NOTIFICATION = 0x10 AUTHENTICATION_KEYPRESS_NOTIFICATION = 0x10
@ -176,6 +128,10 @@ public:
*/ */
class SecurityManagerEventHandler { class SecurityManagerEventHandler {
public: public:
////////////////////////////////////////////////////////////////////////////
// Pairing
//
/** /**
* Called upon reception of a pairing request. * Called upon reception of a pairing request.
* *
@ -204,27 +160,15 @@ public:
) = 0; ) = 0;
/** /**
* Called when the application should display a passkey. * To indicate that the pairing for the link has completed.
*/ */
virtual void on_passkey_display( virtual void on_pairing_completed(
connection_handle_t connection, const passkey_num_t passkey connection_handle_t connection
) = 0; ) = 0;
/** ////////////////////////////////////////////////////////////////////////////
* Request the passkey entered during pairing. // Security
* //
* @note shall be followed by: pal::SecurityManager::passkey_request_reply
* or a cancellation of the procedure.
*/
virtual void on_passkey_request(connection_handle_t connection) = 0;
/**
* Request oob data entered during pairing
*
* @note shall be followed by: pal::SecurityManager::oob_data_request_reply
* or a cancellation of the procedure.
*/
virtual void on_oob_data_request(connection_handle_t connection) = 0;
/** /**
* To indicate that a security procedure for the link has started. * To indicate that a security procedure for the link has started.
@ -236,14 +180,6 @@ public:
io_capability_t iocaps io_capability_t iocaps
) = 0; ) = 0;
/**
* To indicate that the security procedure for the link has completed.
*/
virtual void on_security_setup_completed(
connection_handle_t connection,
SecurityManager::SecurityCompletionStatus_t status
) = 0;
/** /**
* To indicate that the link with the peer is secured. For bonded devices, * To indicate that the link with the peer is secured. For bonded devices,
* subsequent reconnections with a bonded peer will result only in this callback * subsequent reconnections with a bonded peer will result only in this callback
@ -261,7 +197,31 @@ public:
*/ */
virtual void on_valid_mic_timeout(connection_handle_t connection) = 0; virtual void on_valid_mic_timeout(connection_handle_t connection) = 0;
virtual void on_link_key_failure(connection_handle_t connection) = 0; ////////////////////////////////////////////////////////////////////////////
// MITM
//
/**
* Called when the application should display a passkey.
*/
virtual void on_passkey_display(
connection_handle_t connection, const passkey_num_t passkey
) = 0;
/**
* To indicate user confirmation is require to confirm matching
* passkeys displayed on devices
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E, 7.7.42
*/
virtual void on_confirmation_request(connection_handle_t connection) = 0;
/**
* Request the passkey entered during pairing.
*
* @note shall be followed by: pal::SecurityManager::passkey_request_reply
* or a cancellation of the procedure.
*/
virtual void on_passkey_request(connection_handle_t connection) = 0;
/** /**
* To indicate that the peer has pressed a button * To indicate that the peer has pressed a button
@ -275,11 +235,17 @@ public:
virtual void on_legacy_pariring_oob_request(connection_handle_t connection) = 0; virtual void on_legacy_pariring_oob_request(connection_handle_t connection) = 0;
/** /**
* To indicate user confirmation is require to confirm matching * Request oob data entered during pairing
* passkeys displayed on devices *
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E, 7.7.42 * @note shall be followed by: pal::SecurityManager::oob_data_request_reply
* or a cancellation of the procedure.
*/ */
virtual void on_confirmation_request(connection_handle_t connection) = 0; virtual void on_oob_data_request(connection_handle_t connection) = 0;
////////////////////////////////////////////////////////////////////////////
// Keys
//
virtual void on_keys_distributed( virtual void on_keys_distributed(
connection_handle_t handle, connection_handle_t handle,

View File

@ -21,6 +21,7 @@
#include "PalSecurityManager.h" #include "PalSecurityManager.h"
#include "Callback.h" #include "Callback.h"
#include "ble/pal/GapTypes.h" #include "ble/pal/GapTypes.h"
#include "ble/BLETypes.h"
namespace ble { namespace ble {
namespace generic { namespace generic {
@ -36,6 +37,7 @@ using ble::pal::rand_t;
using ble::pal::pairing_failure_t; using ble::pal::pairing_failure_t;
using ble::pal::AuthenticationMask::AuthenticationFlags_t; using ble::pal::AuthenticationMask::AuthenticationFlags_t;
using ble::pal::AuthenticationMask; using ble::pal::AuthenticationMask;
using ble::pairing_failure_t;
typedef SecurityManager::SecurityIOCapabilities_t SecurityIOCapabilities_t; typedef SecurityManager::SecurityIOCapabilities_t SecurityIOCapabilities_t;
class PasskeyNum { class PasskeyNum {
@ -491,6 +493,39 @@ private:
/* implements ble::pal::SecurityManagerEventHandler */ /* implements ble::pal::SecurityManagerEventHandler */
public: public:
////////////////////////////////////////////////////////////////////////////
// Pairing
//
void on_pairing_request(connection_handle_t connection,
SecurityIOCapabilities_t iocaps,
bool use_oob,
AuthenticationMask authentication,
uint8_t max_key_size,
key_distribution_t initiator_dist,
key_distribution_t responder_dist) {
if (_app_event_handler && pairing_authorisation_required) {
_app_event_handler->acceptPairingRequest(connection);
}
}
void on_pairing_error(connection_handle_t connection, pairing_failure_t error) {
if (_app_event_handler) {
_app_event_handler->pairingError(connection, error);
}
}
void on_pairing_completed(connection_handle_t connection) {
if (_app_event_handler) {
_app_event_handler->pairingCompleted(connection);
}
}
////////////////////////////////////////////////////////////////////////////
// Security
//
void on_security_setup_initiated(connection_handle_t connection, void on_security_setup_initiated(connection_handle_t connection,
bool allow_bonding, bool allow_bonding,
bool require_mitm, bool require_mitm,
@ -499,12 +534,7 @@ public:
_app_event_handler->securitySetupInitiated(connection, allow_bonding, require_mitm, iocaps); _app_event_handler->securitySetupInitiated(connection, allow_bonding, require_mitm, iocaps);
} }
} }
void on_security_setup_completed(connection_handle_t connection,
SecurityManager::SecurityCompletionStatus_t status) {
if (_app_event_handler) {
_app_event_handler->securitySetupCompleted(connection, status);
}
}
void on_link_secured(connection_handle_t connection, void on_link_secured(connection_handle_t connection,
SecurityManager::SecurityMode_t security_mode) { SecurityManager::SecurityMode_t security_mode) {
if (_app_event_handler) { if (_app_event_handler) {
@ -512,27 +542,27 @@ public:
} }
} }
void on_security_context_stored(connection_handle_t connection) {
if (_app_event_handler) {
_app_event_handler->securityContextStored(connection);
}
}
void on_passkey_display(connection_handle_t connection,
const SecurityManager::Passkey_t passkey) {
if (_app_event_handler) {
_app_event_handler->passkeyDisplay(connection, passkey);
}
}
void on_valid_mic_timeout(connection_handle_t connection) { void on_valid_mic_timeout(connection_handle_t connection) {
if (_app_event_handler) { if (_app_event_handler) {
_app_event_handler->validMicTimeout(connection); _app_event_handler->validMicTimeout(connection);
} }
} }
void on_link_key_failure(connection_handle_t connection) { /* TODO: this appears to be redundant */
void on_security_context_stored(connection_handle_t connection) {
if (_app_event_handler) { if (_app_event_handler) {
_app_event_handler->linkKeyFailure(connection); _app_event_handler->securityContextStored(connection);
}
}
////////////////////////////////////////////////////////////////////////////
// MITM
//
void on_passkey_display(connection_handle_t connection,
const SecurityManager::Passkey_t passkey) {
if (_app_event_handler) {
_app_event_handler->passkeyDisplay(connection, passkey);
} }
} }
@ -543,6 +573,19 @@ public:
} }
} }
void on_passkey_request(connection_handle_t connection) {
if (_app_event_handler) {
_app_event_handler->passkeyRequest(connection);
}
}
void on_confirmation_request(connection_handle_t connection) {
if (_app_event_handler) {
_app_event_handler->confirmationRequest(connection);
}
}
void on_legacy_pariring_oob_request(connection_handle_t connection) { void on_legacy_pariring_oob_request(connection_handle_t connection) {
if (_app_event_handler) { if (_app_event_handler) {
_app_event_handler->legacyPairingOobRequest(connection); _app_event_handler->legacyPairingOobRequest(connection);
@ -554,35 +597,10 @@ public:
_app_event_handler->oobRequest(connection); _app_event_handler->oobRequest(connection);
} }
} }
void on_pin_request(connection_handle_t connection) {
if (_app_event_handler) { ////////////////////////////////////////////////////////////////////////////
_app_event_handler->pinRequest(connection); // Keys
} //
}
void on_passkey_request(connection_handle_t connection) {
if (_app_event_handler) {
_app_event_handler->passkeyRequest(connection);
}
}
void on_confirmation_request(connection_handle_t connection) {
if (_app_event_handler) {
_app_event_handler->confirmationRequest(connection);
}
}
void on_accept_pairing_request(connection_handle_t connection,
SecurityIOCapabilities_t iocaps,
bool use_oob,
AuthenticationMask authentication,
uint8_t max_key_size,
key_distribution_t initiator_dist,
key_distribution_t responder_dist) {
if (_app_event_handler && pairing_authorisation_required) {
_app_event_handler->acceptPairingRequest(connection);
}
}
void on_keys_distributed(connection_handle_t connection, void on_keys_distributed(connection_handle_t connection,
advertising_peer_address_type_t peer_address_type, advertising_peer_address_type_t peer_address_type,