From 2f04aece23ff13205c622bb668bf82c7435a56c1 Mon Sep 17 00:00:00 2001 From: paul-szczepanek-arm <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Wed, 17 Jan 2018 21:22:48 +0000 Subject: [PATCH] shared types in common header, connected up the events in handlers --- features/FEATURE_BLE/ble/BLETypes.h | 49 ++++++ features/FEATURE_BLE/ble/SecurityManager.h | 144 ++++++++++++------ .../FEATURE_BLE/ble/pal/PalSecurityManager.h | 126 ++++++--------- .../source/generic/GenericSecurityManager.cpp | 114 ++++++++------ 4 files changed, 260 insertions(+), 173 deletions(-) diff --git a/features/FEATURE_BLE/ble/BLETypes.h b/features/FEATURE_BLE/ble/BLETypes.h index cf71d040df..ba13114036 100644 --- a/features/FEATURE_BLE/ble/BLETypes.h +++ b/features/FEATURE_BLE/ble/BLETypes.h @@ -19,6 +19,7 @@ #include #include +#include "ble/SafeEnum.h" /** * @addtogroup ble @@ -117,6 +118,54 @@ static inline attribute_handle_range_t attribute_handle_range( return result; } + +/** + * Type that describe a pairing failure. + */ +struct pairing_failure_t : SafeEnum { + 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(value) { } +}; + + +/** + * Type that describe the IO capability of a device; it is used during Pairing + * Feature exchange. + */ +struct io_capability_t : SafeEnum { + 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(value) { } +}; + } // namespace ble /** diff --git a/features/FEATURE_BLE/ble/SecurityManager.h b/features/FEATURE_BLE/ble/SecurityManager.h index f13f53e39a..351982ad1c 100644 --- a/features/FEATURE_BLE/ble/SecurityManager.h +++ b/features/FEATURE_BLE/ble/SecurityManager.h @@ -21,11 +21,13 @@ #include "Gap.h" #include "CallChainOfFunctionPointersWithContext.h" +#include "ble/BLETypes.h" class SecurityManagerEventHandler; class LegacySecurityManagerEventHandler; using ble::connection_handle_t; +using ble::pairing_failure_t; class SecurityManager { public: @@ -109,60 +111,82 @@ public: 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) { (void)handle; (void)allowBonding; (void)requireMITM; (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) { (void)handle; (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) { (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) { if (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: @@ -176,26 +200,49 @@ private: securityContextStoredCallback(), 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) { if (securitySetupInitiatedCallback) { 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) { if (linkSecuredCallback) { linkSecuredCallback(handle, securityMode); } }; + + /* TODO: this appears to be redundant */ void securityContextStored(connection_handle_t handle) { if (securityContextStoredCallback) { securityContextStoredCallback(handle); } } + + //////////////////////////////////////////////////////////////////////////// + // MITM + // + void passkeyDisplay(connection_handle_t handle, const SecurityManager::Passkey_t passkey) { if (passkeyDisplayCallback) { passkeyDisplayCallback(handle, passkey); @@ -604,7 +651,14 @@ public: } /** @deprecated */ 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 */ void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { diff --git a/features/FEATURE_BLE/ble/pal/PalSecurityManager.h b/features/FEATURE_BLE/ble/pal/PalSecurityManager.h index ed14092735..dc31c732ca 100644 --- a/features/FEATURE_BLE/ble/pal/PalSecurityManager.h +++ b/features/FEATURE_BLE/ble/pal/PalSecurityManager.h @@ -20,7 +20,6 @@ #include "platform/Callback.h" #include "platform/NonCopyable.h" #include "ble/BLETypes.h" -#include "ble/SafeEnum.h" #include "ble/BLEProtocol.h" #include "ble/SecurityManager.h" #include "ble/pal/GapTypes.h" @@ -28,53 +27,6 @@ namespace ble { namespace pal { -/** - * Type that describe the IO capability of a device; it is used during Pairing - * Feature exchange. - */ -struct io_capability_t : SafeEnum { - 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(value) { } -}; - - -/** - * Type that describe a pairing failure. - */ -struct pairing_failure_t : SafeEnum { - 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(value) { } -}; - typedef SecurityManager::SecurityCompletionStatus_t SecurityCompletionStatus_t; typedef SecurityManager::SecurityMode_t SecurityMode_t; typedef SecurityManager::LinkSecurityStatus_t LinkSecurityStatus_t; @@ -106,7 +58,7 @@ enum KeyDistributionFlags_t { class AuthenticationMask { public: enum AuthenticationFlags_t { - AUTHENTICATION_BONDABLE = 0x01, + AUTHENTICATION_BONDABLE = 0x01, AUTHENTICATION_MITM = 0x04, /* 0x02 missing because bonding uses two bits */ AUTHENTICATION_SECURE_CONNECTIONS = 0x08, AUTHENTICATION_KEYPRESS_NOTIFICATION = 0x10 @@ -176,6 +128,10 @@ public: */ class SecurityManagerEventHandler { public: + //////////////////////////////////////////////////////////////////////////// + // Pairing + // + /** * Called upon reception of a pairing request. * @@ -204,27 +160,15 @@ public: ) = 0; /** - * Called when the application should display a passkey. + * To indicate that the pairing for the link has completed. */ - virtual void on_passkey_display( - connection_handle_t connection, const passkey_num_t passkey + virtual void on_pairing_completed( + 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; - - /** - * 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; + //////////////////////////////////////////////////////////////////////////// + // Security + // /** * To indicate that a security procedure for the link has started. @@ -236,14 +180,6 @@ public: io_capability_t iocaps ) = 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, * 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_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 @@ -275,11 +235,17 @@ public: virtual void on_legacy_pariring_oob_request(connection_handle_t connection) = 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 + * 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_confirmation_request(connection_handle_t connection) = 0; + virtual void on_oob_data_request(connection_handle_t connection) = 0; + + + //////////////////////////////////////////////////////////////////////////// + // Keys + // virtual void on_keys_distributed( connection_handle_t handle, diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index 9c206310e6..7b9ac71da0 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -21,6 +21,7 @@ #include "PalSecurityManager.h" #include "Callback.h" #include "ble/pal/GapTypes.h" +#include "ble/BLETypes.h" namespace ble { namespace generic { @@ -36,6 +37,7 @@ using ble::pal::rand_t; using ble::pal::pairing_failure_t; using ble::pal::AuthenticationMask::AuthenticationFlags_t; using ble::pal::AuthenticationMask; +using ble::pairing_failure_t; typedef SecurityManager::SecurityIOCapabilities_t SecurityIOCapabilities_t; class PasskeyNum { @@ -491,6 +493,39 @@ private: /* implements ble::pal::SecurityManagerEventHandler */ 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, bool allow_bonding, bool require_mitm, @@ -499,12 +534,7 @@ public: _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, SecurityManager::SecurityMode_t security_mode) { 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) { if (_app_event_handler) { _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) { - _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) { if (_app_event_handler) { _app_event_handler->legacyPairingOobRequest(connection); @@ -554,35 +597,10 @@ public: _app_event_handler->oobRequest(connection); } } - void on_pin_request(connection_handle_t connection) { - if (_app_event_handler) { - _app_event_handler->pinRequest(connection); - } - } - 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); - } - } + //////////////////////////////////////////////////////////////////////////// + // Keys + // void on_keys_distributed(connection_handle_t connection, advertising_peer_address_type_t peer_address_type,