Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SecurityManager.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __SECURITY_MANAGER_H__ 00018 #define __SECURITY_MANAGER_H__ 00019 00020 #include <stdint.h> 00021 00022 #include "Gap.h" 00023 #include "CallChainOfFunctionPointersWithContext.h" 00024 00025 class SecurityManager { 00026 public: 00027 enum SecurityMode_t { 00028 SECURITY_MODE_NO_ACCESS, 00029 SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< Require no protection, open link. */ 00030 SECURITY_MODE_ENCRYPTION_NO_MITM, /**< Require encryption, but no MITM protection. */ 00031 SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< Require encryption and MITM protection. */ 00032 SECURITY_MODE_SIGNED_NO_MITM, /**< Require signing or encryption, but no MITM protection. */ 00033 SECURITY_MODE_SIGNED_WITH_MITM, /**< Require signing or encryption, and MITM protection. */ 00034 }; 00035 00036 /** 00037 * @brief Defines possible security status or states. 00038 * 00039 * @details Defines possible security status or states of a link when requested by getLinkSecurity(). 00040 */ 00041 enum LinkSecurityStatus_t { 00042 NOT_ENCRYPTED, /**< The link is not secured. */ 00043 ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ 00044 ENCRYPTED /**< The link is secure.*/ 00045 }; 00046 00047 enum SecurityIOCapabilities_t { 00048 IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display only. */ 00049 IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and yes/no entry. */ 00050 IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard only. */ 00051 IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ 00052 IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and display. */ 00053 }; 00054 00055 enum SecurityCompletionStatus_t { 00056 SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ 00057 SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ 00058 SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ 00059 SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ 00060 SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ 00061 SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ 00062 SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ 00063 SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ 00064 SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ 00065 SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ 00066 SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ 00067 SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ 00068 SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ 00069 }; 00070 00071 /** 00072 * Declaration of type containing a passkey to be used during pairing. This 00073 * is passed into initializeSecurity() to specify a pre-programmed passkey 00074 * for authentication instead of generating a random one. 00075 */ 00076 static const unsigned PASSKEY_LEN = 6; 00077 typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ 00078 00079 public: 00080 typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle); 00081 typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); 00082 typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status); 00083 typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode); 00084 typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey); 00085 00086 typedef FunctionPointerWithContext<const SecurityManager *> SecurityManagerShutdownCallback_t; 00087 typedef CallChainOfFunctionPointersWithContext<const SecurityManager *> SecurityManagerShutdownCallbackChain_t; 00088 00089 /* 00090 * The following functions are meant to be overridden in the platform-specific sub-class. 00091 */ 00092 public: 00093 /** 00094 * Enable the BLE stack's Security Manager. The Security Manager implements 00095 * the actual cryptographic algorithms and protocol exchanges that allow two 00096 * devices to securely exchange data and privately detect each other. 00097 * Calling this API is a prerequisite for encryption and pairing (bonding). 00098 * 00099 * @param[in] enableBonding Allow for bonding. 00100 * @param[in] requireMITM Require protection for man-in-the-middle attacks. 00101 * @param[in] iocaps To specify the I/O capabilities of this peripheral, 00102 * such as availability of a display or keyboard, to 00103 * support out-of-band exchanges of security data. 00104 * @param[in] passkey To specify a static passkey. 00105 * 00106 * @return BLE_ERROR_NONE on success. 00107 */ 00108 virtual ble_error_t init(bool enableBonding = true, 00109 bool requireMITM = true, 00110 SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, 00111 const Passkey_t passkey = NULL) { 00112 /* Avoid compiler warnings about unused variables. */ 00113 (void)enableBonding; 00114 (void)requireMITM; 00115 (void)iocaps; 00116 (void)passkey; 00117 00118 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00119 } 00120 00121 /** 00122 * Get the security status of a connection. 00123 * 00124 * @param[in] connectionHandle Handle to identify the connection. 00125 * @param[out] securityStatusP Security status. 00126 * 00127 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00128 */ 00129 virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) { 00130 /* Avoid compiler warnings about unused variables. */ 00131 (void)connectionHandle; 00132 (void)securityStatusP; 00133 00134 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00135 } 00136 00137 /** 00138 * Set the security mode on a connection. Useful for elevating the security mode 00139 * once certain conditions are met, e.g., a particular service is found. 00140 * 00141 * @param[in] connectionHandle Handle to identify the connection. 00142 * @param[in] securityMode Requested security mode. 00143 * 00144 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00145 */ 00146 virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) { 00147 /* Avoid compiler warnings about unused variables. */ 00148 (void)connectionHandle; 00149 (void)securityMode; 00150 00151 return BLE_ERROR_NOT_IMPLEMENTED; 00152 } 00153 00154 /** 00155 * Delete all peer device context and all related bonding information from 00156 * the database within the security manager. 00157 * 00158 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00159 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00160 * application registration. 00161 */ 00162 virtual ble_error_t purgeAllBondingState(void) { 00163 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00164 } 00165 00166 /** 00167 * Get a list of addresses from all peers in the bond table. 00168 * 00169 * @param[in,out] addresses 00170 * (on input) addresses.capacity contains the maximum 00171 * number of addresses to be returned. 00172 * (on output) The populated table with copies of the 00173 * addresses in the implementation's whitelist. 00174 * 00175 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00176 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00177 * application registration. 00178 * 00179 * @experimental 00180 */ 00181 virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const { 00182 /* Avoid compiler warnings about unused variables */ 00183 (void) addresses; 00184 00185 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00186 } 00187 00188 /* Event callback handlers. */ 00189 public: 00190 /** 00191 * Setup a callback to be invoked to notify the user application that the 00192 * SecurityManager instance is about to shutdown (possibly as a result of a call 00193 * to BLE::shutdown()). 00194 * 00195 * @note It is possible to chain together multiple onShutdown callbacks 00196 * (potentially from different modules of an application) to be notified 00197 * before the SecurityManager is shutdown. 00198 * 00199 * @note It is also possible to set up a callback into a member function of 00200 * some object. 00201 * 00202 * @note It is possible to unregister a callback using onShutdown().detach(callback) 00203 */ 00204 void onShutdown(const SecurityManagerShutdownCallback_t& callback) { 00205 shutdownCallChain.add(callback); 00206 } 00207 template <typename T> 00208 void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { 00209 shutdownCallChain.add(objPtr, memberPtr); 00210 } 00211 00212 /** 00213 * @brief provide access to the callchain of shutdown event callbacks 00214 * It is possible to register callbacks using onShutdown().add(callback); 00215 * It is possible to unregister callbacks using onShutdown().detach(callback) 00216 * @return The shutdown event callbacks chain 00217 */ 00218 SecurityManagerShutdownCallbackChain_t& onShutdown() { 00219 return shutdownCallChain; 00220 } 00221 00222 /** 00223 * To indicate that a security procedure for the link has started. 00224 */ 00225 virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} 00226 00227 /** 00228 * To indicate that the security procedure for the link has completed. 00229 */ 00230 virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} 00231 00232 /** 00233 * To indicate that the link with the peer is secured. For bonded devices, 00234 * subsequent reconnections with a bonded peer will result only in this callback 00235 * when the link is secured; setup procedures will not occur (unless the 00236 * bonding information is either lost or deleted on either or both sides). 00237 */ 00238 virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} 00239 00240 /** 00241 * To indicate that device context is stored persistently. 00242 */ 00243 virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} 00244 00245 /** 00246 * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. 00247 */ 00248 virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} 00249 00250 /* Entry points for the underlying stack to report events back to the user. */ 00251 public: 00252 void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { 00253 if (securitySetupInitiatedCallback) { 00254 securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); 00255 } 00256 } 00257 00258 void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { 00259 if (securitySetupCompletedCallback) { 00260 securitySetupCompletedCallback(handle, status); 00261 } 00262 } 00263 00264 void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { 00265 if (linkSecuredCallback) { 00266 linkSecuredCallback(handle, securityMode); 00267 } 00268 } 00269 00270 void processSecurityContextStoredEvent(Gap::Handle_t handle) { 00271 if (securityContextStoredCallback) { 00272 securityContextStoredCallback(handle); 00273 } 00274 } 00275 00276 void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { 00277 if (passkeyDisplayCallback) { 00278 passkeyDisplayCallback(handle, passkey); 00279 } 00280 } 00281 00282 protected: 00283 SecurityManager() : 00284 securitySetupInitiatedCallback(), 00285 securitySetupCompletedCallback(), 00286 linkSecuredCallback(), 00287 securityContextStoredCallback(), 00288 passkeyDisplayCallback() { 00289 /* empty */ 00290 } 00291 00292 public: 00293 /** 00294 * Notify all registered onShutdown callbacks that the SecurityManager is 00295 * about to be shutdown and clear all SecurityManager state of the 00296 * associated object. 00297 * 00298 * This function is meant to be overridden in the platform-specific 00299 * sub-class. Nevertheless, the sub-class is only expected to reset its 00300 * state and not the data held in SecurityManager members. This shall be 00301 * achieved by a call to SecurityManager::reset() from the sub-class' 00302 * reset() implementation. 00303 * 00304 * @return BLE_ERROR_NONE on success. 00305 */ 00306 virtual ble_error_t reset(void) { 00307 /* Notify that the instance is about to shutdown */ 00308 shutdownCallChain.call(this); 00309 shutdownCallChain.clear(); 00310 00311 securitySetupInitiatedCallback = NULL; 00312 securitySetupCompletedCallback = NULL; 00313 linkSecuredCallback = NULL; 00314 securityContextStoredCallback = NULL; 00315 passkeyDisplayCallback = NULL; 00316 00317 return BLE_ERROR_NONE; 00318 } 00319 00320 protected: 00321 SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; 00322 SecuritySetupCompletedCallback_t securitySetupCompletedCallback; 00323 LinkSecuredCallback_t linkSecuredCallback; 00324 HandleSpecificEvent_t securityContextStoredCallback; 00325 PasskeyDisplayCallback_t passkeyDisplayCallback; 00326 00327 private: 00328 SecurityManagerShutdownCallbackChain_t shutdownCallChain; 00329 }; 00330 00331 #endif /*__SECURITY_MANAGER_H__*/
Generated on Thu Jul 14 2022 14:36:21 by
