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