Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SecurityManager.h Source File

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_*/