init
Embed:
(wiki syntax)
Show/hide line numbers
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