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.
Dependencies: nRF51_Vdd TextLCD BME280
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 #include "ble/BLETypes.h" 00025 00026 /** 00027 * Overview 00028 * 00029 * Security Manager is used to provide link security through encryption, signing and authentication 00030 * which are made possible by pairing and optionally bonding. Pairing is the process of establishing 00031 * and/or exchanging keys used for the current connection. Bonding means saving this information so that 00032 * it can later be used after reconnecting without having to pair again. This saves time and power. 00033 * 00034 * @par Paring 00035 * 00036 * There are several ways to provide different levels of security during pairing depending on your requirements 00037 * and the facilities provided by the application. The process starts with initialising the SecurityManager 00038 * with default options for new connections. Some settings can later be changed per link or globally. 00039 * 00040 * The important settings in the init() function are the MITM requirement and IO capabilities. Man in the 00041 * Middle (MITM) protection prevents an attack where one device can impersonate another device by 00042 * pairing with both devices at the same time. This protection is achieved by sharing some information 00043 * between the devices through some independent channel. The IO capabilities of both devices dictate 00044 * what algorithm is used. For details @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 2.3.5.1. 00045 * You can change the IO capabilities after initialisation with setIoCapability(). This will take effect 00046 * for all subsequent pairings. 00047 * 00048 * @par Out of Band data used in pairing 00049 * 00050 * Sharing this information through IO capabilities means user interaction which limits the degree of 00051 * protection due to the limit of the amount of data that we can expect the user to transfer. Another 00052 * solution is using OOB (out of band) communication to transfer this data instead which can send much 00053 * more data making MITM attack even less likely to succeed. OOB data has to be exchanged by the application 00054 * and provided to the Security Manager. Use setOOBDataUsage() to indicate you want to use it. The same call also 00055 * allows you to set whether or not the communication channel you are using to transmit the OOB data is 00056 * itself secure against MITM protection - this will set the level of the link security achieved using pairing 00057 * that uses this data. 00058 * 00059 * The most secure pairing is provided by Secure Connections which relies on Elliptical Curve Cryptography. 00060 * Support for Secure Connections is dependent on both the stack and controller on both sides supporting 00061 * it. If either side doesn't support it Legacy Pairing will be used. This is an older standard of pairing. 00062 * If higher security is required legacy pairing can be disabled by calling allowLegacyPairing(false); 00063 * 00064 * @par Signing 00065 * 00066 * Applications may require a level of security providing confidence that data transfers are coming 00067 * from a trusted source. This can be achieved by encrypting the link which also provides added confidentiality. 00068 * Encryption is a good choice when a device stays connected but introduces latency due to the need of encrypting the 00069 * link if the device only connects periodically to transfer data. If confidentiality is not required data GATT 00070 * server may allow writes to happen over an unencrypted link but authenticated by a signature present in each packet. 00071 * This signature relies on having sent a signing key to the peer during pairing prior to sending any signed packets. 00072 * 00073 * @par Persistence of Security information 00074 * 00075 * Security Manager stores all the data required for its operation on active links. Depending on resources 00076 * available on the device it will also attempt to store data for disconnected devices which have bonded to be 00077 * reused when reconnected. 00078 * 00079 * If the application has initialised a filesystem and the Security Manager has been provided with a 00080 * filepath during the init() call it may also provide data persistence across resets. This must be enabled by 00081 * calling preserveBondingStateOnReset(). Persistence is not guaranteed and may fail if abnormally terminated. 00082 * The Security Manager may also fall back to a non-persistent implementation if the resources are too limited. 00083 * 00084 * @par How to use 00085 * 00086 * First thing you need to do is to initialise the manager by calling init() with your chosen settings. 00087 * 00088 * The SecurityManager communicates with your application through events. These will trigger calls in 00089 * the EventHandler which you must provide by calling the setSecurityManagerEventHandler() function. 00090 * 00091 * The most important process is pairing. This may be triggered manually by calling requestPairing() or 00092 * may be called as a result of the application requiring encryption by calling setLinkEncryption() or 00093 * as a result of the application requiring MITM protection through requestAuthentication(). 00094 * 00095 * All these can be implicitly called by using setLinkSecurity() to conveniently set the required 00096 * security for the link. The SecurityManager will trigger all the process required to achieve the set 00097 * security level. Security level can only be escalated. Asking the Security Manager for a lower 00098 * security level than the existing one will not fail but will result in a event informing the 00099 * application through linkEncryptionResult() of the current level (which remains unchanged). 00100 * 00101 * Depending on the IO capabilities and OOB usage settings different pairing algorithms will be chosen. 00102 * They will produce appropriate events which must be handled by your EventHandler. If your event handler 00103 * doesn't support all the calls you must not set IO capabilities or set OOB usage in such a way that would 00104 * trigger them or else the pairing will fail (usually by timing out). 00105 * 00106 * The simplest example is a pairing of a device with no IO capabilities and no OOB data available. 00107 * With such limited pairing capabilities the "just works" method will be employed. This does not provide 00108 * any MITM protection. The pairing (triggered implicitly or called explicitly) will result in an event 00109 * being generated on the peer calling pairingRequest(). The event handler must make a decision (either in 00110 * the application itself or based on user interaction) whether to accept the pairing and call 00111 * accetPairing() or cancelPairing(). The result will be communicated on both peers through an event calling 00112 * pairingResult() in the EventHandler. 00113 * 00114 * @par Sequence diagrams 00115 * 00116 * Sequence diagram "Just Works" pairing 00117 * 00118 * \verbatim 00119 * /----------- Device 1 --------------\ *------ BLE link ------* /-------------- Device 2 -------------\ 00120 * 00121 * App EventHandler SecurityManager SecurityManager EventHandler App 00122 * | | | | | | 00123 * |---------------------------> requestPairing() | | | 00124 * | | |------[pairing start]------>| | | 00125 * | | | |----------------> pairingRequest() ->| 00126 * | | | acceptPairing() <------------------------ | 00127 * | | |<---[pairing complete]----->| | | 00128 * |<- pairingResult() <---------------| |----------------> pairingResult() -->| 00129 * | | | | | | 00130 * @endverbatim 00131 * 00132 * @note the requestPairing() call isn't required to trigger pairing. Pairing will also be triggered 00133 * if you request encryption and authentication and no bonding information is available. The sequence will 00134 * be the same save for the lack of explicit requestPairing() call. 00135 * 00136 * 00137 * Sequence diagram Encryption request when bonding information is available 00138 * 00139 * \verbatim 00140 * /----------- Device 1 --------------\ *------ BLE link ------* /-------------- Device 2 -------------\ 00141 * 00142 * App EventHandler SecurityManager SecurityManager EventHandler App 00143 * | | | | | | 00144 * |---------------------------> setLinkEncryption() | | | 00145 * | | |<-[encryption established]->| | | 00146 * |<- linkEncryptionResult() <--------| |---------> linkEncryptionResult() -->| 00147 * | | | | | | 00148 * @endverbatim 00149 * 00150 * @note if bonding information is not available, pairing will be triggered 00151 * 00152 * 00153 * Sequence diagram for Secure Connections passkey entry pairing with one device having a display only 00154 * and other a keyboard 00155 * 00156 * \verbatim 00157 * /----------- Device 1 (keyboard) ---\ *------ BLE link ------* /-------------- Device 2 (display) ---\ 00158 * 00159 * App EventHandler SecurityManager SecurityManager EventHandler App 00160 * | | | | | | 00161 * |---------------------------> requestPairing() | | | 00162 * | | |------[pairing start]------>| | | 00163 * | | | |----------------> pairingRequest() ->| 00164 * | | | acceptPairing() <------------------------ | 00165 * | | |<---[secure con. pairing]-->| | | 00166 * |<- passkeyRequest() <--------------| |----------------> passkeyDisplay() ->| 00167 * | | | | | | 00168 * 00169 * user reads the passkey on Device 2 and inputs it on Device 1 00170 * 00171 * | | | | | | 00172 * |-------------------------->passkeyEntered() | | | 00173 * | | |<---[pairing complete]----->| | | 00174 * |<- pairingResult() <---------------| |----------------> pairingResult() -->| 00175 * | | | | | | 00176 * @endverbatim 00177 * 00178 */ 00179 00180 class SecurityManager { 00181 public: 00182 /** events sent and received when passkey is being entered */ 00183 enum Keypress_t { 00184 KEYPRESS_STARTED, /**< Passkey entry started */ 00185 KEYPRESS_ENTERED, /**< Passkey digit entered */ 00186 KEYPRESS_ERASED, /**< Passkey digit erased */ 00187 KEYPRESS_CLEARED, /**< Passkey cleared */ 00188 KEYPRESS_COMPLETED, /**< Passkey entry completed */ 00189 }; 00190 00191 /** level of security required from the link by the application */ 00192 enum SecurityMode_t { 00193 SECURITY_MODE_NO_ACCESS, 00194 SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< Require no protection, open link. */ 00195 SECURITY_MODE_ENCRYPTION_NO_MITM, /**< Require encryption, but no MITM protection. */ 00196 SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< Require encryption and MITM protection. */ 00197 SECURITY_MODE_SIGNED_NO_MITM, /**< Require signing or encryption, but no MITM protection. */ 00198 SECURITY_MODE_SIGNED_WITH_MITM, /**< Require signing or encryption, and MITM protection. */ 00199 }; 00200 00201 /** 00202 * @brief Defines possible security status or states. 00203 * 00204 * @details Defines possible security status or states of a link when requested by getLinkSecurity(). 00205 */ 00206 enum LinkSecurityStatus_t { 00207 NOT_ENCRYPTED, /**< The link is not secured. */ 00208 ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ 00209 ENCRYPTED /**< The link is secure.*/ 00210 }; 00211 00212 /** Input/output capability of the device and application */ 00213 enum SecurityIOCapabilities_t { 00214 IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display only. */ 00215 IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and yes/no entry. */ 00216 IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard only. */ 00217 IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ 00218 IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and display. */ 00219 }; 00220 00221 /** Result of security requests */ 00222 enum SecurityCompletionStatus_t { 00223 SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ 00224 SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ 00225 SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ 00226 SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user cancelled or other). */ 00227 SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ 00228 SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ 00229 SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ 00230 SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ 00231 SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ 00232 SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ 00233 SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ 00234 SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ 00235 SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ 00236 SEC_STATUS_DHKEY_CHECK_FAILED = 0x8B, /**< DHKey received doesn’t match locally calculated one. */ 00237 SEC_STATUS_COMPARISON_FAILED = 0x8C, /**< Values in the numeric comparison protocol do not match. */ 00238 }; 00239 00240 /** 00241 * Declaration of type containing a passkey to be used during pairing. This 00242 * is passed into initializeSecurity() to specify a pre-programmed passkey 00243 * for authentication instead of generating a random one. 00244 */ 00245 static const unsigned PASSKEY_LEN = 6; 00246 typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ 00247 00248 typedef FunctionPointerWithContext<const SecurityManager *> SecurityManagerShutdownCallback_t ; 00249 typedef CallChainOfFunctionPointersWithContext<const SecurityManager *> SecurityManagerShutdownCallbackChain_t ; 00250 00251 /* legacy callbacks, please use SecurityManagerEventHandler instead */ 00252 typedef void (*HandleSpecificEvent_t)(ble::connection_handle_t connectionHandle); 00253 typedef void (*SecuritySetupInitiatedCallback_t)(ble::connection_handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); 00254 typedef void (*SecuritySetupCompletedCallback_t)(ble::connection_handle_t, SecurityCompletionStatus_t status); 00255 typedef void (*LinkSecuredCallback_t)(ble::connection_handle_t connectionHandle, SecurityMode_t securityMode); 00256 typedef void (*PasskeyDisplayCallback_t)(ble::connection_handle_t connectionHandle, const Passkey_t passkey); 00257 00258 /** The stack will use these functions to signal events to the application, 00259 * subclass to override handlers. Use SecurityManager::setSecurityManagerEventHandler 00260 * to set the interface implementation to be used. */ 00261 class EventHandler { 00262 public: 00263 EventHandler() {}; 00264 virtual ~EventHandler() {}; 00265 00266 //////////////////////////////////////////////////////////////////////////// 00267 // Pairing 00268 // 00269 00270 /** 00271 * Request application to accept or reject pairing. Application should respond by 00272 * calling the appropriate function: acceptPairingRequest or cancelPairingRequest 00273 * 00274 * @param[in] connectionHandle connection connectionHandle 00275 */ 00276 virtual void pairingRequest(ble::connection_handle_t connectionHandle) { 00277 (void)connectionHandle; 00278 } 00279 00280 /** 00281 * Indicate to the application that pairing has completed. 00282 * 00283 * @param[in] connectionHandle connection connectionHandle 00284 * @param[in] result result of the pairing indicating success or reason for failure 00285 */ 00286 virtual void pairingResult(ble::connection_handle_t connectionHandle, SecurityCompletionStatus_t result) { 00287 (void)connectionHandle; 00288 (void)result; 00289 } 00290 00291 //////////////////////////////////////////////////////////////////////////// 00292 // Security 00293 // 00294 00295 /** 00296 * Deliver the requested whitelist to the application. 00297 * 00298 * @param[in] whitelist pointer to the whitelist filled with entries based on bonding information 00299 */ 00300 virtual void whitelistFromBondTable(Gap::Whitelist_t* whitelist) { 00301 (void)whitelist; 00302 } 00303 00304 //////////////////////////////////////////////////////////////////////////// 00305 // Encryption 00306 // 00307 00308 /** 00309 * Inform the device of the encryption state of a given link. 00310 * 00311 * @param[in] connectionHandle connection connectionHandle 00312 * @param[in] result encryption state of the link 00313 */ 00314 virtual void linkEncryptionResult(ble::connection_handle_t connectionHandle, ble::link_encryption_t result) { 00315 (void)connectionHandle; 00316 (void)result; 00317 } 00318 00319 //////////////////////////////////////////////////////////////////////////// 00320 // MITM 00321 // 00322 00323 /** 00324 * Display the given passkey on the local device. 00325 * 00326 * @param[in] connectionHandle connection connectionHandle 00327 * @param[in] passkey 6 digit passkey to be displayed 00328 */ 00329 virtual void passkeyDisplay(ble::connection_handle_t connectionHandle, const SecurityManager::Passkey_t passkey) { 00330 (void)connectionHandle; 00331 (void)passkey; 00332 } 00333 00334 /** 00335 * Indicate to the application that a confirmation is required. This is used 00336 * when the device does not have a keyboard but has a yes/no button. The device 00337 * displays numbers on its display in response to passkeyDisplay and the user 00338 * checks if they are the same on both devices. The application should proceed 00339 * by supplying the confirmation using the confirmationEntered function. 00340 * 00341 * @param[in] connectionHandle connection connectionHandle 00342 */ 00343 virtual void confirmationRequest(ble::connection_handle_t connectionHandle) { 00344 (void)connectionHandle; 00345 } 00346 00347 /** 00348 * Indicate to the application that a passkey is required. The application should 00349 * proceed by supplying the passkey through the passkeyEntered function. 00350 * 00351 * @param[in] connectionHandle connection connectionHandle 00352 */ 00353 virtual void passkeyRequest(ble::connection_handle_t connectionHandle) { 00354 (void)connectionHandle; 00355 } 00356 00357 /** 00358 * Notify the application that a key was pressed by the peer during passkey entry. 00359 * 00360 * @param[in] connectionHandle connection connectionHandle 00361 * @param[in] keypress type of keypress event 00362 */ 00363 virtual void keypressNotification(ble::connection_handle_t connectionHandle, SecurityManager::Keypress_t keypress) { 00364 (void)connectionHandle; 00365 (void)keypress; 00366 } 00367 00368 /** 00369 * Indicate to the application it needs to return legacy pairing OOB to the stack. 00370 * 00371 * @param[in] connectionHandle connection connectionHandle 00372 */ 00373 virtual void legacyPairingOobRequest(ble::connection_handle_t connectionHandle) { 00374 (void)connectionHandle; 00375 } 00376 00377 /** 00378 * Indicate that the application needs to send legacy pairing OOB data to the peer. 00379 * 00380 * @param[in] address address that will be used in the pairing 00381 * @param[in] temporaryKey temporary key to be used in legacy pairing 00382 */ 00383 virtual void legacyPairingOobGenerated(const ble::address_t *address, 00384 const ble::oob_tk_t *temporaryKey) { 00385 (void)address; 00386 (void)temporaryKey; 00387 } 00388 00389 /** 00390 * Indicate that the application needs to send secure connections OOB data to the peer. 00391 * 00392 * @param[in] address address that will be used in the pairing 00393 * @param[in] random random number used to generate the confirmation 00394 * @param[in] confirm confirmation value to be use for authentication 00395 * in secure connections pairing 00396 */ 00397 virtual void oobGenerated(const ble::address_t *address, 00398 const ble::oob_lesc_value_t *random, 00399 const ble::oob_confirm_t *confirm) { 00400 (void)address; 00401 (void)random; 00402 (void)confirm; 00403 } 00404 00405 //////////////////////////////////////////////////////////////////////////// 00406 // Keys 00407 // 00408 00409 /** 00410 * Deliver the signing key to the application. 00411 * 00412 * @param[in] connectionHandle connection connectionHandle 00413 * @param[in] csrk signing key, pointer only valid during call 00414 * @param[in] authenticated indicates if the signing key is authenticated 00415 */ 00416 virtual void signingKey(ble::connection_handle_t connectionHandle, const ble::csrk_t *csrk, bool authenticated) { 00417 (void)connectionHandle; 00418 (void)csrk; 00419 (void)authenticated; 00420 } 00421 }; 00422 00423 /* 00424 * The following functions are meant to be overridden in the platform-specific sub-class. 00425 */ 00426 public: 00427 //////////////////////////////////////////////////////////////////////////// 00428 // SM lifecycle management 00429 // 00430 00431 /** 00432 * Enable the BLE stack's Security Manager. The Security Manager implements 00433 * the actual cryptographic algorithms and protocol exchanges that allow two 00434 * devices to securely exchange data and privately detect each other. 00435 * Calling this API is a prerequisite for encryption and pairing (bonding). 00436 * 00437 * @param[in] enableBonding Allow for bonding. 00438 * @param[in] requireMITM Require protection for man-in-the-middle attacks. 00439 * @param[in] iocaps To specify the I/O capabilities of this peripheral, 00440 * such as availability of a display or keyboard, to 00441 * support out-of-band exchanges of security data. 00442 * @param[in] passkey To specify a static passkey. 00443 * @param[in] signing Generate and distribute signing key during pairing 00444 * @param[in] dbFilepath Path to the file used to store keys in the filesystem, 00445 * if NULL keys will be only stored in memory 00446 * 00447 * 00448 * @return BLE_ERROR_NONE on success. 00449 */ 00450 virtual ble_error_t init(bool enableBonding = true, 00451 bool requireMITM = true, 00452 SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, 00453 const Passkey_t passkey = NULL, 00454 bool signing = true, 00455 const char *dbFilepath = NULL) { 00456 /* Avoid compiler warnings about unused variables. */ 00457 (void)enableBonding; 00458 (void)requireMITM; 00459 (void)iocaps; 00460 (void)passkey; 00461 (void)dbFilepath; 00462 00463 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00464 } 00465 00466 /** 00467 * Change the file used for the security database. If path is invalid or a NULL is passed 00468 * keys will only be stored in memory. 00469 * 00470 * @note This operation is only allowed with no active connections. 00471 * 00472 * @param[in] dbFilepath Path to the file used to store keys in the filesystem, 00473 * if NULL keys will be only stored in memory 00474 * 00475 * @return BLE_ERROR_NONE on success. 00476 */ 00477 virtual ble_error_t setDatabaseFilepath(const char *dbFilepath = NULL) { 00478 (void)dbFilepath; 00479 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00480 } 00481 00482 /** 00483 * Notify all registered onShutdown callbacks that the SecurityManager is 00484 * about to be shutdown and clear all SecurityManager state of the 00485 * associated object. 00486 * 00487 * This function is meant to be overridden in the platform-specific 00488 * sub-class. Nevertheless, the sub-class is only expected to reset its 00489 * state and not the data held in SecurityManager members. This shall be 00490 * achieved by a call to SecurityManager::reset() from the sub-class' 00491 * reset() implementation. 00492 * 00493 * @return BLE_ERROR_NONE on success. 00494 */ 00495 virtual ble_error_t reset(void) { 00496 /* Notify that the instance is about to shutdown */ 00497 shutdownCallChain.call(this); 00498 shutdownCallChain.clear(); 00499 eventHandler = &defaultEventHandler; 00500 00501 return BLE_ERROR_NONE; 00502 } 00503 00504 /** 00505 * Normally all bonding information is lost when device is reset, this requests that the stack 00506 * attempts to save the information and reload it during initialisation. This is not guaranteed. 00507 * 00508 * @param[in] enable if true the stack will attempt to preserve bonding information on reset. 00509 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00510 */ 00511 virtual ble_error_t preserveBondingStateOnReset(bool enable) { 00512 /* Avoid compiler warnings about unused variables */ 00513 (void) enable; 00514 00515 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00516 } 00517 00518 //////////////////////////////////////////////////////////////////////////// 00519 // List management 00520 // 00521 00522 /** 00523 * Delete all peer device context and all related bonding information from 00524 * the database within the security manager. 00525 * 00526 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00527 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00528 * application registration. 00529 */ 00530 virtual ble_error_t purgeAllBondingState(void) { 00531 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00532 } 00533 00534 /** 00535 * Create a list of addresses from all peers in the bond table and generate 00536 * an event which returns it as a whitelist. Pass in the container for the whitelist. 00537 * This will be returned by the event. 00538 * 00539 * @param[in] whitelist Preallocated whitelist which will be filled up to its capacity. 00540 * If whitelist already contains entries this will be appended to. 00541 * Do not access the whitelist until callback has been called, 00542 * returning the filled whitelist. 00543 * 00544 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure 00545 */ 00546 virtual ble_error_t generateWhitelistFromBondTable(Gap::Whitelist_t *whitelist) const { 00547 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00548 } 00549 00550 //////////////////////////////////////////////////////////////////////////// 00551 // Pairing 00552 // 00553 00554 /** 00555 * Request pairing with the peer. Called by the master. 00556 * @note Slave can call requestAuthentication or setLinkEncryption to achieve security. 00557 * 00558 * @param[in] connectionHandle Handle to identify the connection. 00559 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00560 */ 00561 virtual ble_error_t requestPairing(ble::connection_handle_t connectionHandle) { 00562 (void) connectionHandle; 00563 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00564 } 00565 00566 /** 00567 * Accept the pairing request. Called as a result of pairingRequest being called 00568 * on the event handler. 00569 * 00570 * @param[in] connectionHandle Handle to identify the connection. 00571 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00572 */ 00573 virtual ble_error_t acceptPairingRequest(ble::connection_handle_t connectionHandle) { 00574 (void) connectionHandle; 00575 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00576 } 00577 00578 /** 00579 * Reject pairing request if the local device is the slave or cancel an outstanding 00580 * pairing request if master. 00581 * 00582 * @param[in] connectionHandle Handle to identify the connection. 00583 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00584 */ 00585 virtual ble_error_t cancelPairingRequest(ble::connection_handle_t connectionHandle) { 00586 (void) connectionHandle; 00587 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00588 } 00589 00590 /** 00591 * Tell the stack whether the application needs to authorise pairing requests or should 00592 * they be automatically accepted. 00593 * 00594 * @param[in] required If set to true, pairingRequest in the event handler will 00595 * will be called and will require an action from the application 00596 * to continue with pairing by calling acceptPairingRequest 00597 * or cancelPairingRequest if the user wishes to reject it. 00598 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00599 */ 00600 virtual ble_error_t setPairingRequestAuthorisation(bool required = true) { 00601 (void) required; 00602 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00603 } 00604 00605 //////////////////////////////////////////////////////////////////////////// 00606 // Feature support 00607 // 00608 00609 /** 00610 * Allow of disallow the use of legacy pairing in case the application only wants 00611 * to force the use of Secure Connections. If legacy pairing is disallowed and either 00612 * side doesn't support Secure Connections the pairing will fail. 00613 * 00614 * @param[out] allow If true legacy pairing will be used if either side doesn't support Secure Connections. 00615 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00616 */ 00617 virtual ble_error_t allowLegacyPairing(bool allow = true) { 00618 (void) allow; 00619 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00620 } 00621 00622 /** 00623 * Check if the Secure Connections feature is supported by the stack and controller. 00624 * 00625 * @param[out] enabled true if SC are supported 00626 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00627 */ 00628 virtual ble_error_t getSecureConnectionsSupport(bool *enabled) { 00629 (void) enabled; 00630 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00631 } 00632 00633 //////////////////////////////////////////////////////////////////////////// 00634 // Security settings 00635 // 00636 00637 /** 00638 * Set the IO capability of the local device. 00639 * 00640 * @param[in] iocaps type of IO capabilities available on the local device 00641 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00642 */ 00643 virtual ble_error_t setIoCapability(SecurityIOCapabilities_t iocaps) { 00644 (void) iocaps; 00645 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00646 } 00647 00648 /** 00649 * Set the passkey that is displayed on the local device instead of using 00650 * a randomly generated one 00651 * 00652 * @param[in] passkey ASCII string of 6 digits 00653 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00654 */ 00655 virtual ble_error_t setDisplayPasskey(const Passkey_t passkey) { 00656 (void) passkey; 00657 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00658 } 00659 00660 /** 00661 * Set the security mode on a connection. Useful for elevating the security mode 00662 * once certain conditions are met, e.g., a particular service is found. 00663 * 00664 * @param[in] connectionHandle Handle to identify the connection. 00665 * @param[in] securityMode Requested security mode. 00666 * 00667 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00668 */ 00669 virtual ble_error_t setLinkSecurity(ble::connection_handle_t connectionHandle, SecurityMode_t securityMode) { 00670 /* Avoid compiler warnings about unused variables. */ 00671 (void)connectionHandle; 00672 (void)securityMode; 00673 00674 return BLE_ERROR_NOT_IMPLEMENTED; 00675 } 00676 00677 /** 00678 * Set whether or not we want to send and receive keypress notifications 00679 * during passkey entry. 00680 * 00681 * @param[in] enabled if true pairing will try to enable keypress notifications 00682 * (dependent on other side supporting it) 00683 * 00684 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00685 */ 00686 virtual ble_error_t setKeypressNotification(bool enabled = true) { 00687 (void)enabled; 00688 return BLE_ERROR_NOT_IMPLEMENTED; 00689 } 00690 00691 /** 00692 * Request generation and exchange of signing keys so that packet signing can be utilised 00693 * on this connection. 00694 * @note This does not generate a signingKey event. Use getSigningKey for that. 00695 * 00696 * @param[in] connectionHandle Handle to identify the connection. 00697 * @param[in] enabled If set to true, signing keys will be exchanged 00698 * during subsequent pairing. 00699 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00700 */ 00701 virtual ble_error_t enableSigning(ble::connection_handle_t connectionHandle, bool enabled = true) { 00702 (void) enabled; 00703 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00704 } 00705 00706 /** 00707 * Give a hint to the stack that the master/slave role might change in the future. 00708 * 00709 * @param[in] enable If set to true it hints the roles are likely to swap in the future. 00710 * 00711 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00712 */ 00713 virtual ble_error_t setHintFutureRoleReversal(bool enable = true) { 00714 (void)enable; 00715 return BLE_ERROR_NOT_IMPLEMENTED; 00716 } 00717 00718 //////////////////////////////////////////////////////////////////////////// 00719 // Encryption 00720 // 00721 00722 /** 00723 * Current state of encryption on the link. 00724 * 00725 * @param[in] connectionHandle Handle to identify the connection. 00726 * @param[out] encryption 00727 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00728 */ 00729 virtual ble_error_t getLinkEncryption(ble::connection_handle_t connectionHandle, ble::link_encryption_t *encryption) { 00730 (void)connectionHandle; 00731 (void)encryption; 00732 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00733 } 00734 00735 /** 00736 * Enabled or disable encryption on the link. The result of this request will be indicated 00737 * by a call to linkEncryptionResult in the event handler when the action is completed. 00738 * 00739 * @param[in] connectionHandle Handle to identify the connection. 00740 * @param[in] encryption encryption state requested 00741 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00742 */ 00743 virtual ble_error_t setLinkEncryption(ble::connection_handle_t connectionHandle, ble::link_encryption_t encryption) { 00744 (void)connectionHandle; 00745 (void)encryption; 00746 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00747 } 00748 00749 /** 00750 * Set the requirements for encryption key size. If the peer cannot comply with the requirements 00751 * paring will fail. 00752 * 00753 * @param[in] minimumByteSize Smallest allowed encryption key size in bytes. (no smaller than 7) 00754 * @param[in] maximumByteSize Largest allowed encryption key size in bytes. (no larger than 16) 00755 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00756 */ 00757 virtual ble_error_t setEncryptionKeyRequirements(uint8_t minimumByteSize, uint8_t maximumByteSize) { 00758 (void) minimumByteSize; 00759 (void) maximumByteSize; 00760 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00761 } 00762 00763 //////////////////////////////////////////////////////////////////////////// 00764 // Authentication 00765 // 00766 00767 /** 00768 * Request that the link be authenticated (keys with MITM protection). This might trigger encryption 00769 * or pairing/re-pairing. The success will be indicated through an event indicating security level change. 00770 * 00771 * @param[in] connectionHandle Handle to identify the connection. 00772 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00773 */ 00774 virtual ble_error_t requestAuthentication(ble::connection_handle_t connectionHandle) { 00775 (void) connectionHandle; 00776 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00777 } 00778 00779 //////////////////////////////////////////////////////////////////////////// 00780 // MITM 00781 // 00782 00783 /** 00784 * Generate OOB data with the given address. If Secure Connections is supported this will 00785 * also generate Secure Connections OOB data on top of legacy pairing OOB data. This can be used 00786 * to generate such data before the connection takes place. 00787 * 00788 * In this model the OOB exchange takes place before the devices connect. Devices should establish 00789 * communication over another channel and exchange the OOB data. The address provided will be used 00790 * by the peer to associate the received data with the address of the device it will then connect 00791 * to over BLE. 00792 * 00793 * @param[in] address The local address you will use in the connection using this OOB data. This 00794 * address will be returned along with the rest of the OOB data when generation 00795 * is complete. Using an invalid address is illegal. 00796 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00797 */ 00798 virtual ble_error_t generateOOB(const ble::address_t *address) { 00799 /* Avoid compiler warnings about unused variables */ 00800 (void) address; 00801 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00802 } 00803 00804 /** 00805 * Enable OOB data usage during paring. If Secure Connections is supported enabling useOOB will 00806 * generate Secure Connections OOB data through oobGenerated() on top of legacy pairing OOB data. 00807 * 00808 * You do not have to call this function to return received OOB data. Use legacyPairingOobReceived 00809 * or oobReceived to hand it in. This will allow the stack to use it if possible. You only need to 00810 * call this function to attempt legacy OOB data exchange after pairing start and to inform 00811 * the stack OOB data does not provide MITM protection (by default it is set to provide this). 00812 * 00813 * In this model the OOB exchange takes places after the devices have connected but possibly 00814 * prior to pairing. For secure connections pairing must not be started until after the OOB 00815 * data has been sent and/or received. The address in the OOB data generated will match 00816 * the original address used to establish the connection and will be used by the peer to 00817 * identify which connection the OOB data belongs to. 00818 * 00819 * @param[in] connectionHandle Handle to identify the connection. 00820 * @param[in] useOOB If set to true, authenticate using OOB data. 00821 * @param[in] OOBProvidesMITM If set to true keys exchanged during pairing using OOB data 00822 * will provide Man-in-the-Middle protection. This indicates that 00823 * the form of exchange used by the OOB data itself provides MITM 00824 * protection. 00825 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00826 */ 00827 virtual ble_error_t setOOBDataUsage(ble::connection_handle_t connectionHandle, bool useOOB, bool OOBProvidesMITM = true) { 00828 /* Avoid compiler warnings about unused variables */ 00829 (void) connectionHandle; 00830 (void) useOOB; 00831 (void) OOBProvidesMITM; 00832 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00833 } 00834 00835 /** 00836 * Report to the stack if the passkey matches or not. Used during pairing to provide MITM protection. 00837 * 00838 * @param[in] connectionHandle Handle to identify the connection. 00839 * @param[in] confirmation True value indicates the passkey displayed matches. 00840 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00841 */ 00842 virtual ble_error_t confirmationEntered(ble::connection_handle_t connectionHandle, bool confirmation) { 00843 (void) connectionHandle; 00844 (void) confirmation; 00845 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00846 } 00847 00848 /** 00849 * Supply the stack with the user entered passkey. 00850 * 00851 * @param[in] connectionHandle Handle to identify the connection. 00852 * @param[in] passkey ASCII string of digits entered by the user. 00853 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00854 */ 00855 virtual ble_error_t passkeyEntered(ble::connection_handle_t connectionHandle, Passkey_t passkey) { 00856 (void) connectionHandle; 00857 (void) passkey; 00858 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00859 } 00860 00861 /** 00862 * Send a notification to the peer that the user pressed a key on the local device. 00863 * @note This will only be delivered if the keypress notifications have been enabled during pairing. 00864 * 00865 * @param[in] connectionHandle Handle to identify the connection. 00866 * @param[in] keypress Type of keypress event. 00867 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00868 */ 00869 virtual ble_error_t sendKeypressNotification(ble::connection_handle_t connectionHandle, Keypress_t keypress) { 00870 (void) connectionHandle; 00871 (void) keypress; 00872 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00873 } 00874 00875 /** 00876 * Supply the stack with the OOB data for legacy connections. 00877 * 00878 * @param[in] address address of the peer device this data comes from 00879 * @param[in] tk pointer to out of band data received containing the temporary key. 00880 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00881 */ 00882 virtual ble_error_t legacyPairingOobReceived(const ble::address_t *address, const ble::oob_tk_t *tk) { 00883 (void) address; 00884 (void) tk; 00885 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00886 } 00887 00888 /** 00889 * Supply the stack with the OOB data for secure connections. 00890 * 00891 * @param[in] address address of the peer device this data comes from 00892 * @param[in] random random number used to generate the confirmation 00893 * @param[in] confirm confirmation value to be use for authentication 00894 * in secure connections pairing 00895 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00896 */ 00897 virtual ble_error_t oobReceived(const ble::address_t *address, const ble::oob_lesc_value_t *random, const ble::oob_confirm_t *confirm) { 00898 (void) address; 00899 (void) random; 00900 (void) confirm; 00901 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00902 } 00903 00904 //////////////////////////////////////////////////////////////////////////// 00905 // Keys 00906 // 00907 00908 /** 00909 * Retrieves a signing key through a signingKey event. 00910 * If a signing key is not present, pairing/authentication will be attempted. 00911 * @note This will attempt to retrieve the key even if enableSigning hasn't been called prior to pairing. 00912 * 00913 * @param[in] connectionHandle Handle to identify the connection. 00914 * @param[in] authenticated Whether the signing key needs to be authenticated 00915 * (provide MITM protection). 00916 * 00917 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00918 */ 00919 virtual ble_error_t getSigningKey(ble::connection_handle_t connectionHandle, bool authenticated) { 00920 (void)connectionHandle; 00921 (void)authenticated; 00922 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00923 } 00924 00925 /* Event callback handlers. */ 00926 public: 00927 /** 00928 * Setup a callback to be invoked to notify the user application that the 00929 * SecurityManager instance is about to shutdown (possibly as a result of a call 00930 * to BLE::shutdown()). 00931 * 00932 * @note It is possible to chain together multiple onShutdown callbacks 00933 * (potentially from different modules of an application) to be notified 00934 * before the SecurityManager is shutdown. 00935 * 00936 * @note It is also possible to set up a callback into a member function of 00937 * some object. 00938 * 00939 * @note It is possible to unregister a callback using onShutdown().detach(callback) 00940 */ 00941 void onShutdown(const SecurityManagerShutdownCallback_t & callback) { 00942 shutdownCallChain.add(callback); 00943 } 00944 template <typename T> 00945 void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { 00946 shutdownCallChain.add(objPtr, memberPtr); 00947 } 00948 00949 /** 00950 * Provide access to the callchain of shutdown event callbacks. 00951 * It is possible to register callbacks using onShutdown().add(callback). 00952 * It is possible to unregister callbacks using onShutdown().detach(callback). 00953 * 00954 * @return The shutdown event callbacks chain 00955 */ 00956 SecurityManagerShutdownCallbackChain_t & onShutdown() { 00957 return shutdownCallChain; 00958 } 00959 00960 /** 00961 * Assign the event handler implementation that will be used by the stack to signal events 00962 * back to the application. 00963 * 00964 * @param[in] handler Event Handler interface implementation. 00965 */ 00966 virtual void setSecurityManagerEventHandler(EventHandler* handler) { 00967 if (handler) { 00968 eventHandler = handler; 00969 } else { 00970 eventHandler = &defaultEventHandler; 00971 } 00972 } 00973 00974 protected: 00975 SecurityManager() { 00976 eventHandler = &defaultEventHandler; 00977 } 00978 00979 virtual ~SecurityManager() { }; 00980 00981 public: 00982 /** 00983 * @deprecated use generateWhitelistFromBondTable instead 00984 * 00985 * Get a list of addresses from all peers in the bond table. 00986 * 00987 * @param[in,out] addresses 00988 * (on input) addresses.capacity contains the maximum 00989 * number of addresses to be returned. 00990 * (on output) The populated table with copies of the 00991 * addresses in the implementation's whitelist. 00992 * 00993 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00994 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00995 * application registration. 00996 */ 00997 virtual ble_error_t getAddressesFromBondTable (Gap::Whitelist_t &addresses) const { 00998 /* Avoid compiler warnings about unused variables */ 00999 (void) addresses; 01000 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 01001 } 01002 01003 /** 01004 * @deprecated 01005 * 01006 * Get the security status of a connection. 01007 * 01008 * @param[in] connectionHandle Handle to identify the connection. 01009 * @param[out] securityStatus Security status. 01010 * 01011 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 01012 */ 01013 ble_error_t getLinkSecurity (ble::connection_handle_t connectionHandle, LinkSecurityStatus_t *securityStatus) { 01014 ble::link_encryption_t encryption(ble::link_encryption_t::NOT_ENCRYPTED); 01015 ble_error_t err = getLinkEncryption(connectionHandle, &encryption); 01016 if (err) { 01017 return err; 01018 } 01019 01020 switch (encryption.value()) { 01021 case ble::link_encryption_t::NOT_ENCRYPTED: 01022 *securityStatus = NOT_ENCRYPTED; 01023 break; 01024 case ble::link_encryption_t::ENCRYPTION_IN_PROGRESS: 01025 *securityStatus = ENCRYPTION_IN_PROGRESS; 01026 break; 01027 case ble::link_encryption_t::ENCRYPTED: 01028 case ble::link_encryption_t::ENCRYPTED_WITH_MITM: 01029 case ble::link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM: 01030 *securityStatus = ENCRYPTED; 01031 break; 01032 default: 01033 // should never happen 01034 MBED_ASSERT(false); 01035 *securityStatus = NOT_ENCRYPTED; 01036 break; 01037 } 01038 01039 return BLE_ERROR_NONE; 01040 } 01041 01042 /** 01043 * @deprecated 01044 * 01045 * To indicate that a security procedure for the link has started. 01046 */ 01047 virtual void onSecuritySetupInitiated (SecuritySetupInitiatedCallback_t callback) { 01048 defaultEventHandler.securitySetupInitiatedCallback = callback; 01049 } 01050 01051 /** 01052 * @deprecated 01053 * 01054 * To indicate that the security procedure for the link has completed. 01055 */ 01056 virtual void onSecuritySetupCompleted (SecuritySetupCompletedCallback_t callback) { 01057 defaultEventHandler.securitySetupCompletedCallback = callback; 01058 } 01059 01060 /** 01061 * @deprecated 01062 * 01063 * To indicate that the link with the peer is secured. For bonded devices, 01064 * subsequent reconnections with a bonded peer will result only in this callback 01065 * when the link is secured; setup procedures will not occur (unless the 01066 * bonding information is either lost or deleted on either or both sides). 01067 */ 01068 virtual void onLinkSecured (LinkSecuredCallback_t callback) { 01069 defaultEventHandler.linkSecuredCallback = callback; 01070 } 01071 01072 /** 01073 * @deprecated 01074 * 01075 * To indicate that device context is stored persistently. 01076 */ 01077 virtual void onSecurityContextStored (HandleSpecificEvent_t callback) { 01078 defaultEventHandler.securityContextStoredCallback = callback; 01079 } 01080 01081 /** @deprecated 01082 * 01083 * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. 01084 */ 01085 virtual void onPasskeyDisplay (PasskeyDisplayCallback_t callback) { 01086 defaultEventHandler.passkeyDisplayCallback = callback; 01087 } 01088 01089 /* Entry points for the underlying stack to report events back to the user. */ 01090 public: 01091 /** @deprecated */ 01092 void processSecuritySetupInitiatedEvent (ble::connection_handle_t connectionHandle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { 01093 if (defaultEventHandler.securitySetupInitiatedCallback) { 01094 defaultEventHandler.securitySetupInitiatedCallback(connectionHandle, allowBonding, requireMITM, iocaps); 01095 } 01096 } 01097 /** @deprecated */ 01098 void processSecuritySetupCompletedEvent (ble::connection_handle_t connectionHandle, SecurityCompletionStatus_t status) { 01099 eventHandler->pairingResult(connectionHandle, status); 01100 } 01101 /** @deprecated */ 01102 void processLinkSecuredEvent (ble::connection_handle_t connectionHandle, SecurityMode_t securityMode) { 01103 if (securityMode == SECURITY_MODE_ENCRYPTION_NO_MITM) { 01104 eventHandler->linkEncryptionResult(connectionHandle, ble::link_encryption_t::ENCRYPTED); 01105 } else { 01106 eventHandler->linkEncryptionResult(connectionHandle, ble::link_encryption_t::NOT_ENCRYPTED); 01107 } 01108 } 01109 /** @deprecated */ 01110 void processSecurityContextStoredEvent (ble::connection_handle_t connectionHandle) { 01111 if (defaultEventHandler.securityContextStoredCallback) { 01112 defaultEventHandler.securityContextStoredCallback(connectionHandle); 01113 } 01114 } 01115 /** @deprecated */ 01116 void processPasskeyDisplayEvent (ble::connection_handle_t connectionHandle, const Passkey_t passkey) { 01117 eventHandler->passkeyDisplay(connectionHandle, passkey); 01118 } 01119 01120 private: 01121 /* Legacy compatibility with old callbacks (from both sides so any 01122 * combination of new and old works) */ 01123 class LegacyEventHandler : public EventHandler { 01124 public: 01125 LegacyEventHandler() : 01126 securitySetupInitiatedCallback(), 01127 securitySetupCompletedCallback(), 01128 linkSecuredCallback(), 01129 securityContextStoredCallback(), 01130 passkeyDisplayCallback() { }; 01131 01132 virtual void pairingResult(ble::connection_handle_t connectionHandle, SecurityCompletionStatus_t result) { 01133 if (securitySetupCompletedCallback) { 01134 securitySetupCompletedCallback(connectionHandle, result); 01135 } 01136 } 01137 01138 virtual void linkEncryptionResult(ble::connection_handle_t connectionHandle, ble::link_encryption_t result) { 01139 if (linkSecuredCallback) { 01140 SecurityManager::SecurityMode_t securityMode; 01141 if (result == ble::link_encryption_t::ENCRYPTED) { 01142 securityMode = SECURITY_MODE_ENCRYPTION_NO_MITM; 01143 } else if ( 01144 result == ble::link_encryption_t::ENCRYPTED_WITH_MITM || 01145 result == ble::link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM 01146 ) { 01147 securityMode = SECURITY_MODE_ENCRYPTION_WITH_MITM; 01148 } else { 01149 securityMode = SECURITY_MODE_ENCRYPTION_OPEN_LINK; 01150 } 01151 linkSecuredCallback(connectionHandle, securityMode); 01152 } 01153 }; 01154 01155 virtual void passkeyDisplay(ble::connection_handle_t connectionHandle, const SecurityManager::Passkey_t passkey) { 01156 if (passkeyDisplayCallback) { 01157 passkeyDisplayCallback(connectionHandle, passkey); 01158 } 01159 }; 01160 01161 SecurityManager::SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; 01162 SecurityManager::SecuritySetupCompletedCallback_t securitySetupCompletedCallback; 01163 SecurityManager::LinkSecuredCallback_t linkSecuredCallback; 01164 SecurityManager::HandleSpecificEvent_t securityContextStoredCallback; 01165 SecurityManager::PasskeyDisplayCallback_t passkeyDisplayCallback; 01166 }; 01167 01168 private: 01169 SecurityManagerShutdownCallbackChain_t shutdownCallChain; 01170 01171 protected: 01172 EventHandler* eventHandler; 01173 LegacyEventHandler defaultEventHandler; 01174 }; 01175 01176 #endif /*SECURITY_MANAGER_H_*/
Generated on Tue Jul 12 2022 15:15:58 by
