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 virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const { 00180 /* Avoid compiler warnings about unused variables */ 00181 (void) addresses; 00182 00183 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00184 } 00185 00186 /* Event callback handlers. */ 00187 public: 00188 /** 00189 * Setup a callback to be invoked to notify the user application that the 00190 * SecurityManager instance is about to shutdown (possibly as a result of a call 00191 * to BLE::shutdown()). 00192 * 00193 * @note It is possible to chain together multiple onShutdown callbacks 00194 * (potentially from different modules of an application) to be notified 00195 * before the SecurityManager is shutdown. 00196 * 00197 * @note It is also possible to set up a callback into a member function of 00198 * some object. 00199 * 00200 * @note It is possible to unregister a callback using onShutdown().detach(callback) 00201 */ 00202 void onShutdown(const SecurityManagerShutdownCallback_t& callback) { 00203 shutdownCallChain.add(callback); 00204 } 00205 template <typename T> 00206 void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { 00207 shutdownCallChain.add(objPtr, memberPtr); 00208 } 00209 00210 /** 00211 * @brief provide access to the callchain of shutdown event callbacks 00212 * It is possible to register callbacks using onShutdown().add(callback); 00213 * It is possible to unregister callbacks using onShutdown().detach(callback) 00214 * @return The shutdown event callbacks chain 00215 */ 00216 SecurityManagerShutdownCallbackChain_t& onShutdown() { 00217 return shutdownCallChain; 00218 } 00219 00220 /** 00221 * To indicate that a security procedure for the link has started. 00222 */ 00223 virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} 00224 00225 /** 00226 * To indicate that the security procedure for the link has completed. 00227 */ 00228 virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} 00229 00230 /** 00231 * To indicate that the link with the peer is secured. For bonded devices, 00232 * subsequent reconnections with a bonded peer will result only in this callback 00233 * when the link is secured; setup procedures will not occur (unless the 00234 * bonding information is either lost or deleted on either or both sides). 00235 */ 00236 virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} 00237 00238 /** 00239 * To indicate that device context is stored persistently. 00240 */ 00241 virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} 00242 00243 /** 00244 * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. 00245 */ 00246 virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} 00247 00248 /* Entry points for the underlying stack to report events back to the user. */ 00249 public: 00250 void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { 00251 if (securitySetupInitiatedCallback) { 00252 securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); 00253 } 00254 } 00255 00256 void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { 00257 if (securitySetupCompletedCallback) { 00258 securitySetupCompletedCallback(handle, status); 00259 } 00260 } 00261 00262 void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { 00263 if (linkSecuredCallback) { 00264 linkSecuredCallback(handle, securityMode); 00265 } 00266 } 00267 00268 void processSecurityContextStoredEvent(Gap::Handle_t handle) { 00269 if (securityContextStoredCallback) { 00270 securityContextStoredCallback(handle); 00271 } 00272 } 00273 00274 void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { 00275 if (passkeyDisplayCallback) { 00276 passkeyDisplayCallback(handle, passkey); 00277 } 00278 } 00279 00280 protected: 00281 SecurityManager() : 00282 securitySetupInitiatedCallback(), 00283 securitySetupCompletedCallback(), 00284 linkSecuredCallback(), 00285 securityContextStoredCallback(), 00286 passkeyDisplayCallback() { 00287 /* empty */ 00288 } 00289 00290 public: 00291 /** 00292 * Notify all registered onShutdown callbacks that the SecurityManager is 00293 * about to be shutdown and clear all SecurityManager state of the 00294 * associated object. 00295 * 00296 * This function is meant to be overridden in the platform-specific 00297 * sub-class. Nevertheless, the sub-class is only expected to reset its 00298 * state and not the data held in SecurityManager members. This shall be 00299 * achieved by a call to SecurityManager::reset() from the sub-class' 00300 * reset() implementation. 00301 * 00302 * @return BLE_ERROR_NONE on success. 00303 */ 00304 virtual ble_error_t reset(void) { 00305 /* Notify that the instance is about to shutdown */ 00306 shutdownCallChain.call(this); 00307 shutdownCallChain.clear(); 00308 00309 securitySetupInitiatedCallback = NULL; 00310 securitySetupCompletedCallback = NULL; 00311 linkSecuredCallback = NULL; 00312 securityContextStoredCallback = NULL; 00313 passkeyDisplayCallback = NULL; 00314 00315 return BLE_ERROR_NONE; 00316 } 00317 00318 protected: 00319 SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; 00320 SecuritySetupCompletedCallback_t securitySetupCompletedCallback; 00321 LinkSecuredCallback_t linkSecuredCallback; 00322 HandleSpecificEvent_t securityContextStoredCallback; 00323 PasskeyDisplayCallback_t passkeyDisplayCallback; 00324 00325 private: 00326 SecurityManagerShutdownCallbackChain_t shutdownCallChain; 00327 }; 00328 00329 #endif /*__SECURITY_MANAGER_H__*/
Generated on Tue Jul 12 2022 13:25:06 by
1.7.2