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 #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 12:45:45 by
