mirror of https://github.com/ARMmbed/mbed-os.git
commit
268655a028
|
@ -435,7 +435,7 @@ public:
|
|||
* @param[in] connectionHandle Handle to identify the connection.
|
||||
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
||||
*/
|
||||
virtual ble_error_t canceltPairingRequest(connection_handle_t connectionHandle) {
|
||||
virtual ble_error_t cancelPairingRequest(connection_handle_t connectionHandle) {
|
||||
(void) connectionHandle;
|
||||
return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ public:
|
|||
* @param[in] required If set to true, pairingRequest in the event handler will
|
||||
* will be called and will require an action from the application
|
||||
* to continue with pairing by calling acceptPairingRequest
|
||||
* or canceltPairingRequest if the user wishes to reject it.
|
||||
* or cancelPairingRequest if the user wishes to reject it.
|
||||
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
||||
*/
|
||||
virtual ble_error_t setPairingRequestAuthorisation(bool required = true) {
|
||||
|
|
|
@ -41,7 +41,7 @@ class GenericSecurityManager : public SecurityManager,
|
|||
public pal::SecurityManagerEventHandler,
|
||||
public pal::ConnectionEventHandler {
|
||||
public:
|
||||
typedef ble::pal::SecurityEntry_t SecurityEntry_t;
|
||||
typedef ble::pal::SecurityDistributionFlags_t SecurityDistributionFlags_t;
|
||||
typedef ble::pal::SecurityEntryKeys_t SecurityEntryKeys_t;
|
||||
|
||||
/* implements SecurityManager */
|
||||
|
@ -86,7 +86,7 @@ public:
|
|||
connection_handle_t connection
|
||||
);
|
||||
|
||||
virtual ble_error_t canceltPairingRequest(
|
||||
virtual ble_error_t cancelPairingRequest(
|
||||
connection_handle_t connection
|
||||
);
|
||||
|
||||
|
@ -302,7 +302,7 @@ private:
|
|||
* @param[in] entryKeys security entry containing keys.
|
||||
*/
|
||||
void enable_encryption_cb(
|
||||
const SecurityEntry_t* entry,
|
||||
pal::SecurityDb::entry_handle_t entry,
|
||||
const SecurityEntryKeys_t* entryKeys
|
||||
);
|
||||
|
||||
|
@ -313,7 +313,7 @@ private:
|
|||
* @param[in] entryKeys security entry containing keys.
|
||||
*/
|
||||
void set_ltk_cb(
|
||||
const SecurityEntry_t* entry,
|
||||
pal::SecurityDb::entry_handle_t entry,
|
||||
const SecurityEntryKeys_t* entryKeys
|
||||
);
|
||||
|
||||
|
@ -324,7 +324,7 @@ private:
|
|||
* @param[in] entryKeys security entry containing keys.
|
||||
*/
|
||||
void return_csrk_cb(
|
||||
connection_handle_t connection,
|
||||
pal::SecurityDb::entry_handle_t connection,
|
||||
const csrk_t *csrk
|
||||
);
|
||||
|
||||
|
@ -431,6 +431,31 @@ private:
|
|||
);
|
||||
|
||||
private:
|
||||
struct ControlBlock_t : public pal::SecurityDistributionFlags_t {
|
||||
ControlBlock_t();
|
||||
|
||||
connection_handle_t connection;
|
||||
pal::SecurityDb::entry_handle_t db_entry;
|
||||
|
||||
address_t local_address; /**< address used for connection, possibly different from identity */
|
||||
|
||||
uint8_t connected:1;
|
||||
uint8_t authenticated:1; /**< have we turned encryption on during this connection */
|
||||
uint8_t is_master:1;
|
||||
|
||||
uint8_t encryption_requested:1;
|
||||
uint8_t encryption_failed:1;
|
||||
uint8_t encrypted:1;
|
||||
uint8_t signing_requested:1;
|
||||
|
||||
uint8_t mitm_requested:1;
|
||||
uint8_t mitm_performed:1; /**< keys exchange will have MITM protection */
|
||||
|
||||
uint8_t attempt_oob:1;
|
||||
uint8_t oob_mitm_protection:1;
|
||||
uint8_t oob_present:1;
|
||||
};
|
||||
|
||||
pal::SecurityManager &_pal;
|
||||
pal::SecurityDb &_db;
|
||||
pal::ConnectionEventMonitor &_connection_monitor;
|
||||
|
@ -443,6 +468,14 @@ private:
|
|||
bool _master_sends_keys;
|
||||
bool _public_keys_generated;
|
||||
|
||||
/** There is always only one OOB data set stored at a time (for now) */
|
||||
address_t _peer_sc_oob_address;
|
||||
oob_rand_t _peer_sc_oob_random;
|
||||
oob_confirm_t _peer_sc_oob_confirm;
|
||||
oob_rand_t _local_sc_oob_random;
|
||||
|
||||
static const size_t MAX_CONTROL_BLOCKS = 5;
|
||||
ControlBlock_t _control_blocks[MAX_CONTROL_BLOCKS];
|
||||
|
||||
/* implements ble::pal::SecurityManagerEventHandler */
|
||||
public:
|
||||
|
@ -642,6 +675,18 @@ public:
|
|||
);
|
||||
|
||||
/* end implements ble::pal::SecurityManagerEventHandler */
|
||||
|
||||
/* list management */
|
||||
|
||||
ControlBlock_t* acquire_control_block(connection_handle_t connection);
|
||||
|
||||
ControlBlock_t* get_control_block(connection_handle_t connection);
|
||||
|
||||
ControlBlock_t* get_control_block(const address_t &peer_address);
|
||||
|
||||
ControlBlock_t* get_control_block(pal::SecurityDb::entry_handle_t db_entry);
|
||||
|
||||
void release_control_block(ControlBlock_t* entry);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,17 +17,9 @@
|
|||
#ifndef MBED_BLE_CONNECTION_EVENT_MONITOR
|
||||
#define MBED_BLE_CONNECTION_EVENT_MONITOR
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ble/BLE.h"
|
||||
#include "ble/BLEProtocol.h"
|
||||
#include "ble/Gap.h"
|
||||
#include "ble/pal/PalGap.h"
|
||||
#include "ble/pal/GapEvents.h"
|
||||
#include "ble/pal/GapTypes.h"
|
||||
#include "ble/BLETypes.h"
|
||||
#include "ble/pal/GenericAccessService.h"
|
||||
#include "ble/pal/EventQueue.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
|
|
@ -14,11 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef PAL_MEMORY_SECURITY_MANAGER_DB_H__
|
||||
#define PAL_MEMORY_SECURITY_MANAGER_DB_H__
|
||||
#ifndef PAL_MEMORY_SECURITY_MANAGER_entries_H__
|
||||
#define PAL_MEMORY_SECURITY_MANAGER_entries_H__
|
||||
|
||||
#include "SecurityDB.h"
|
||||
#include "Gap.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
@ -27,42 +26,57 @@ namespace pal {
|
|||
* TODO: make thread safe */
|
||||
class MemorySecurityDb : public SecurityDb {
|
||||
private:
|
||||
struct db_store_t {
|
||||
db_store_t() { };
|
||||
SecurityEntry_t entry;
|
||||
enum state_t {
|
||||
ENTRY_FREE,
|
||||
ENTRY_RESERVED,
|
||||
ENTRY_WRITTEN
|
||||
};
|
||||
|
||||
struct entry_t {
|
||||
entry_t() : state(ENTRY_FREE) { };
|
||||
SecurityDistributionFlags_t flags;
|
||||
SecurityEntryKeys_t peer_keys;
|
||||
SecurityEntryKeys_t local_keys;
|
||||
SecurityEntryIdentity_t peer_identity;
|
||||
csrk_t csrk;
|
||||
state_t state;
|
||||
};
|
||||
static const size_t MAX_ENTRIES = 5;
|
||||
|
||||
static entry_t* as_entry(entry_handle_t entry_handle)
|
||||
{
|
||||
return reinterpret_cast<entry_t*>(entry_handle);
|
||||
}
|
||||
|
||||
public:
|
||||
MemorySecurityDb() { };
|
||||
virtual ~MemorySecurityDb() { };
|
||||
|
||||
virtual SecurityEntry_t* get_entry(
|
||||
connection_handle_t connection
|
||||
virtual const SecurityDistributionFlags_t* get_distribution_flags(
|
||||
entry_handle_t entry_handle
|
||||
) {
|
||||
SecurityEntry_t *entry = NULL;
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
entry = &store->entry;
|
||||
entry_t* entry = as_entry(entry_handle);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
return entry;
|
||||
|
||||
return &entry->flags;
|
||||
}
|
||||
|
||||
virtual SecurityEntry_t* get_entry(
|
||||
const address_t &peer_address
|
||||
/**
|
||||
* Set the distribution flags of the DB entry
|
||||
*/
|
||||
virtual void set_distribution_flags(
|
||||
entry_handle_t entry_handle,
|
||||
const SecurityDistributionFlags_t& flags
|
||||
) {
|
||||
SecurityEntry_t *entry = NULL;
|
||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (!_db[i].entry.connected) {
|
||||
continue;
|
||||
} else if (peer_address == _db[i].entry.peer_address) {
|
||||
entry = &_db[i].entry;
|
||||
}
|
||||
entry_t* entry = as_entry(entry_handle);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
return entry;
|
||||
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->flags = flags;
|
||||
}
|
||||
|
||||
/* local keys */
|
||||
|
@ -70,64 +84,63 @@ public:
|
|||
/* get */
|
||||
virtual void get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
SecurityEntry_t *entry = NULL;
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
entry = &store->entry;
|
||||
entry_t* entry = as_entry(entry_handle);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* validate we have the correct key */
|
||||
if (ediv == store->local_keys.ediv
|
||||
&& rand == store->local_keys.rand) {
|
||||
cb(entry, &store->local_keys);
|
||||
if (ediv == entry->local_keys.ediv && rand == entry->local_keys.rand) {
|
||||
cb(entry_handle, &entry->local_keys);
|
||||
} else {
|
||||
cb(entry, NULL);
|
||||
cb(entry_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
connection_handle_t connection
|
||||
entry_handle_t entry_handle
|
||||
) {
|
||||
SecurityEntry_t *entry = NULL;
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
entry = &store->entry;
|
||||
entry_t* entry = as_entry(entry_handle);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* validate we have the correct key */
|
||||
if (entry->secure_connections_paired) {
|
||||
cb(entry, &store->local_keys);
|
||||
if (entry->flags.secure_connections_paired) {
|
||||
cb(entry_handle, &entry->local_keys);
|
||||
} else {
|
||||
cb(entry, NULL);
|
||||
cb(entry_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set */
|
||||
virtual void set_entry_local_ltk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const ltk_t <k
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
store->local_keys.ltk = ltk;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->local_keys.ltk = ltk;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_entry_local_ediv_rand(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
store->local_keys.ediv = ediv;
|
||||
store->local_keys.rand = rand;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->local_keys.ediv = ediv;
|
||||
entry->local_keys.rand = rand;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,86 +149,85 @@ public:
|
|||
/* get */
|
||||
virtual void get_entry_peer_csrk(
|
||||
SecurityEntryCsrkDbCb_t cb,
|
||||
connection_handle_t connection
|
||||
entry_handle_t entry_handle
|
||||
) {
|
||||
SecurityEntry_t *entry = NULL;
|
||||
csrk_t csrk;
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
entry = &store->entry;
|
||||
csrk = store->csrk;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
csrk = entry->csrk;
|
||||
}
|
||||
cb(entry->handle, &csrk);
|
||||
cb(entry_handle, &csrk);
|
||||
}
|
||||
|
||||
virtual void get_entry_peer_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
connection_handle_t connection
|
||||
entry_handle_t entry_handle
|
||||
) {
|
||||
SecurityEntry_t *entry = NULL;
|
||||
SecurityEntryKeys_t *key = NULL;
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
entry = &store->entry;
|
||||
key = &store->peer_keys;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
key = &entry->peer_keys;
|
||||
}
|
||||
cb(entry, key);
|
||||
cb(entry_handle, key);
|
||||
}
|
||||
|
||||
/* set */
|
||||
|
||||
virtual void set_entry_peer_ltk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const ltk_t <k
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
store->peer_keys.ltk = ltk;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->peer_keys.ltk = ltk;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_entry_peer_ediv_rand(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
store->peer_keys.ediv = ediv;
|
||||
store->peer_keys.rand = rand;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->peer_keys.ediv = ediv;
|
||||
entry->peer_keys.rand = rand;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_entry_peer_irk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const irk_t &irk
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
size_t index = store - _db;
|
||||
_identities[index].irk = irk;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->peer_identity.irk = irk;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_entry_peer_bdaddr(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
bool address_is_public,
|
||||
const address_t &peer_address
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
size_t index = store - _db;
|
||||
_identities[index].identity_address = peer_address;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->peer_identity.identity_address = peer_address;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_entry_peer_csrk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t entry_handle,
|
||||
const csrk_t &csrk
|
||||
) {
|
||||
db_store_t *store = get_store(connection);
|
||||
if (store) {
|
||||
store->csrk = csrk;
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry) {
|
||||
entry->state = ENTRY_WRITTEN;
|
||||
entry->csrk = csrk;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,96 +259,62 @@ public:
|
|||
_public_key_y = public_key_y;
|
||||
}
|
||||
|
||||
/* oob data */
|
||||
|
||||
/** There is always only one OOB data set stored at a time */
|
||||
|
||||
virtual const address_t& get_peer_sc_oob_address() {
|
||||
return _peer_sc_oob_address;
|
||||
}
|
||||
|
||||
virtual const oob_rand_t& get_peer_sc_oob_random() {
|
||||
return _peer_sc_oob_random;
|
||||
}
|
||||
|
||||
virtual const oob_confirm_t& get_peer_sc_oob_confirm() {
|
||||
return _peer_sc_oob_confirm;
|
||||
}
|
||||
|
||||
virtual void get_sc_oob_data(
|
||||
address_t &peer_address,
|
||||
oob_rand_t &peer_random,
|
||||
oob_confirm_t &peer_confirm,
|
||||
oob_rand_t &local_random
|
||||
) {
|
||||
peer_address = _peer_sc_oob_address;
|
||||
peer_random = _peer_sc_oob_random;
|
||||
peer_confirm = _peer_sc_oob_confirm;
|
||||
local_random = _local_sc_oob_random;
|
||||
}
|
||||
|
||||
virtual const oob_rand_t& get_local_sc_oob_random() {
|
||||
return _local_sc_oob_random;
|
||||
}
|
||||
|
||||
virtual void set_peer_sc_oob_data(
|
||||
const address_t &address,
|
||||
const oob_rand_t &random,
|
||||
const oob_confirm_t &confirm
|
||||
) {
|
||||
_peer_sc_oob_address = address;
|
||||
_peer_sc_oob_random = random;
|
||||
_peer_sc_oob_confirm = confirm;
|
||||
}
|
||||
|
||||
virtual void set_local_sc_oob_random(
|
||||
const oob_rand_t &random
|
||||
) {
|
||||
_local_sc_oob_random = random;
|
||||
}
|
||||
|
||||
/* list management */
|
||||
|
||||
virtual SecurityEntry_t* connect_entry(
|
||||
connection_handle_t connection,
|
||||
virtual entry_handle_t open_entry(
|
||||
BLEProtocol::AddressType_t peer_address_type,
|
||||
const address_t &peer_address,
|
||||
const address_t &local_address
|
||||
const address_t &peer_address
|
||||
) {
|
||||
const bool peer_address_public =
|
||||
(peer_address_type == BLEProtocol::AddressType::PUBLIC);
|
||||
|
||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (_db[i].entry.connected) {
|
||||
if (_entries[i].state == ENTRY_FREE) {
|
||||
continue;
|
||||
} else if (peer_address == _identities[i].identity_address
|
||||
&& _db[i].entry.peer_address_is_public == peer_address_public) {
|
||||
return &_db[i].entry;
|
||||
} else if (peer_address == _entries[i].peer_identity.identity_address
|
||||
&& _entries[i].flags.peer_address_is_public == peer_address_public) {
|
||||
return &_entries[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* if we din't find one grab the first disconnected slot*/
|
||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (!_db[i].entry.connected) {
|
||||
_db[i] = db_store_t();
|
||||
_identities[i] = SecurityEntryIdentity_t();
|
||||
_db[i].entry.peer_address = peer_address;
|
||||
_db[i].entry.local_address = local_address;
|
||||
_db[i].entry.peer_address_is_public = peer_address_public;
|
||||
return &_db[i].entry;
|
||||
if (_entries[i].state == ENTRY_FREE) {
|
||||
_entries[i] = entry_t();
|
||||
_entries[i].flags.peer_address = peer_address;
|
||||
_entries[i].flags.peer_address_is_public = peer_address_public;
|
||||
_entries[i].state = ENTRY_RESERVED;
|
||||
return &_entries[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual void disconnect_entry(connection_handle_t connection) { }
|
||||
virtual void close_entry(entry_handle_t entry_handle)
|
||||
{
|
||||
entry_t *entry = as_entry(entry_handle);
|
||||
if (entry && entry->state == ENTRY_RESERVED) {
|
||||
entry->state = ENTRY_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void remove_entry(address_t peer_identity_address) { }
|
||||
virtual void remove_entry(const address_t peer_identity_address)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (_entries[i].state == ENTRY_FREE) {
|
||||
continue;
|
||||
} else if (peer_identity_address == _entries[i].peer_identity.identity_address) {
|
||||
_entries[i] = entry_t();
|
||||
_entries[i].state = ENTRY_FREE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void clear_entries() {
|
||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||
_db[i] = db_store_t();
|
||||
_entries[i] = entry_t();
|
||||
}
|
||||
_local_identity = SecurityEntryIdentity_t();
|
||||
_local_csrk = csrk_t();
|
||||
|
@ -349,7 +327,7 @@ public:
|
|||
|
||||
virtual void generate_whitelist_from_bond_table(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist) {
|
||||
for (size_t i = 0; i < MAX_ENTRIES && i < whitelist->capacity; i++) {
|
||||
if (_db[i].entry.peer_address_is_public) {
|
||||
if (_entries[i].flags.peer_address_is_public) {
|
||||
whitelist->addresses[i].type = BLEProtocol::AddressType::PUBLIC;
|
||||
} else {
|
||||
whitelist->addresses[i].type = BLEProtocol::AddressType::RANDOM_STATIC;
|
||||
|
@ -357,7 +335,7 @@ public:
|
|||
|
||||
memcpy(
|
||||
whitelist->addresses[i].address,
|
||||
_identities[i].identity_address.data(),
|
||||
_entries[i].peer_identity.identity_address.data(),
|
||||
sizeof(BLEProtocol::AddressBytes_t)
|
||||
);
|
||||
}
|
||||
|
@ -365,8 +343,6 @@ public:
|
|||
cb(whitelist);
|
||||
}
|
||||
|
||||
virtual void update_whitelist(::Gap::Whitelist_t &whitelist) { }
|
||||
|
||||
virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) { };
|
||||
|
||||
virtual void add_whitelist_entry(const address_t &address) { }
|
||||
|
@ -384,32 +360,14 @@ public:
|
|||
virtual void set_restore(bool reload) { }
|
||||
|
||||
private:
|
||||
|
||||
virtual db_store_t* get_store(connection_handle_t connection) {
|
||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (!_db[i].entry.connected) {
|
||||
continue;
|
||||
} else if (connection == _db[i].entry.handle) {
|
||||
return &_db[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
db_store_t _db[MAX_ENTRIES];
|
||||
SecurityEntryIdentity_t _identities[MAX_ENTRIES];
|
||||
entry_t _entries[MAX_ENTRIES];
|
||||
SecurityEntryIdentity_t _local_identity;
|
||||
csrk_t _local_csrk;
|
||||
public_key_t _public_key_x;
|
||||
public_key_t _public_key_y;
|
||||
|
||||
address_t _peer_sc_oob_address;
|
||||
oob_rand_t _peer_sc_oob_random;
|
||||
oob_confirm_t _peer_sc_oob_confirm;
|
||||
oob_rand_t _local_sc_oob_random;
|
||||
};
|
||||
|
||||
} /* namespace pal */
|
||||
} /* namespace ble */
|
||||
|
||||
#endif /*PAL_MEMORY_SECURITY_MANAGER_DB_H__*/
|
||||
#endif /*PAL_MEMORY_SECURITY_MANAGER_entries_H__*/
|
||||
|
|
|
@ -26,13 +26,10 @@
|
|||
namespace ble {
|
||||
namespace pal {
|
||||
|
||||
/* separate structs for keys to allow db implementation
|
||||
* to minimise memory usage, only holding live connection
|
||||
* state in memory */
|
||||
|
||||
struct SecurityEntry_t {
|
||||
SecurityEntry_t()
|
||||
: handle(0),
|
||||
struct SecurityDistributionFlags_t {
|
||||
SecurityDistributionFlags_t() :
|
||||
peer_address(),
|
||||
encryption_key_size(0),
|
||||
peer_address_is_public(false),
|
||||
local_address_is_public(false),
|
||||
|
@ -40,44 +37,9 @@ struct SecurityEntry_t {
|
|||
csrk_mitm_protected(false),
|
||||
ltk_stored(false),
|
||||
ltk_mitm_protected(false),
|
||||
secure_connections_paired(false),
|
||||
connected(false),
|
||||
authenticated(false),
|
||||
is_master(false),
|
||||
encryption_requested(false),
|
||||
encryption_failed(false),
|
||||
encrypted(false),
|
||||
signing_requested(false),
|
||||
mitm_requested(false),
|
||||
mitm_performed(false),
|
||||
attempt_oob(false),
|
||||
oob_mitm_protection(false),
|
||||
oob_present(false) { }
|
||||
|
||||
/**
|
||||
* Reset state of the connection when disconnected.
|
||||
*/
|
||||
void reset() {
|
||||
local_address = address_t();
|
||||
|
||||
connected = false;
|
||||
authenticated = false;
|
||||
is_master = false;
|
||||
|
||||
encryption_requested = false;
|
||||
encryption_failed = false;
|
||||
encrypted = false;
|
||||
signing_requested = false;
|
||||
|
||||
mitm_requested = false;
|
||||
mitm_performed = false;
|
||||
|
||||
attempt_oob = false;
|
||||
oob_mitm_protection = false;
|
||||
oob_present = false;
|
||||
secure_connections_paired(false) {
|
||||
}
|
||||
|
||||
connection_handle_t handle;
|
||||
address_t peer_address;
|
||||
|
||||
uint8_t encryption_key_size;
|
||||
|
@ -89,26 +51,6 @@ struct SecurityEntry_t {
|
|||
uint8_t ltk_stored:1;
|
||||
uint8_t ltk_mitm_protected:1;
|
||||
uint8_t secure_connections_paired:1;
|
||||
|
||||
/* do not store in NVM */
|
||||
|
||||
address_t local_address; /**< address used for connection, possibly different from identity */
|
||||
|
||||
uint8_t connected:1;
|
||||
uint8_t authenticated:1; /**< have we turned encryption on during this connection */
|
||||
uint8_t is_master:1;
|
||||
|
||||
uint8_t encryption_requested:1;
|
||||
uint8_t encryption_failed:1;
|
||||
uint8_t encrypted:1;
|
||||
uint8_t signing_requested:1;
|
||||
|
||||
uint8_t mitm_requested:1;
|
||||
uint8_t mitm_performed:1; /**< keys exchange will have MITM protection */
|
||||
|
||||
uint8_t attempt_oob:1;
|
||||
uint8_t oob_mitm_protection:1;
|
||||
uint8_t oob_present:1;
|
||||
};
|
||||
|
||||
struct SecurityEntryKeys_t {
|
||||
|
@ -122,12 +64,6 @@ struct SecurityEntryIdentity_t {
|
|||
irk_t irk;
|
||||
};
|
||||
|
||||
/* callbacks for asynchronous data retrieval from the security db */
|
||||
|
||||
typedef mbed::Callback<void(const SecurityEntry_t*, const SecurityEntryKeys_t*)> SecurityEntryKeysDbCb_t;
|
||||
typedef mbed::Callback<void(connection_handle_t, const csrk_t*)> SecurityEntryCsrkDbCb_t;
|
||||
typedef mbed::Callback<void(::Gap::Whitelist_t*)> WhitelistDbCb_t;
|
||||
|
||||
/**
|
||||
* SecurityDB holds the state for active connections and bonded devices.
|
||||
* Keys can be stored in NVM and are returned via callbacks.
|
||||
|
@ -137,6 +73,20 @@ typedef mbed::Callback<void(::Gap::Whitelist_t*)> WhitelistDbCb_t;
|
|||
*/
|
||||
class SecurityDb {
|
||||
public:
|
||||
/**
|
||||
* Opaque type representing an handle to a database entry.
|
||||
*/
|
||||
typedef void* entry_handle_t;
|
||||
|
||||
/* callbacks for asynchronous data retrieval from the security db */
|
||||
|
||||
typedef mbed::Callback<void(entry_handle_t, const SecurityEntryKeys_t*)>
|
||||
SecurityEntryKeysDbCb_t;
|
||||
typedef mbed::Callback<void(entry_handle_t, const csrk_t*)>
|
||||
SecurityEntryCsrkDbCb_t;
|
||||
typedef mbed::Callback<void(::Gap::Whitelist_t*)>
|
||||
WhitelistDbCb_t;
|
||||
|
||||
SecurityDb() { };
|
||||
virtual ~SecurityDb() { };
|
||||
|
||||
|
@ -147,19 +97,16 @@ public:
|
|||
* @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 const SecurityDistributionFlags_t* get_distribution_flags(
|
||||
entry_handle_t db_entry
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Return immediately security entry containing the state
|
||||
* information for active connection.
|
||||
*
|
||||
* @param[in] peer_address peer address in the entry being requested
|
||||
* @return pointer to security entry, NULL if no entry was fined
|
||||
* Set the distribution flags of the DB entry
|
||||
*/
|
||||
virtual SecurityEntry_t* get_entry(
|
||||
const address_t &peer_address
|
||||
virtual void set_distribution_flags(
|
||||
entry_handle_t db_entry,
|
||||
const SecurityDistributionFlags_t& flags
|
||||
) = 0;
|
||||
|
||||
/* local keys */
|
||||
|
@ -174,7 +121,7 @@ public:
|
|||
*/
|
||||
virtual void get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) = 0;
|
||||
|
@ -187,7 +134,7 @@ public:
|
|||
*/
|
||||
virtual void get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
connection_handle_t connection
|
||||
entry_handle_t db_entry
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
|
@ -198,7 +145,7 @@ public:
|
|||
* be used when link is encrypted
|
||||
*/
|
||||
virtual void set_entry_local_ltk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const ltk_t <k
|
||||
) = 0;
|
||||
|
||||
|
@ -210,7 +157,7 @@ public:
|
|||
* @param[in] rand new RAND value
|
||||
*/
|
||||
virtual void set_entry_local_ediv_rand(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) = 0;
|
||||
|
@ -226,7 +173,7 @@ public:
|
|||
*/
|
||||
virtual void get_entry_peer_csrk(
|
||||
SecurityEntryCsrkDbCb_t cb,
|
||||
connection_handle_t connection
|
||||
entry_handle_t db_entry
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
|
@ -238,7 +185,7 @@ public:
|
|||
*/
|
||||
virtual void get_entry_peer_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
connection_handle_t connection
|
||||
entry_handle_t db_entry
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
|
@ -249,7 +196,7 @@ public:
|
|||
* be used when link is encrypted
|
||||
*/
|
||||
virtual void set_entry_peer_ltk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const ltk_t <k
|
||||
) = 0;
|
||||
|
||||
|
@ -261,7 +208,7 @@ public:
|
|||
* @param[in] rand new RAND value
|
||||
*/
|
||||
virtual void set_entry_peer_ediv_rand(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) = 0;
|
||||
|
@ -273,7 +220,7 @@ public:
|
|||
* @param[in] irk new IRK value
|
||||
*/
|
||||
virtual void set_entry_peer_irk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const irk_t &irk
|
||||
) = 0;
|
||||
|
||||
|
@ -285,7 +232,7 @@ public:
|
|||
* @param[in] peer_address the new address
|
||||
*/
|
||||
virtual void set_entry_peer_bdaddr(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
bool address_is_public,
|
||||
const address_t &peer_address
|
||||
) = 0;
|
||||
|
@ -297,7 +244,7 @@ public:
|
|||
* @param[in] csrk new CSRK value
|
||||
*/
|
||||
virtual void set_entry_peer_csrk(
|
||||
connection_handle_t connection,
|
||||
entry_handle_t db_entry,
|
||||
const csrk_t &csrk
|
||||
) = 0;
|
||||
|
||||
|
@ -315,9 +262,7 @@ public:
|
|||
*
|
||||
* @param[in] csrk new CSRK value
|
||||
*/
|
||||
virtual void set_local_csrk(
|
||||
const csrk_t &csrk
|
||||
) = 0;
|
||||
virtual void set_local_csrk(const csrk_t &csrk) = 0;
|
||||
|
||||
/* public keys */
|
||||
|
||||
|
@ -346,118 +291,38 @@ public:
|
|||
const public_key_t &public_key_y
|
||||
) = 0;
|
||||
|
||||
/* oob data */
|
||||
|
||||
/** There is always only one OOB data set stored at a time */
|
||||
|
||||
/**
|
||||
* Return peer address the OOB data belongs to.
|
||||
*
|
||||
* @return peer address
|
||||
*/
|
||||
virtual const address_t& get_peer_sc_oob_address() = 0;
|
||||
|
||||
/**
|
||||
* Return random number from the peer received in OOB data.
|
||||
*
|
||||
* @return random number the peer chose
|
||||
*/
|
||||
virtual const oob_rand_t& get_peer_sc_oob_random() = 0;
|
||||
|
||||
/**
|
||||
* Return confirm number from the peer received in OOB data.
|
||||
*
|
||||
* @return confirm value calculated by peer based
|
||||
* on the random number, its public key and address
|
||||
*/
|
||||
virtual const oob_confirm_t& get_peer_sc_oob_confirm() = 0;
|
||||
|
||||
/**
|
||||
* Return OOB data in a single transaction.
|
||||
*
|
||||
* @param[out] peer_address peer address OOB data belongs to
|
||||
* @param[out] peer_random random number the peer chose
|
||||
* @param[out] peer_confirm confirm value calculated by peer based
|
||||
* on the random number, its public key and address
|
||||
* @param[out] local_random random number chosen by the local device
|
||||
*/
|
||||
virtual void get_sc_oob_data(
|
||||
address_t &peer_address,
|
||||
oob_rand_t &peer_random,
|
||||
oob_confirm_t &peer_confirm,
|
||||
oob_rand_t &local_random
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Return random number used by the local device to calculate
|
||||
* the confirm value sent the peer in OOB data.
|
||||
*
|
||||
* @return random number chosen by local device
|
||||
*/
|
||||
virtual const oob_rand_t& get_local_sc_oob_random() = 0;
|
||||
|
||||
/**
|
||||
* Store the OOB data received from the peer.
|
||||
*
|
||||
* @param address peer address OOB data belongs to
|
||||
* @param random random number the peer chose
|
||||
* @param confirm confirm value calculated by peer based
|
||||
* on the random number, its public key and address
|
||||
*/
|
||||
virtual void set_peer_sc_oob_data(
|
||||
const address_t &address,
|
||||
const oob_rand_t &random,
|
||||
const oob_confirm_t &confirm
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Set random number used for OOB data calculation on the local device.
|
||||
*
|
||||
* @param random random number chosen by the local device
|
||||
*/
|
||||
virtual void set_local_sc_oob_random(
|
||||
const oob_rand_t &random
|
||||
) = 0;
|
||||
|
||||
/* list management */
|
||||
|
||||
/**
|
||||
* Create a new entry or retrieve existing stored entry
|
||||
* and put it in the live connections store to be retrieved
|
||||
* synchronously through connection handle.
|
||||
* Open a database entry.
|
||||
*
|
||||
* While this entry is opened; it can be queried and modified with the help
|
||||
* of the database setter and getter functions.
|
||||
*
|
||||
* @param[in] connection this will be the index for live entries.
|
||||
* @param[in] peer_address_type type of address
|
||||
* @param[in] peer_address this address will be used to locate existing entry.
|
||||
* @param[in] peer_address this address will be used to locate an existing
|
||||
* entry.
|
||||
*
|
||||
* @return pointer to entry newly created or located existing entry.
|
||||
* @return An handle to the entry.
|
||||
*/
|
||||
virtual SecurityEntry_t* connect_entry(
|
||||
connection_handle_t connection,
|
||||
virtual entry_handle_t open_entry(
|
||||
BLEProtocol::AddressType_t peer_address_type,
|
||||
const address_t &peer_address,
|
||||
const address_t &local_address
|
||||
const address_t &peer_address
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Create a new entry or retrieve existing stored entry
|
||||
* and put it in the live connections store to be retrieved
|
||||
* synchronously through connection handle.
|
||||
* Close a connection entry.
|
||||
*
|
||||
* @param[in] connection this handle will be freed up from the security db
|
||||
* @param[in] entry this handle will be freed up from the security db.
|
||||
*/
|
||||
virtual void disconnect_entry(
|
||||
connection_handle_t connection
|
||||
) = 0;
|
||||
virtual void close_entry(entry_handle_t db_entry) = 0;
|
||||
|
||||
/**
|
||||
* Remove entry for this peer from NVM.
|
||||
*
|
||||
* @param[in] peer_identity_address peer address that no longer needs NVM storage.
|
||||
*/
|
||||
virtual void remove_entry(
|
||||
const address_t peer_identity_address
|
||||
) = 0;
|
||||
virtual void remove_entry(const address_t peer_identity_address) = 0;
|
||||
|
||||
/**
|
||||
* Remove all entries from the security DB.
|
||||
|
@ -495,27 +360,21 @@ public:
|
|||
*
|
||||
* @param[in] whitelist
|
||||
*/
|
||||
virtual void set_whitelist(
|
||||
const ::Gap::Whitelist_t &whitelist
|
||||
) = 0;
|
||||
virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) = 0;
|
||||
|
||||
/**
|
||||
* Add a new entry to the whitelist in the NVM.
|
||||
*
|
||||
* @param[in] address new whitelist entry
|
||||
*/
|
||||
virtual void add_whitelist_entry(
|
||||
const address_t &address
|
||||
) = 0;
|
||||
virtual void add_whitelist_entry(const address_t &address) = 0;
|
||||
|
||||
/**
|
||||
* Remove whitelist entry from NVM.
|
||||
*
|
||||
* @param[in] address entry to be removed
|
||||
*/
|
||||
virtual void remove_whitelist_entry(
|
||||
const address_t &address
|
||||
) = 0;
|
||||
virtual void remove_whitelist_entry(const address_t &address) = 0;
|
||||
|
||||
/**
|
||||
*Remove all whitelist entries stored in the NVM.
|
||||
|
|
|
@ -100,8 +100,8 @@ ble_error_t GenericSecurityManager::generateWhitelistFromBondTable(Gap::Whitelis
|
|||
//
|
||||
|
||||
ble_error_t GenericSecurityManager::requestPairing(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
@ -113,15 +113,15 @@ ble_error_t GenericSecurityManager::requestPairing(connection_handle_t connectio
|
|||
update_oob_presence(connection);
|
||||
|
||||
AuthenticationMask link_authentication(_default_authentication);
|
||||
link_authentication.set_mitm(entry->mitm_requested);
|
||||
link_authentication.set_mitm(cb->mitm_requested);
|
||||
|
||||
KeyDistribution link_key_distribution(_default_key_distribution);
|
||||
link_key_distribution.set_signing(entry->signing_requested);
|
||||
link_key_distribution.set_signing(cb->signing_requested);
|
||||
link_key_distribution.set_encryption(_master_sends_keys);
|
||||
|
||||
return _pal.send_pairing_request(
|
||||
connection,
|
||||
entry->oob_present,
|
||||
cb->oob_present,
|
||||
link_authentication,
|
||||
link_key_distribution,
|
||||
link_key_distribution
|
||||
|
@ -129,29 +129,29 @@ ble_error_t GenericSecurityManager::requestPairing(connection_handle_t connectio
|
|||
}
|
||||
|
||||
ble_error_t GenericSecurityManager::acceptPairingRequest(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
update_oob_presence(connection);
|
||||
|
||||
AuthenticationMask link_authentication(_default_authentication);
|
||||
link_authentication.set_mitm(entry->mitm_requested);
|
||||
link_authentication.set_mitm(cb->mitm_requested);
|
||||
|
||||
KeyDistribution link_key_distribution(_default_key_distribution);
|
||||
link_key_distribution.set_signing(entry->signing_requested);
|
||||
link_key_distribution.set_signing(cb->signing_requested);
|
||||
|
||||
return _pal.send_pairing_response(
|
||||
connection,
|
||||
entry->oob_present,
|
||||
cb->oob_present,
|
||||
link_authentication,
|
||||
link_key_distribution,
|
||||
link_key_distribution
|
||||
);
|
||||
}
|
||||
|
||||
ble_error_t GenericSecurityManager::canceltPairingRequest(connection_handle_t connection) {
|
||||
ble_error_t GenericSecurityManager::cancelPairingRequest(connection_handle_t connection) {
|
||||
return _pal.cancel_pairing(connection, pairing_failure_t::UNSPECIFIED_REASON);
|
||||
}
|
||||
|
||||
|
@ -206,12 +206,12 @@ ble_error_t GenericSecurityManager::setLinkSecurity(
|
|||
connection_handle_t connection,
|
||||
SecurityMode_t securityMode
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (entry->encryption_requested) {
|
||||
if (cb->encryption_requested) {
|
||||
return BLE_ERROR_OPERATION_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
|
@ -245,19 +245,19 @@ ble_error_t GenericSecurityManager::enableSigning(
|
|||
connection_handle_t connection,
|
||||
bool enabled
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
entry->signing_requested = enabled;
|
||||
cb->signing_requested = enabled;
|
||||
|
||||
if (entry->encrypted) {
|
||||
if (cb->encrypted) {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
if (!entry->csrk_stored && entry->signing_requested) {
|
||||
if (!cb->csrk_stored && cb->signing_requested) {
|
||||
init_signing();
|
||||
if (entry->is_master) {
|
||||
if (cb->is_master) {
|
||||
return requestPairing(connection);
|
||||
} else {
|
||||
return slave_security_request(connection);
|
||||
|
@ -281,18 +281,18 @@ ble_error_t GenericSecurityManager::getLinkEncryption(
|
|||
link_encryption_t *encryption
|
||||
) {
|
||||
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (entry->encrypted) {
|
||||
if (entry->ltk_mitm_protected || entry->mitm_performed) {
|
||||
if (cb->encrypted) {
|
||||
if (cb->ltk_mitm_protected || cb->mitm_performed) {
|
||||
*encryption = link_encryption_t::ENCRYPTED_WITH_MITM;
|
||||
} else {
|
||||
*encryption = link_encryption_t::ENCRYPTED;
|
||||
}
|
||||
} else if (entry->encryption_requested) {
|
||||
} else if (cb->encryption_requested) {
|
||||
*encryption = link_encryption_t::ENCRYPTION_IN_PROGRESS;
|
||||
} else {
|
||||
*encryption = link_encryption_t::NOT_ENCRYPTED;
|
||||
|
@ -305,8 +305,8 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
|
|||
connection_handle_t connection,
|
||||
link_encryption_t encryption
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
|
|||
|
||||
if (encryption == link_encryption_t::NOT_ENCRYPTED) {
|
||||
|
||||
if (entry->encrypted) {
|
||||
if (cb->encrypted) {
|
||||
return _pal.disable_encryption(connection);
|
||||
}
|
||||
|
||||
|
@ -334,16 +334,16 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
|
|||
if (current_encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
entry->encryption_requested = true;
|
||||
cb->encryption_requested = true;
|
||||
return enable_encryption(connection);
|
||||
|
||||
} else if (encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
||||
|
||||
if (entry->ltk_mitm_protected && !entry->encrypted) {
|
||||
entry->encryption_requested = true;
|
||||
if (cb->ltk_mitm_protected && !cb->encrypted) {
|
||||
cb->encryption_requested = true;
|
||||
return enable_encryption(connection);
|
||||
} else {
|
||||
entry->encryption_requested = true;
|
||||
cb->encryption_requested = true;
|
||||
return requestAuthentication(connection);
|
||||
}
|
||||
|
||||
|
@ -358,9 +358,9 @@ ble_error_t GenericSecurityManager::getEncryptionKeySize(
|
|||
connection_handle_t connection,
|
||||
uint8_t *size
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (entry) {
|
||||
*size = entry->encryption_key_size;
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (cb) {
|
||||
*size = cb->encryption_key_size;
|
||||
return BLE_ERROR_NONE;
|
||||
} else {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
@ -379,17 +379,17 @@ ble_error_t GenericSecurityManager::setEncryptionKeyRequirements(
|
|||
//
|
||||
|
||||
ble_error_t GenericSecurityManager::getSigningKey(connection_handle_t connection, bool authenticated) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (entry->csrk_stored && (entry->csrk_mitm_protected || !authenticated)) {
|
||||
if (cb->csrk_stored && (cb->csrk_mitm_protected || !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_peer_csrk(
|
||||
mbed::callback(this, &GenericSecurityManager::return_csrk_cb),
|
||||
connection
|
||||
cb->db_entry
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
|
@ -398,7 +398,7 @@ ble_error_t GenericSecurityManager::getSigningKey(connection_handle_t connection
|
|||
* keys exchange will create the signingKey event */
|
||||
if (authenticated) {
|
||||
return requestAuthentication(connection);
|
||||
} else if (entry->is_master) {
|
||||
} else if (cb->is_master) {
|
||||
return requestPairing(connection);
|
||||
} else {
|
||||
return slave_security_request(connection);
|
||||
|
@ -419,21 +419,21 @@ ble_error_t GenericSecurityManager::setPrivateAddressTimeout(uint16_t timeout_in
|
|||
//
|
||||
|
||||
ble_error_t GenericSecurityManager::requestAuthentication(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (entry->ltk_mitm_protected) {
|
||||
if (entry->authenticated) {
|
||||
if (cb->ltk_mitm_protected) {
|
||||
if (cb->authenticated) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else {
|
||||
entry->encryption_requested = true;
|
||||
cb->encryption_requested = true;
|
||||
return enable_encryption(connection);
|
||||
}
|
||||
} else {
|
||||
entry->mitm_requested = true;
|
||||
if (entry->is_master) {
|
||||
cb->mitm_requested = true;
|
||||
if (cb->is_master) {
|
||||
return requestPairing(connection);
|
||||
} else {
|
||||
return slave_security_request(connection);
|
||||
|
@ -450,13 +450,13 @@ ble_error_t GenericSecurityManager::setOOBDataUsage(
|
|||
bool useOOB,
|
||||
bool OOBProvidesMITM
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
entry->attempt_oob = useOOB;
|
||||
entry->oob_mitm_protection = OOBProvidesMITM;
|
||||
cb->attempt_oob = useOOB;
|
||||
cb->oob_mitm_protection = OOBProvidesMITM;
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
if (_public_keys_generated) {
|
||||
|
@ -496,12 +496,12 @@ ble_error_t GenericSecurityManager::legacyPairingOobReceived(
|
|||
const oob_tk_t *tk
|
||||
) {
|
||||
if (address && tk) {
|
||||
SecurityEntry_t *entry = _db.get_entry(*address);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(*address);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return _pal.legacy_pairing_oob_data_request_reply(entry->handle, *tk);
|
||||
return _pal.legacy_pairing_oob_data_request_reply(cb->connection, *tk);
|
||||
}
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
@ -512,12 +512,9 @@ ble_error_t GenericSecurityManager::oobReceived(
|
|||
const oob_confirm_t *confirm
|
||||
) {
|
||||
if (address && random && confirm) {
|
||||
_db.set_peer_sc_oob_data(
|
||||
*address,
|
||||
*random,
|
||||
*confirm
|
||||
);
|
||||
|
||||
_peer_sc_oob_address = *address;
|
||||
_peer_sc_oob_random = *random;
|
||||
_peer_sc_oob_confirm = *confirm;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
@ -564,25 +561,25 @@ ble_error_t GenericSecurityManager::get_random_data(uint8_t *buffer, size_t size
|
|||
}
|
||||
|
||||
ble_error_t GenericSecurityManager::slave_security_request(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
AuthenticationMask link_authentication(_default_authentication);
|
||||
link_authentication.set_mitm(entry->mitm_requested);
|
||||
link_authentication.set_mitm(cb->mitm_requested);
|
||||
return _pal.slave_security_request(connection, link_authentication);
|
||||
}
|
||||
|
||||
ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
if (entry->is_master) {
|
||||
if (entry->ltk_stored) {
|
||||
if (cb->is_master) {
|
||||
if (cb->ltk_stored) {
|
||||
_db.get_entry_peer_keys(
|
||||
mbed::callback(this, &GenericSecurityManager::enable_encryption_cb),
|
||||
connection
|
||||
cb->db_entry
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
} else {
|
||||
|
@ -594,44 +591,48 @@ ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connec
|
|||
}
|
||||
|
||||
void GenericSecurityManager::enable_encryption_cb(
|
||||
const SecurityEntry_t* entry,
|
||||
pal::SecurityDb::entry_handle_t db_entry,
|
||||
const SecurityEntryKeys_t* entryKeys
|
||||
) {
|
||||
if (entry && entryKeys) {
|
||||
if (entry->secure_connections_paired) {
|
||||
_pal.enable_encryption(entry->handle, entryKeys->ltk);
|
||||
ControlBlock_t *cb = get_control_block(db_entry);
|
||||
|
||||
if (cb && entryKeys) {
|
||||
if (cb->secure_connections_paired) {
|
||||
_pal.enable_encryption(cb->connection, entryKeys->ltk);
|
||||
} else {
|
||||
_pal.enable_encryption(entry->handle, entryKeys->ltk, entryKeys->rand, entryKeys->ediv);
|
||||
_pal.enable_encryption(cb->connection, entryKeys->ltk, entryKeys->rand, entryKeys->ediv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenericSecurityManager::set_ltk_cb(
|
||||
const SecurityEntry_t* entry,
|
||||
pal::SecurityDb::entry_handle_t db_entry,
|
||||
const SecurityEntryKeys_t* entryKeys
|
||||
) {
|
||||
if (entry) {
|
||||
ControlBlock_t *cb = get_control_block(db_entry);
|
||||
|
||||
if (cb) {
|
||||
if (entryKeys) {
|
||||
_pal.set_ltk(entry->handle, entryKeys->ltk);
|
||||
_pal.set_ltk(cb->connection, entryKeys->ltk);
|
||||
} else {
|
||||
_pal.set_ltk_not_found(entry->handle);
|
||||
_pal.set_ltk_not_found(cb->connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenericSecurityManager::return_csrk_cb(
|
||||
connection_handle_t connection,
|
||||
pal::SecurityDb::entry_handle_t db_entry,
|
||||
const csrk_t *csrk
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(db_entry);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
eventHandler->signingKey(
|
||||
connection,
|
||||
cb->connection,
|
||||
csrk,
|
||||
entry->csrk_mitm_protected
|
||||
cb->csrk_mitm_protected
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -642,8 +643,8 @@ void GenericSecurityManager::generate_secure_connections_oob(
|
|||
oob_confirm_t confirm;
|
||||
oob_rand_t random;
|
||||
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -660,31 +661,31 @@ void GenericSecurityManager::generate_secure_connections_oob(
|
|||
);
|
||||
|
||||
eventHandler->oobGenerated(
|
||||
&entry->local_address,
|
||||
&cb->local_address,
|
||||
&random,
|
||||
&confirm
|
||||
);
|
||||
|
||||
_db.set_local_sc_oob_random(random);
|
||||
_local_sc_oob_random = random;
|
||||
}
|
||||
#endif
|
||||
|
||||
void GenericSecurityManager::update_oob_presence(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* only update the oob state if we support secure connections,
|
||||
* otherwise follow the user set preference for providing legacy
|
||||
* pairing oob data */
|
||||
entry->oob_present = entry->attempt_oob;
|
||||
cb->oob_present = cb->attempt_oob;
|
||||
|
||||
if (_default_authentication.get_secure_connections()) {
|
||||
entry->oob_present = false;
|
||||
cb->oob_present = false;
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
if (entry->peer_address == _db.get_peer_sc_oob_address()) {
|
||||
entry->oob_present = true;
|
||||
if (cb->peer_address == _peer_sc_oob_address) {
|
||||
cb->oob_present = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -721,9 +722,9 @@ bool GenericSecurityManager::crypto_toolbox_f4(
|
|||
#endif
|
||||
|
||||
void GenericSecurityManager::set_mitm_performed(connection_handle_t connection, bool enable) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (entry) {
|
||||
entry->mitm_performed = true;
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (cb) {
|
||||
cb->mitm_performed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,33 +737,41 @@ void GenericSecurityManager::on_connected(
|
|||
const BLEProtocol::AddressBytes_t local_address,
|
||||
const Gap::ConnectionParams_t *connection_params
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.connect_entry(
|
||||
connection,
|
||||
peer_address_type,
|
||||
address_t(peer_address),
|
||||
address_t(local_address)
|
||||
);
|
||||
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = acquire_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry->reset();
|
||||
// setup the control block
|
||||
cb->peer_address = peer_address;
|
||||
cb->local_address = local_address;
|
||||
cb->peer_address_is_public =
|
||||
(peer_address_type == BLEProtocol::AddressType::PUBLIC);
|
||||
cb->is_master = (role == Gap::CENTRAL);
|
||||
|
||||
entry->is_master = (role == Gap::CENTRAL);
|
||||
entry->handle = connection;
|
||||
entry->connected = true;
|
||||
// get the associated db handle and the distribution flags if any
|
||||
cb->db_entry = _db.open_entry(peer_address_type, peer_address);
|
||||
|
||||
const pal::SecurityDistributionFlags_t* dist_flags =
|
||||
_db.get_distribution_flags(cb->db_entry);
|
||||
|
||||
if (dist_flags) {
|
||||
*static_cast<pal::SecurityDistributionFlags_t*>(cb) = *dist_flags;
|
||||
}
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_disconnected(
|
||||
connection_handle_t connection,
|
||||
Gap::DisconnectionReason_t reason
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
entry->connected = false;
|
||||
|
||||
_db.close_entry(cb->db_entry);
|
||||
release_control_block(cb);
|
||||
|
||||
_db.sync();
|
||||
}
|
||||
|
||||
|
@ -781,7 +790,7 @@ void GenericSecurityManager::on_pairing_request(
|
|||
) {
|
||||
/* cancel pairing if secure connection paring is not possible */
|
||||
if (!_legacy_pairing_allowed && !authentication.get_secure_connections()) {
|
||||
canceltPairingRequest(connection);
|
||||
cancelPairingRequest(connection);
|
||||
}
|
||||
|
||||
set_mitm_performed(connection, false);
|
||||
|
@ -804,8 +813,8 @@ void GenericSecurityManager::on_pairing_error(
|
|||
|
||||
/* if this pairing was triggered by a failed encryption attempt
|
||||
* inform the application of the encryption failure */
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (entry && entry->encryption_requested && entry->encryption_failed) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (cb && cb->encryption_requested && cb->encryption_failed) {
|
||||
eventHandler->linkEncryptionResult(
|
||||
connection,
|
||||
link_encryption_t::NOT_ENCRYPTED
|
||||
|
@ -823,18 +832,21 @@ void GenericSecurityManager::on_pairing_timed_out(connection_handle_t connection
|
|||
}
|
||||
|
||||
void GenericSecurityManager::on_pairing_completed(connection_handle_t connection) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (entry) {
|
||||
if (entry->encryption_requested) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (cb) {
|
||||
if (cb->encryption_requested) {
|
||||
enable_encryption(connection);
|
||||
}
|
||||
|
||||
/* sc doesn't need to exchange ltk */
|
||||
if (entry->secure_connections_paired) {
|
||||
entry->ltk_mitm_protected = entry->mitm_performed;
|
||||
if (cb->secure_connections_paired) {
|
||||
cb->ltk_mitm_protected = cb->mitm_performed;
|
||||
}
|
||||
}
|
||||
|
||||
// set the distribution flags in the db
|
||||
_db.set_distribution_flags(cb->db_entry, *cb);
|
||||
|
||||
eventHandler->pairingResult(
|
||||
connection,
|
||||
SecurityManager::SEC_STATUS_SUCCESS
|
||||
|
@ -853,20 +865,20 @@ void GenericSecurityManager::on_slave_security_request(
|
|||
connection_handle_t connection,
|
||||
AuthenticationMask authentication
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (authentication.get_secure_connections()
|
||||
&& _default_authentication.get_secure_connections()
|
||||
&& !entry->secure_connections_paired) {
|
||||
&& !cb->secure_connections_paired) {
|
||||
requestPairing(connection);
|
||||
}
|
||||
|
||||
if (authentication.get_mitm()
|
||||
&& !entry->ltk_mitm_protected) {
|
||||
entry->mitm_requested = true;
|
||||
&& !cb->ltk_mitm_protected) {
|
||||
cb->mitm_requested = true;
|
||||
requestPairing(connection);
|
||||
}
|
||||
}
|
||||
|
@ -880,30 +892,30 @@ void GenericSecurityManager::on_link_encryption_result(
|
|||
link_encryption_t result
|
||||
) {
|
||||
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == link_encryption_t::ENCRYPTED) {
|
||||
|
||||
entry->encryption_requested = false;
|
||||
entry->encryption_failed = false;
|
||||
cb->encryption_requested = false;
|
||||
cb->encryption_failed = false;
|
||||
|
||||
} else if (result == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
||||
|
||||
entry->encryption_requested = false;
|
||||
entry->encryption_failed = false;
|
||||
entry->authenticated = true;
|
||||
cb->encryption_requested = false;
|
||||
cb->encryption_failed = false;
|
||||
cb->authenticated = true;
|
||||
|
||||
} else if (result == link_encryption_t::NOT_ENCRYPTED
|
||||
&& entry->encryption_requested
|
||||
&& !entry->encryption_failed) {
|
||||
&& cb->encryption_requested
|
||||
&& !cb->encryption_failed) {
|
||||
|
||||
/* if we failed encryption for the first time
|
||||
* retry repairing in case slave lost LTK */
|
||||
requestPairing(entry->handle);
|
||||
entry->encryption_failed = true;
|
||||
requestPairing(cb->connection);
|
||||
cb->encryption_failed = true;
|
||||
/* don't return an event yet since we are retrying */
|
||||
return;
|
||||
}
|
||||
|
@ -961,31 +973,20 @@ void GenericSecurityManager::on_oob_data_verification_request(
|
|||
const public_key_t &peer_public_key_y
|
||||
) {
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
|
||||
oob_confirm_t confirm_verify;
|
||||
|
||||
address_t peer_oob_address;
|
||||
oob_rand_t peer_oob_random;
|
||||
oob_confirm_t peer_oob_confirm;
|
||||
oob_rand_t local_oob_random;
|
||||
_db.get_sc_oob_data(
|
||||
peer_oob_address,
|
||||
peer_oob_random,
|
||||
peer_oob_confirm,
|
||||
local_oob_random
|
||||
);
|
||||
|
||||
crypto_toolbox_f4(
|
||||
peer_public_key_x,
|
||||
peer_public_key_y,
|
||||
peer_oob_random,
|
||||
_peer_oob_random,
|
||||
confirm_verify
|
||||
);
|
||||
|
||||
if (entry && (entry->peer_address == peer_oob_address)
|
||||
&& (confirm_verify == peer_oob_confirm)) {
|
||||
_pal.oob_data_verified(connection, local_oob_random, peer_oob_random);
|
||||
if (cb && (cb->peer_address == _peer_oob_address)
|
||||
&& (confirm_verify == _peer_oob_confirm)) {
|
||||
_pal.oob_data_verified(connection, _local_oob_random, _peer_oob_random);
|
||||
} else {
|
||||
_pal.cancel_pairing(connection, pairing_failure_t::CONFIRM_VALUE_FAILED);
|
||||
}
|
||||
|
@ -1008,27 +1009,27 @@ void GenericSecurityManager::on_secure_connections_ltk_generated(
|
|||
connection_handle_t connection,
|
||||
const ltk_t <k
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry->ltk_mitm_protected = entry->mitm_performed;
|
||||
entry->secure_connections_paired = true;
|
||||
cb->ltk_mitm_protected = cb->mitm_performed;
|
||||
cb->secure_connections_paired = true;
|
||||
|
||||
_db.set_entry_peer_ltk(connection, ltk);
|
||||
_db.set_entry_peer_ltk(cb->db_entry, ltk);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_keys_distributed_ltk(
|
||||
connection_handle_t connection,
|
||||
const ltk_t <k
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
entry->ltk_mitm_protected = entry->mitm_performed;
|
||||
_db.set_entry_peer_ltk(connection, ltk);
|
||||
cb->ltk_mitm_protected = cb->mitm_performed;
|
||||
_db.set_entry_peer_ltk(cb->db_entry, ltk);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_keys_distributed_ediv_rand(
|
||||
|
@ -1036,14 +1037,24 @@ void GenericSecurityManager::on_keys_distributed_ediv_rand(
|
|||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
_db.set_entry_peer_ediv_rand(connection, ediv, rand);
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.set_entry_peer_ediv_rand(cb->db_entry, ediv, rand);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_keys_distributed_local_ltk(
|
||||
connection_handle_t connection,
|
||||
const ltk_t <k
|
||||
) {
|
||||
_db.set_entry_local_ltk(connection, ltk);
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.set_entry_local_ltk(cb->db_entry, ltk);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_keys_distributed_local_ediv_rand(
|
||||
|
@ -1051,14 +1062,24 @@ void GenericSecurityManager::on_keys_distributed_local_ediv_rand(
|
|||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
_db.set_entry_local_ediv_rand(connection, ediv, rand);
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.set_entry_local_ediv_rand(cb->db_entry, ediv, rand);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_keys_distributed_irk(
|
||||
connection_handle_t connection,
|
||||
const irk_t &irk
|
||||
) {
|
||||
_db.set_entry_peer_irk(connection, irk);
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.set_entry_peer_irk(cb->db_entry, irk);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_keys_distributed_bdaddr(
|
||||
|
@ -1066,8 +1087,13 @@ void GenericSecurityManager::on_keys_distributed_bdaddr(
|
|||
advertising_peer_address_type_t peer_address_type,
|
||||
const address_t &peer_identity_address
|
||||
) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.set_entry_peer_bdaddr(
|
||||
connection,
|
||||
cb->db_entry,
|
||||
(peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS),
|
||||
peer_identity_address
|
||||
);
|
||||
|
@ -1077,19 +1103,19 @@ void GenericSecurityManager::on_keys_distributed_csrk(
|
|||
connection_handle_t connection,
|
||||
const csrk_t &csrk
|
||||
) {
|
||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
||||
if (!entry) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry->csrk_mitm_protected = entry->mitm_performed;
|
||||
cb->csrk_mitm_protected = cb->mitm_performed;
|
||||
|
||||
_db.set_entry_peer_csrk(connection, csrk);
|
||||
_db.set_entry_peer_csrk(cb->db_entry, csrk);
|
||||
|
||||
eventHandler->signingKey(
|
||||
connection,
|
||||
&csrk,
|
||||
entry->csrk_mitm_protected
|
||||
cb->csrk_mitm_protected
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1098,22 +1124,111 @@ void GenericSecurityManager::on_ltk_request(
|
|||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.get_entry_local_keys(
|
||||
mbed::callback(this, &GenericSecurityManager::set_ltk_cb),
|
||||
connection,
|
||||
cb->db_entry,
|
||||
ediv,
|
||||
rand
|
||||
);
|
||||
}
|
||||
|
||||
void GenericSecurityManager::on_ltk_request(
|
||||
connection_handle_t connection
|
||||
) {
|
||||
/* control blocks list management */
|
||||
|
||||
GenericSecurityManager::ControlBlock_t::ControlBlock_t() :
|
||||
pal::SecurityDistributionFlags_t(),
|
||||
connection(0),
|
||||
local_address(),
|
||||
db_entry(0),
|
||||
connected(false),
|
||||
authenticated(false),
|
||||
is_master(false),
|
||||
encryption_requested(false),
|
||||
encryption_failed(false),
|
||||
encrypted(false),
|
||||
signing_requested(false),
|
||||
mitm_requested(false),
|
||||
mitm_performed(false),
|
||||
attempt_oob(false),
|
||||
oob_mitm_protection(false),
|
||||
oob_present(false) { }
|
||||
|
||||
void GenericSecurityManager::on_ltk_request(connection_handle_t connection)
|
||||
{
|
||||
ControlBlock_t *cb = get_control_block(connection);
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
_db.get_entry_local_keys(
|
||||
mbed::callback(this, &GenericSecurityManager::set_ltk_cb),
|
||||
connection
|
||||
cb->db_entry
|
||||
);
|
||||
}
|
||||
|
||||
GenericSecurityManager::ControlBlock_t*
|
||||
GenericSecurityManager::acquire_control_block(connection_handle_t connection)
|
||||
{
|
||||
/* grab the first disconnected slot*/
|
||||
for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) {
|
||||
if (!_control_blocks[i].connected) {
|
||||
ControlBlock_t* cb = &_control_blocks[i];
|
||||
cb->connected = true;
|
||||
cb->connection = connection;
|
||||
return cb;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_block(
|
||||
connection_handle_t connection
|
||||
) {
|
||||
for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) {
|
||||
if (!_control_blocks[i].connected) {
|
||||
continue;
|
||||
} else if (connection == _control_blocks[i].connection) {
|
||||
return &_control_blocks[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_block(
|
||||
const address_t &peer_address
|
||||
) {
|
||||
for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) {
|
||||
if (!_control_blocks[i].connected) {
|
||||
continue;
|
||||
} else if (peer_address == _control_blocks[i].peer_address) {
|
||||
return &_control_blocks[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_block(
|
||||
pal::SecurityDb::entry_handle_t db_entry
|
||||
) {
|
||||
for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) {
|
||||
if (!_control_blocks[i].connected) {
|
||||
continue;
|
||||
} else if (db_entry == _control_blocks[i].db_entry) {
|
||||
return &_control_blocks[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GenericSecurityManager::release_control_block(ControlBlock_t* cb)
|
||||
{
|
||||
*cb = ControlBlock_t();
|
||||
}
|
||||
|
||||
} /* namespace generic */
|
||||
} /* namespace ble */
|
||||
|
|
|
@ -94,6 +94,8 @@ add_executable(security-manager-tests
|
|||
mbed_os_stub/mbed_assert.c
|
||||
generic/SecurityManager/mock/MockPalSecurityManager.cpp
|
||||
generic/SecurityManager/mock/MockPalSecurityDb.cpp
|
||||
generic/SecurityManager/mock/MockConnectionEventMonitor.cpp
|
||||
generic/SecurityManager/mock/MockSecurityManagerEventHandler.cpp
|
||||
${PROJECT_SOURCE_DIR}/../source/generic/GenericSecurityManager.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#include "MockConnectionEventMonitor.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
namespace vendor {
|
||||
namespace mock {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor implementation of the mocked pal connection event monitor
|
||||
//
|
||||
// WARNING: Do not remove; it speedup compile time.
|
||||
|
||||
MockPalConnectionEventMonitor::MockPalConnectionEventMonitor() { }
|
||||
MockPalConnectionEventMonitor::~MockPalConnectionEventMonitor() { }
|
||||
|
||||
} // namespace ble
|
||||
} // namespace pal
|
||||
} // namespace vendor
|
||||
} // namespace mock
|
|
@ -0,0 +1,45 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 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 TESTS_GENERIC_SECURITYMANAGER_MOCK_MOCKPALCONENCTIONEVENTMONITOR_H_
|
||||
#define TESTS_GENERIC_SECURITYMANAGER_MOCK_MOCKPALCONENCTIONEVENTMONITOR_H_
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "ble/pal/ConnectionEventMonitor.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
namespace vendor {
|
||||
namespace mock {
|
||||
|
||||
/*
|
||||
* Mock of ble::pal::ConnectionEventMonitor
|
||||
*/
|
||||
class MockPalConnectionEventMonitor : public ble::pal::ConnectionEventMonitor {
|
||||
public:
|
||||
MockPalConnectionEventMonitor();
|
||||
|
||||
virtual ~MockPalConnectionEventMonitor();
|
||||
|
||||
MOCK_METHOD1(set_connection_event_handler, void(ConnectionEventHandler *));
|
||||
};
|
||||
|
||||
} // namespace ble
|
||||
} // namespace pal
|
||||
} // namespace vendor
|
||||
} // namespace mock
|
||||
|
||||
#endif /* TESTS_GENERIC_SECURITYMANAGER_MOCK_MOCKPALCONENCTIONEVENTMONITOR_H_ */
|
|
@ -34,154 +34,68 @@ public:
|
|||
|
||||
virtual ~MockPalSecurityDb();
|
||||
|
||||
MOCK_METHOD1(get_entry, SecurityEntry_t*(connection_handle_t));
|
||||
|
||||
MOCK_METHOD1(get_entry, SecurityEntry_t*(const address_t &));
|
||||
|
||||
MOCK_METHOD4(
|
||||
get_entry_local_keys,
|
||||
void(
|
||||
SecurityEntryKeysDbCb_t,
|
||||
connection_handle_t,
|
||||
const ediv_t &,
|
||||
const rand_t &
|
||||
)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
get_entry_local_keys,
|
||||
void(SecurityEntryKeysDbCb_t, connection_handle_t)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
set_entry_local_ltk,
|
||||
void(connection_handle_t, const ltk_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD3(
|
||||
set_entry_local_ediv_rand,
|
||||
void(connection_handle_t, const ediv_t &, const rand_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
get_entry_peer_csrk,
|
||||
void(SecurityEntryCsrkDbCb_t, connection_handle_t)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
get_entry_peer_keys,
|
||||
void(SecurityEntryKeysDbCb_t, connection_handle_t)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
set_entry_peer_ltk,
|
||||
void(connection_handle_t, const ltk_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD3(
|
||||
set_entry_peer_ediv_rand,
|
||||
void(connection_handle_t, const ediv_t &, const rand_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
set_entry_peer_irk,
|
||||
void(connection_handle_t, const irk_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD3(
|
||||
set_entry_peer_bdaddr,
|
||||
void(connection_handle_t, bool, const address_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
set_entry_peer_csrk,
|
||||
void(connection_handle_t, const csrk_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD0(get_local_csrk, const csrk_t*());
|
||||
|
||||
MOCK_METHOD1(set_local_csrk, void(const csrk_t &));
|
||||
|
||||
MOCK_METHOD0(get_public_key_x, const public_key_t&());
|
||||
|
||||
MOCK_METHOD0(get_public_key_y, const public_key_t&());
|
||||
|
||||
MOCK_METHOD2(set_public_key, void(const public_key_t &, const public_key_t &));
|
||||
|
||||
MOCK_METHOD0(get_peer_sc_oob_address, const address_t&());
|
||||
|
||||
MOCK_METHOD0(get_peer_sc_oob_random, const oob_rand_t&());
|
||||
|
||||
MOCK_METHOD0(get_peer_sc_oob_confirm, const oob_confirm_t&());
|
||||
|
||||
MOCK_METHOD4(
|
||||
get_sc_oob_data,
|
||||
void(
|
||||
address_t &,
|
||||
oob_rand_t &,
|
||||
oob_confirm_t &,
|
||||
oob_rand_t &
|
||||
)
|
||||
);
|
||||
|
||||
MOCK_METHOD0(get_local_sc_oob_random, const oob_rand_t&());
|
||||
|
||||
MOCK_METHOD3(
|
||||
set_peer_sc_oob_data,
|
||||
void(
|
||||
const address_t &,
|
||||
const oob_rand_t &,
|
||||
const oob_confirm_t &
|
||||
)
|
||||
);
|
||||
|
||||
MOCK_METHOD1(set_local_sc_oob_random, void(const oob_rand_t&));
|
||||
|
||||
MOCK_METHOD4(
|
||||
connect_entry,
|
||||
SecurityEntry_t*(
|
||||
connection_handle_t,
|
||||
BLEProtocol::AddressType_t,
|
||||
const address_t &,
|
||||
const address_t &
|
||||
)
|
||||
);
|
||||
|
||||
MOCK_METHOD1(disconnect_entry, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD1(remove_entry, void(const address_t));
|
||||
|
||||
MOCK_METHOD0(clear_entries, void());
|
||||
|
||||
MOCK_METHOD2(get_whitelist, void(WhitelistDbCb_t, Gap::Whitelist_t *));
|
||||
|
||||
MOCK_METHOD2(
|
||||
generate_whitelist_from_bond_table,
|
||||
void(WhitelistDbCb_t, Gap::Whitelist_t *)
|
||||
);
|
||||
|
||||
MOCK_METHOD2(
|
||||
set_whitelist,
|
||||
void(WhitelistDbCb_t, const Gap::Whitelist_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD1(
|
||||
add_whitelist_entry,
|
||||
void(const address_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD1(
|
||||
remove_whitelist_entry,
|
||||
void(const address_t &)
|
||||
);
|
||||
|
||||
MOCK_METHOD0(clear_whitelist, void());
|
||||
|
||||
MOCK_METHOD0(restore, void());
|
||||
|
||||
MOCK_METHOD0(sync, void());
|
||||
|
||||
MOCK_METHOD1(set_restore, void(bool));
|
||||
MOCK_METHOD1(get_distribution_flags,
|
||||
const SecurityDistributionFlags_t*(entry_handle_t db_entry));
|
||||
MOCK_METHOD2(set_distribution_flags,
|
||||
void(entry_handle_t db_entry, const SecurityDistributionFlags_t& flags));
|
||||
MOCK_METHOD4(get_entry_local_keys,
|
||||
void(SecurityEntryKeysDbCb_t cb, entry_handle_t db_entry, const ediv_t &ediv, const rand_t &rand));
|
||||
MOCK_METHOD2(get_entry_local_keys,
|
||||
void(SecurityEntryKeysDbCb_t cb, entry_handle_t db_entry));
|
||||
MOCK_METHOD2(set_entry_local_ltk,
|
||||
void(entry_handle_t db_entry, const ltk_t <k));
|
||||
MOCK_METHOD3(set_entry_local_ediv_rand,
|
||||
void(entry_handle_t db_entry, const ediv_t &ediv, const rand_t &rand));
|
||||
MOCK_METHOD2(get_entry_peer_csrk,
|
||||
void(SecurityEntryCsrkDbCb_t cb, entry_handle_t db_entry));
|
||||
MOCK_METHOD2(get_entry_peer_keys,
|
||||
void(SecurityEntryKeysDbCb_t cb, entry_handle_t db_entry));
|
||||
MOCK_METHOD2(set_entry_peer_ltk,
|
||||
void(entry_handle_t db_entry, const ltk_t <k));
|
||||
MOCK_METHOD3(set_entry_peer_ediv_rand,
|
||||
void(entry_handle_t db_entry, const ediv_t &ediv, const rand_t &rand));
|
||||
MOCK_METHOD2(set_entry_peer_irk,
|
||||
void(entry_handle_t db_entry, const irk_t &irk));
|
||||
MOCK_METHOD3(set_entry_peer_bdaddr,
|
||||
void(entry_handle_t db_entry, bool address_is_public, const address_t &peer_address));
|
||||
MOCK_METHOD2(set_entry_peer_csrk,
|
||||
void(entry_handle_t db_entry, const csrk_t &csrk));
|
||||
MOCK_METHOD0(get_local_csrk,
|
||||
const csrk_t*());
|
||||
MOCK_METHOD1(set_local_csrk,
|
||||
void(const csrk_t &csrk));
|
||||
MOCK_METHOD0(get_public_key_x,
|
||||
const public_key_t&());
|
||||
MOCK_METHOD0(get_public_key_y,
|
||||
const public_key_t&());
|
||||
MOCK_METHOD2(set_public_key,
|
||||
void(const public_key_t &public_key_x, const public_key_t &public_key_y));
|
||||
MOCK_METHOD2(open_entry,
|
||||
entry_handle_t(BLEProtocol::AddressType_t peer_address_type, const address_t &peer_address));
|
||||
MOCK_METHOD1(close_entry,
|
||||
void(entry_handle_t db_entry));
|
||||
MOCK_METHOD1(remove_entry,
|
||||
void(const address_t peer_identity_address));
|
||||
MOCK_METHOD0(clear_entries,
|
||||
void());
|
||||
MOCK_METHOD2(get_whitelist,
|
||||
void(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist));
|
||||
MOCK_METHOD2(generate_whitelist_from_bond_table,
|
||||
void(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist));
|
||||
MOCK_METHOD1(set_whitelist,
|
||||
void(const ::Gap::Whitelist_t &whitelist));
|
||||
MOCK_METHOD1(add_whitelist_entry,
|
||||
void(const address_t &address));
|
||||
MOCK_METHOD1(remove_whitelist_entry,
|
||||
void(const address_t &address));
|
||||
MOCK_METHOD0(clear_whitelist,
|
||||
void());
|
||||
MOCK_METHOD0(restore,
|
||||
void());
|
||||
MOCK_METHOD0(sync,
|
||||
void());
|
||||
MOCK_METHOD1(set_restore,
|
||||
void(bool reload));
|
||||
};
|
||||
|
||||
} // namespace ble
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#include "MockSecurityManagerEventHandler.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
namespace vendor {
|
||||
namespace mock {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor implementation of the mocked pal security manager
|
||||
//
|
||||
// WARNING: Do not remove; it speedup compile time.
|
||||
|
||||
MockSecurityManagerEventHandler::MockSecurityManagerEventHandler() { }
|
||||
MockSecurityManagerEventHandler::~MockSecurityManagerEventHandler() { }
|
||||
|
||||
} // namespace ble
|
||||
} // namespace pal
|
||||
} // namespace vendor
|
||||
} // namespace mock
|
|
@ -0,0 +1,72 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 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 TESTS_GENERIC_SECURITYMANAGER_MOCK_MOCKSECURITYMANAGEREVENTHANDLER_H_
|
||||
#define TESTS_GENERIC_SECURITYMANAGER_MOCK_MOCKSECURITYMANAGEREVENTHANDLER_H_
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "ble/SecurityManager.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
namespace vendor {
|
||||
namespace mock {
|
||||
|
||||
/*
|
||||
* Mock of ble::pal::SecurityManager
|
||||
*/
|
||||
class MockSecurityManagerEventHandler :
|
||||
public ::SecurityManager::SecurityManagerEventHandler {
|
||||
public:
|
||||
MockSecurityManagerEventHandler();
|
||||
|
||||
virtual ~MockSecurityManagerEventHandler();
|
||||
|
||||
MOCK_METHOD1(pairingRequest, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD2(pairingResult, void(connection_handle_t, SecurityManager::SecurityCompletionStatus_t));
|
||||
|
||||
MOCK_METHOD1(validMicTimeout, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD1(whitelistFromBondTable, void(Gap::Whitelist_t*));
|
||||
|
||||
MOCK_METHOD2(whitelistFromBondTable, void(connection_handle_t, link_encryption_t));
|
||||
|
||||
MOCK_METHOD2(passkeyDisplay, void(connection_handle_t, const SecurityManager::Passkey_t));
|
||||
|
||||
MOCK_METHOD1(confirmationRequest, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD1(passkeyRequest, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD2(keypressNotification, void(connection_handle_t, SecurityManager::Keypress_t));
|
||||
|
||||
MOCK_METHOD1(legacyPairingOobRequest, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD1(oobRequest, void(connection_handle_t));
|
||||
|
||||
MOCK_METHOD2(legacyPairingOobGenerated, void(const address_t *, const oob_tk_t *));
|
||||
|
||||
MOCK_METHOD3(oobGenerated, void(const address_t *, const oob_rand_t *, const oob_confirm_t *));
|
||||
|
||||
MOCK_METHOD3(signingKey, void(connection_handle_t, const csrk_t *, bool));
|
||||
};
|
||||
|
||||
} // namespace ble
|
||||
} // namespace pal
|
||||
} // namespace vendor
|
||||
} // namespace mock
|
||||
|
||||
#endif /* TESTS_GENERIC_SECURITYMANAGER_MOCK_MOCKSECURITYMANAGEREVENTHANDLER_H_ */
|
|
@ -0,0 +1,49 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 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 TESTS_GENERIC_SECURITYMANAGER_MOCK_STUBCONNECTIONEVENTMONITOR_H_
|
||||
#define TESTS_GENERIC_SECURITYMANAGER_MOCK_STUBCONNECTIONEVENTMONITOR_H_
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "ble/pal/ConnectionEventMonitor.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
namespace vendor {
|
||||
namespace mock {
|
||||
|
||||
/*
|
||||
* Stub of ble::pal::ConnectionEventMonitor
|
||||
*/
|
||||
struct StubPalConnectionEventMonitor : public ble::pal::ConnectionEventMonitor {
|
||||
StubPalConnectionEventMonitor() : event_handler(nullptr) { }
|
||||
|
||||
virtual ~StubPalConnectionEventMonitor() { }
|
||||
|
||||
void set_connection_event_handler(pal::ConnectionEventHandler *connection_event_handler)
|
||||
{
|
||||
event_handler = connection_event_handler;
|
||||
}
|
||||
|
||||
pal::ConnectionEventHandler *event_handler;
|
||||
};
|
||||
|
||||
} // namespace mock
|
||||
} // namespace vendor
|
||||
} // namespace pal
|
||||
} // namespace ble
|
||||
|
||||
#endif /* TESTS_GENERIC_SECURITYMANAGER_MOCK_STUBCONNECTIONEVENTMONITOR_H_ */
|
Loading…
Reference in New Issue