mirror of https://github.com/ARMmbed/mbed-os.git
792 lines
24 KiB
C++
792 lines
24 KiB
C++
/* mbed Microcontroller Library
|
|
* Copyright (c) 2017-2018 ARM Limited
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef __GENERIC_SECURITY_MANAGER_H__
|
|
#define __GENERIC_SECURITY_MANAGER_H__
|
|
|
|
#include "SecurityManager.h"
|
|
#include "PalSecurityManager.h"
|
|
#include "Callback.h"
|
|
#include "ble/pal/GapTypes.h"
|
|
#include "ble/BLETypes.h"
|
|
|
|
namespace ble {
|
|
namespace generic {
|
|
|
|
using ble::pal::address_t;
|
|
using ble::pal::advertising_peer_address_type_t;
|
|
using ble::pal::irk_t;
|
|
using ble::pal::csrk_t;
|
|
using ble::pal::ltk_t;
|
|
using ble::pal::ediv_t;
|
|
using ble::pal::rand_t;
|
|
using ble::pal::AuthenticationMask;
|
|
using ble::pal::KeyDistribution;
|
|
using ble::pairing_failure_t;
|
|
using ble::pal::PasskeyAsci;
|
|
using ble::pal::passkey_num_t;
|
|
typedef SecurityManager::SecurityIOCapabilities_t SecurityIOCapabilities_t;
|
|
|
|
/* separate structs to allow db implementation to minimise memory usage */
|
|
|
|
struct SecurityEntry_t {
|
|
connection_handle_t handle;
|
|
address_t peer_identity_address;
|
|
uint8_t encryption_key_size;
|
|
uint8_t peer_address_public:1;
|
|
uint8_t mitm:1; /**< does the key provide mitm */
|
|
uint8_t connected:1;
|
|
uint8_t authenticated:1; /**< have we authenticated during this connection */
|
|
uint8_t sign_data:1;
|
|
uint8_t encryption_requested:1;
|
|
uint8_t encrypted:1;
|
|
uint8_t oob:1;
|
|
uint8_t oob_mitm_protection:1;
|
|
uint8_t secure_connections:1;
|
|
uint8_t signing_key:1;
|
|
uint8_t encryption_key:1;
|
|
};
|
|
|
|
struct SecurityEntryKeys_t {
|
|
ltk_t ltk;
|
|
ediv_t ediv;
|
|
rand_t rand;
|
|
};
|
|
|
|
struct SecurityEntryIdentity_t {
|
|
irk_t irk;
|
|
csrk_t csrk;
|
|
};
|
|
|
|
enum DbCbAction_t {
|
|
DB_CB_ACTION_UPDATE,
|
|
DB_CB_ACTION_NO_UPDATE_REQUIRED, /* does not guarantee discarding changes if you made any */
|
|
DB_CB_ACTION_REMOVE
|
|
};
|
|
|
|
typedef mbed::Callback<DbCbAction_t(SecurityEntry_t&)> SecurityEntryDbCb_t;
|
|
typedef mbed::Callback<DbCbAction_t(SecurityEntry_t&, SecurityEntryKeys_t&)> SecurityEntryKeysDbCb_t;
|
|
typedef mbed::Callback<DbCbAction_t(connection_handle_t, csrk_t)> SecurityEntryCsrkDbCb_t;
|
|
typedef mbed::Callback<DbCbAction_t(SecurityEntry_t&, SecurityEntryIdentity_t&)> SecurityEntryIdentityDbCb_t;
|
|
typedef mbed::Callback<DbCbAction_t(Gap::Whitelist_t&)> WhitelistDbCb_t;
|
|
|
|
class GenericSecurityManagerEventHandler;
|
|
|
|
/**
|
|
* SecurityDB holds the state for active connections and bonded devices.
|
|
* Keys can be stored in NVM and are returned via callbacks.
|
|
* SecurityDB is responsible for serialising any requests and keeping
|
|
* the store in a consistent state.
|
|
* Active connections state must be returned immediately.
|
|
*/
|
|
class SecurityDb {
|
|
public:
|
|
SecurityDb() { };
|
|
virtual ~SecurityDb() { };
|
|
|
|
/**
|
|
* Return immediately security entry containing the state
|
|
* information for active connection.
|
|
* @param[in] handle valid connection handle
|
|
* @return pointer to security entry, NULL if handle was invalid
|
|
*/
|
|
virtual SecurityEntry_t* get_entry(connection_handle_t connection);
|
|
|
|
|
|
virtual void get_entry_csrk(
|
|
SecurityEntryCsrkDbCb_t cb,
|
|
connection_handle_t connection
|
|
);
|
|
virtual void get_entry_keys(
|
|
SecurityEntryKeysDbCb_t cb,
|
|
const ediv_t ediv,
|
|
const rand_t rand
|
|
);
|
|
virtual void get_entry_identityt(
|
|
SecurityEntryIdentityDbCb_t cb,
|
|
address_t &identity_address
|
|
);
|
|
|
|
virtual void update_entry(
|
|
connection_handle_t connection,
|
|
bool address_is_public,
|
|
const address_t &peer_address,
|
|
const ediv_t ediv,
|
|
const rand_t rand,
|
|
const ltk_t ltk,
|
|
const irk_t irk,
|
|
const csrk_t csrk
|
|
);
|
|
virtual void update_entry_ltk(
|
|
connection_handle_t connection,
|
|
const ltk_t ltk
|
|
);
|
|
virtual void update_entry_ediv_rand(
|
|
connection_handle_t connection,
|
|
const ediv_t ediv,
|
|
const rand_t rand
|
|
);
|
|
virtual void update_entry_irk(
|
|
connection_handle_t connection,
|
|
const irk_t irk
|
|
);
|
|
virtual void update_entry_bdaddr(
|
|
connection_handle_t connection,
|
|
bool address_is_public,
|
|
const address_t &peer_address
|
|
);
|
|
virtual void update_entry_csrk(
|
|
connection_handle_t connection,
|
|
const csrk_t csrk
|
|
);
|
|
|
|
virtual void remove_entry(SecurityEntry_t&);
|
|
virtual void clear_entries();
|
|
|
|
virtual void get_whitelist(WhitelistDbCb_t cb);
|
|
|
|
virtual void update_whitelist(Gap::Whitelist_t& whitelist);
|
|
virtual void add_whitelist_entry(const address_t &address);
|
|
|
|
virtual void remove_whitelist_entry(const address_t &address);
|
|
virtual void clear_whitelist();
|
|
|
|
virtual void restore();
|
|
virtual void sync();
|
|
virtual void set_restore(bool reload);
|
|
};
|
|
|
|
class GenericSecurityManager : public SecurityManager,
|
|
public ble::pal::SecurityManagerEventHandler {
|
|
public:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// SM lifecycle management
|
|
//
|
|
virtual ble_error_t init(
|
|
bool bondable = true,
|
|
bool mitm = true,
|
|
SecurityIOCapabilities_t iocaps = IO_CAPS_NONE,
|
|
const Passkey_t passkey = NULL,
|
|
bool signing = true
|
|
) {
|
|
db.restore();
|
|
pal.set_io_capability((io_capability_t::type) iocaps);
|
|
pal.set_display_passkey(PasskeyAsci::to_num(passkey));
|
|
legacy_pairing_allowed = true;
|
|
|
|
bool secure_connections;
|
|
pal.get_secure_connections_support(secure_connections);
|
|
|
|
authentication.set_bondable(bondable);
|
|
authentication.set_mitm(mitm);
|
|
authentication.set_secure_connections(secure_connections);
|
|
authentication.set_keypress_notification(true);
|
|
|
|
key_distribution.set_signing(signing);
|
|
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
virtual ble_error_t reset(void) {
|
|
db.sync();
|
|
SecurityManager::reset();
|
|
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
virtual ble_error_t preserveBondingStateOnReset(bool enabled) {
|
|
db.set_restore(enabled);
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// List management
|
|
//
|
|
|
|
virtual ble_error_t purgeAllBondingState(void) {
|
|
db.clear_entries();
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Pairing
|
|
//
|
|
|
|
virtual ble_error_t requestPairing(connection_handle_t connection) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (entry) {
|
|
return pal.send_pairing_request(
|
|
connection,
|
|
entry->oob,
|
|
authentication,
|
|
key_distribution,
|
|
key_distribution
|
|
);
|
|
} else {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
virtual ble_error_t acceptPairingRequest(connection_handle_t connection) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (entry) {
|
|
return pal.send_pairing_response(
|
|
connection,
|
|
entry->oob,
|
|
authentication,
|
|
key_distribution,
|
|
key_distribution
|
|
);
|
|
} else {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
virtual ble_error_t canceltPairingRequest(connection_handle_t connection) {
|
|
return pal.cancel_pairing(connection, pairing_failure_t::UNSPECIFIED_REASON);
|
|
}
|
|
|
|
virtual ble_error_t setPairingRequestAuthorisation(bool required = true) {
|
|
pairing_authorisation_required = required;
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Feature support
|
|
//
|
|
|
|
virtual ble_error_t allowLegacyPairing(bool allow = true) {
|
|
legacy_pairing_allowed = allow;
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
virtual ble_error_t getSecureConnectionsSupport(bool *enabled) {
|
|
return pal.get_secure_connections_support(*enabled);
|
|
}
|
|
|
|
virtual ble_error_t enableSigning(connection_handle_t connection, bool enabled = true) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (!entry) {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
if (!entry->signing_key && enabled) {
|
|
KeyDistribution distribution = key_distribution;
|
|
distribution.set_signing(enabled);
|
|
return pal.send_pairing_request(
|
|
connection,
|
|
entry->oob,
|
|
authentication,
|
|
distribution,
|
|
distribution
|
|
);
|
|
}
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Security settings
|
|
//
|
|
|
|
virtual ble_error_t setIoCapability(SecurityIOCapabilities_t iocaps) {
|
|
return pal.set_io_capability((io_capability_t::type) iocaps);
|
|
}
|
|
|
|
virtual ble_error_t setDisplayPasskey(const Passkey_t passkey) {
|
|
return pal.set_display_passkey(PasskeyAsci::to_num(passkey));
|
|
}
|
|
|
|
virtual ble_error_t setAuthenticationTimeout(
|
|
connection_handle_t connection,
|
|
uint32_t timeout_in_ms
|
|
) {
|
|
return pal.set_authentication_timeout(connection, timeout_in_ms / 10);
|
|
}
|
|
|
|
virtual ble_error_t getAuthenticationTimeout(
|
|
connection_handle_t connection,
|
|
uint32_t *timeout_in_ms
|
|
) {
|
|
uint16_t timeout_in_10ms;
|
|
ble_error_t status = pal.get_authentication_timeout(connection, timeout_in_10ms);
|
|
*timeout_in_ms = 10 * timeout_in_10ms;
|
|
return status;
|
|
}
|
|
|
|
virtual ble_error_t setLinkSecurity(
|
|
connection_handle_t connection,
|
|
SecurityMode_t securityMode
|
|
) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (!entry) {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
entry->encryption_requested = true;
|
|
pal.enable_encryption(connection);
|
|
}
|
|
|
|
virtual ble_error_t setKeypressNotification(bool enabled = true) {
|
|
authentication.set_keypress_notification(enabled);
|
|
return BLE_ERROR_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Encryption
|
|
//
|
|
|
|
/**
|
|
* Get the security status of a connection.
|
|
*
|
|
* @param[in] connection Handle to identify the connection.
|
|
* @param[out] securityStatusP Security status.
|
|
*
|
|
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
|
*/
|
|
virtual ble_error_t getLinkEncryption(
|
|
connection_handle_t connection,
|
|
link_encryption_t *securityStatus
|
|
) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (entry) {
|
|
if (entry->encrypted) {
|
|
if (entry->mitm) {
|
|
*securityStatus = link_encryption_t::ENCRYPTED_WITH_MITM;
|
|
} else {
|
|
*securityStatus = link_encryption_t::ENCRYPTED;
|
|
}
|
|
} else if (entry->encryption_requested) {
|
|
*securityStatus = link_encryption_t::ENCRYPTION_IN_PROGRESS;
|
|
} else {
|
|
*securityStatus = link_encryption_t::NOT_ENCRYPTED;
|
|
}
|
|
return BLE_ERROR_NONE;
|
|
} else {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
virtual ble_error_t getEncryptionKeySize(
|
|
connection_handle_t connection,
|
|
uint8_t *size
|
|
) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (entry) {
|
|
*size = entry->encryption_key_size;
|
|
return BLE_ERROR_NONE;
|
|
} else {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
virtual ble_error_t setEncryptionKeyRequirements(
|
|
uint8_t minimumByteSize,
|
|
uint8_t maximumByteSize
|
|
) {
|
|
return pal.set_encryption_key_requirements(minimumByteSize, maximumByteSize);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Privacy
|
|
//
|
|
|
|
virtual ble_error_t setPrivateAddressTimeout(uint16_t timeout_in_seconds) {
|
|
return pal.set_private_address_timeout(timeout_in_seconds);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Keys
|
|
//
|
|
|
|
virtual ble_error_t getSigningKey(connection_handle_t connection, bool authenticated) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (!entry) {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
if (entry->signing_key && (entry->mitm || !authenticated)) {
|
|
/* we have a key that is either authenticated or we don't care if it is
|
|
* so retrieve it from the db now */
|
|
db.get_entry_csrk(
|
|
mbed::callback(this, &GenericSecurityManager::return_csrk_cb),
|
|
connection
|
|
);
|
|
return BLE_ERROR_NONE;
|
|
} else {
|
|
/* we don't have the right key so we need to get it first
|
|
* keys exchange will create the signingKey event */
|
|
if (authenticated) {
|
|
return requestAuthentication(connection);
|
|
} else {
|
|
return requestPairing(connection);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the requested LTK to the PAL. Called by the security db.
|
|
*
|
|
* @param entry security entry returned by the database.
|
|
* @param entryKeys security entry containing keys.
|
|
*
|
|
* @return no action instruction to the db since this only reads the keys.
|
|
*/
|
|
DbCbAction_t set_ltk_cb(
|
|
SecurityEntry_t& entry,
|
|
SecurityEntryKeys_t& entryKeys
|
|
) {
|
|
pal.set_ltk(entry.handle, entryKeys.ltk);
|
|
return DB_CB_ACTION_NO_UPDATE_REQUIRED;
|
|
}
|
|
|
|
DbCbAction_t return_csrk_cb(
|
|
connection_handle_t connection,
|
|
csrk_t csrk
|
|
) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->signingKey(connection, csrk, db.get_entry(connection)->mitm);
|
|
}
|
|
return DB_CB_ACTION_NO_UPDATE_REQUIRED;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Authentication
|
|
//
|
|
|
|
virtual ble_error_t requestAuthentication(connection_handle_t connection) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (entry) {
|
|
if (entry->mitm) {
|
|
if (entry->authenticated) {
|
|
return BLE_ERROR_NONE;
|
|
} else {
|
|
return pal.enable_encryption(connection);
|
|
}
|
|
} else {
|
|
/* don't change the default value of authentication */
|
|
AuthenticationMask connection_authentication = authentication;
|
|
connection_authentication.set_mitm(true);
|
|
return pal.send_pairing_request(
|
|
connection,
|
|
entry->oob,
|
|
authentication,
|
|
key_distribution,
|
|
key_distribution
|
|
);
|
|
}
|
|
} else {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// MITM
|
|
//
|
|
|
|
virtual ble_error_t setOOBDataUsage(
|
|
connection_handle_t connection,
|
|
bool useOOB,
|
|
bool OOBProvidesMITM = true
|
|
) {
|
|
SecurityEntry_t *entry = db.get_entry(connection);
|
|
if (entry) {
|
|
entry->oob = useOOB;
|
|
entry->oob_mitm_protection = OOBProvidesMITM;
|
|
return BLE_ERROR_NONE;
|
|
} else {
|
|
return BLE_ERROR_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
virtual ble_error_t confirmationEntered(
|
|
connection_handle_t connection,
|
|
bool confirmation
|
|
) {
|
|
return pal.confirmation_entered(connection, confirmation);
|
|
}
|
|
|
|
virtual ble_error_t passkeyEntered(
|
|
connection_handle_t connection,
|
|
Passkey_t passkey
|
|
) {
|
|
return pal.passkey_request_reply(
|
|
connection,
|
|
PasskeyAsci::to_num(passkey)
|
|
);
|
|
}
|
|
|
|
virtual ble_error_t sendKeypressNotification(
|
|
connection_handle_t connection,
|
|
Keypress_t keypress
|
|
) {
|
|
return pal.send_keypress_notification(connection, keypress);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Event handler
|
|
//
|
|
|
|
virtual void setSecurityManagerEventHandler(
|
|
::SecurityManager::SecurityManagerEventHandler* handler
|
|
) {
|
|
SecurityManager::setSecurityManagerEventHandler(handler);
|
|
if (handler) {
|
|
_app_event_handler = handler;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
GenericSecurityManager(ble::pal::SecurityManager& palImpl)
|
|
: pal(palImpl),
|
|
pairing_authorisation_required(false),
|
|
legacy_pairing_allowed(true),
|
|
authentication(0),
|
|
key_distribution(KeyDistribution::KEY_DISTRIBUTION_ALL) {
|
|
_app_event_handler = &defaultEventHandler;
|
|
pal.set_event_handler(this);
|
|
}
|
|
|
|
private:
|
|
ble::pal::SecurityManager& pal;
|
|
SecurityDb db;
|
|
|
|
bool pairing_authorisation_required;
|
|
bool legacy_pairing_allowed;
|
|
|
|
AuthenticationMask authentication;
|
|
KeyDistribution key_distribution;
|
|
|
|
/* implements ble::pal::SecurityManagerEventHandler */
|
|
public:
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Pairing
|
|
//
|
|
|
|
virtual void on_pairing_request(
|
|
connection_handle_t connection,
|
|
bool use_oob,
|
|
AuthenticationMask authentication,
|
|
KeyDistribution initiator_dist,
|
|
KeyDistribution responder_dist
|
|
) {
|
|
if (_app_event_handler && pairing_authorisation_required) {
|
|
_app_event_handler->acceptPairingRequest(connection);
|
|
}
|
|
}
|
|
|
|
virtual void on_pairing_error(
|
|
connection_handle_t connection,
|
|
pairing_failure_t error
|
|
) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->pairingResult(
|
|
connection,
|
|
(SecurityManager::SecurityCompletionStatus_t)(error.value() | 0x80)
|
|
);
|
|
}
|
|
}
|
|
|
|
virtual void on_pairing_timed_out(connection_handle_t connection) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->pairingResult(
|
|
connection,
|
|
SecurityManager::SEC_STATUS_TIMEOUT
|
|
);
|
|
}
|
|
}
|
|
|
|
virtual void on_pairing_completed(connection_handle_t connection) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->pairingResult(
|
|
connection,
|
|
SecurityManager::SEC_STATUS_SUCCESS
|
|
);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Security
|
|
//
|
|
|
|
virtual void on_valid_mic_timeout(connection_handle_t connection) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->validMicTimeout(connection);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Encryption
|
|
//
|
|
|
|
virtual void on_link_encryption_result(
|
|
connection_handle_t connection,
|
|
link_encryption_t result
|
|
) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->linkEncryptionResult(connection, result);
|
|
}
|
|
}
|
|
|
|
virtual void on_link_encryption_request_timed_out(
|
|
connection_handle_t connection
|
|
) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->linkEncryptionResult(
|
|
connection,
|
|
link_encryption_t::NOT_ENCRYPTED
|
|
);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// MITM
|
|
//
|
|
|
|
virtual void on_passkey_display(
|
|
connection_handle_t connection,
|
|
const passkey_num_t passkey
|
|
) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->passkeyDisplay(connection, PasskeyAsci(passkey).asci);
|
|
}
|
|
}
|
|
|
|
virtual void on_keypress_notification(
|
|
connection_handle_t connection,
|
|
SecurityManager::Keypress_t keypress
|
|
) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->keypressNotification(connection, keypress);
|
|
}
|
|
}
|
|
|
|
virtual void on_passkey_request(connection_handle_t connection) {
|
|
|
|
if (_app_event_handler) {
|
|
_app_event_handler->passkeyRequest(connection);
|
|
}
|
|
}
|
|
|
|
virtual void on_confirmation_request(connection_handle_t connection) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->confirmationRequest(connection);
|
|
}
|
|
}
|
|
|
|
virtual void on_legacy_pairing_oob_request(connection_handle_t connection) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->legacyPairingOobRequest(connection);
|
|
}
|
|
}
|
|
|
|
virtual void on_oob_request(connection_handle_t connection) {
|
|
if (_app_event_handler) {
|
|
_app_event_handler->oobRequest(connection);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Keys
|
|
//
|
|
|
|
virtual void on_keys_distributed(
|
|
connection_handle_t connection,
|
|
advertising_peer_address_type_t peer_address_type,
|
|
const address_t &peer_identity_address,
|
|
const ediv_t ediv,
|
|
const rand_t rand,
|
|
const ltk_t ltk,
|
|
const irk_t irk,
|
|
const csrk_t csrk
|
|
) {
|
|
db.update_entry(
|
|
connection,
|
|
(peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS),
|
|
peer_identity_address,
|
|
ediv,
|
|
rand,
|
|
ltk,
|
|
irk,
|
|
csrk
|
|
);
|
|
|
|
if (_app_event_handler) {
|
|
_app_event_handler->signingKey(connection, csrk, db.get_entry(connection)->mitm);
|
|
}
|
|
}
|
|
|
|
virtual void on_keys_distributed_ltk(
|
|
connection_handle_t connection,
|
|
const ltk_t ltk
|
|
) {
|
|
db.update_entry_ltk(connection, ltk);
|
|
}
|
|
|
|
virtual void on_keys_distributed_ediv_rand(
|
|
connection_handle_t connection,
|
|
const ediv_t ediv,
|
|
const rand_t rand
|
|
) {
|
|
db.update_entry_ediv_rand(connection, ediv, rand);
|
|
}
|
|
|
|
virtual void on_keys_distributed_irk(
|
|
connection_handle_t connection,
|
|
const irk_t irk
|
|
) {
|
|
db.update_entry_irk(connection, irk);
|
|
}
|
|
|
|
virtual void on_keys_distributed_bdaddr(
|
|
connection_handle_t connection,
|
|
advertising_peer_address_type_t peer_address_type,
|
|
const address_t &peer_identity_address
|
|
) {
|
|
db.update_entry_bdaddr(
|
|
connection,
|
|
(peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS),
|
|
peer_identity_address
|
|
);
|
|
}
|
|
|
|
virtual void on_keys_distributed_csrk(
|
|
connection_handle_t connection,
|
|
const csrk_t csrk
|
|
) {
|
|
db.update_entry_csrk(connection, csrk);
|
|
|
|
if (_app_event_handler) {
|
|
_app_event_handler->signingKey(connection, csrk, db.get_entry(connection)->mitm);
|
|
}
|
|
}
|
|
|
|
virtual void on_ltk_request(
|
|
connection_handle_t connection,
|
|
const ediv_t ediv,
|
|
const rand_t rand
|
|
) {
|
|
db.get_entry_keys(mbed::callback(this, &GenericSecurityManager::set_ltk_cb), ediv, rand);
|
|
}
|
|
|
|
private:
|
|
/* handler is always a valid pointer */
|
|
::SecurityManager::SecurityManagerEventHandler *_app_event_handler;
|
|
};
|
|
|
|
|
|
} /* namespace generic */
|
|
} /* namespace ble */
|
|
|
|
#endif /*__GENERIC_SECURITY_MANAGER_H__*/
|