mirror of https://github.com/ARMmbed/mbed-os.git
commit
268655a028
|
@ -435,7 +435,7 @@ public:
|
||||||
* @param[in] connectionHandle Handle to identify the connection.
|
* @param[in] connectionHandle Handle to identify the connection.
|
||||||
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
* @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;
|
(void) connectionHandle;
|
||||||
return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */
|
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
|
* @param[in] required If set to true, pairingRequest in the event handler will
|
||||||
* will be called and will require an action from the application
|
* will be called and will require an action from the application
|
||||||
* to continue with pairing by calling acceptPairingRequest
|
* 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.
|
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
||||||
*/
|
*/
|
||||||
virtual ble_error_t setPairingRequestAuthorisation(bool required = true) {
|
virtual ble_error_t setPairingRequestAuthorisation(bool required = true) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ class GenericSecurityManager : public SecurityManager,
|
||||||
public pal::SecurityManagerEventHandler,
|
public pal::SecurityManagerEventHandler,
|
||||||
public pal::ConnectionEventHandler {
|
public pal::ConnectionEventHandler {
|
||||||
public:
|
public:
|
||||||
typedef ble::pal::SecurityEntry_t SecurityEntry_t;
|
typedef ble::pal::SecurityDistributionFlags_t SecurityDistributionFlags_t;
|
||||||
typedef ble::pal::SecurityEntryKeys_t SecurityEntryKeys_t;
|
typedef ble::pal::SecurityEntryKeys_t SecurityEntryKeys_t;
|
||||||
|
|
||||||
/* implements SecurityManager */
|
/* implements SecurityManager */
|
||||||
|
@ -86,7 +86,7 @@ public:
|
||||||
connection_handle_t connection
|
connection_handle_t connection
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ble_error_t canceltPairingRequest(
|
virtual ble_error_t cancelPairingRequest(
|
||||||
connection_handle_t connection
|
connection_handle_t connection
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ private:
|
||||||
* @param[in] entryKeys security entry containing keys.
|
* @param[in] entryKeys security entry containing keys.
|
||||||
*/
|
*/
|
||||||
void enable_encryption_cb(
|
void enable_encryption_cb(
|
||||||
const SecurityEntry_t* entry,
|
pal::SecurityDb::entry_handle_t entry,
|
||||||
const SecurityEntryKeys_t* entryKeys
|
const SecurityEntryKeys_t* entryKeys
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ private:
|
||||||
* @param[in] entryKeys security entry containing keys.
|
* @param[in] entryKeys security entry containing keys.
|
||||||
*/
|
*/
|
||||||
void set_ltk_cb(
|
void set_ltk_cb(
|
||||||
const SecurityEntry_t* entry,
|
pal::SecurityDb::entry_handle_t entry,
|
||||||
const SecurityEntryKeys_t* entryKeys
|
const SecurityEntryKeys_t* entryKeys
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ private:
|
||||||
* @param[in] entryKeys security entry containing keys.
|
* @param[in] entryKeys security entry containing keys.
|
||||||
*/
|
*/
|
||||||
void return_csrk_cb(
|
void return_csrk_cb(
|
||||||
connection_handle_t connection,
|
pal::SecurityDb::entry_handle_t connection,
|
||||||
const csrk_t *csrk
|
const csrk_t *csrk
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -431,6 +431,31 @@ private:
|
||||||
);
|
);
|
||||||
|
|
||||||
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::SecurityManager &_pal;
|
||||||
pal::SecurityDb &_db;
|
pal::SecurityDb &_db;
|
||||||
pal::ConnectionEventMonitor &_connection_monitor;
|
pal::ConnectionEventMonitor &_connection_monitor;
|
||||||
|
@ -443,6 +468,14 @@ private:
|
||||||
bool _master_sends_keys;
|
bool _master_sends_keys;
|
||||||
bool _public_keys_generated;
|
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 */
|
/* implements ble::pal::SecurityManagerEventHandler */
|
||||||
public:
|
public:
|
||||||
|
@ -642,6 +675,18 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
/* end implements ble::pal::SecurityManagerEventHandler */
|
/* 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
|
#ifndef MBED_BLE_CONNECTION_EVENT_MONITOR
|
||||||
#define MBED_BLE_CONNECTION_EVENT_MONITOR
|
#define MBED_BLE_CONNECTION_EVENT_MONITOR
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "ble/BLE.h"
|
|
||||||
#include "ble/BLEProtocol.h"
|
#include "ble/BLEProtocol.h"
|
||||||
#include "ble/Gap.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/BLETypes.h"
|
||||||
#include "ble/pal/GenericAccessService.h"
|
|
||||||
#include "ble/pal/EventQueue.h"
|
|
||||||
|
|
||||||
namespace ble {
|
namespace ble {
|
||||||
namespace pal {
|
namespace pal {
|
||||||
|
|
|
@ -14,11 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PAL_MEMORY_SECURITY_MANAGER_DB_H__
|
#ifndef PAL_MEMORY_SECURITY_MANAGER_entries_H__
|
||||||
#define PAL_MEMORY_SECURITY_MANAGER_DB_H__
|
#define PAL_MEMORY_SECURITY_MANAGER_entries_H__
|
||||||
|
|
||||||
#include "SecurityDB.h"
|
#include "SecurityDB.h"
|
||||||
#include "Gap.h"
|
|
||||||
|
|
||||||
namespace ble {
|
namespace ble {
|
||||||
namespace pal {
|
namespace pal {
|
||||||
|
@ -27,42 +26,57 @@ namespace pal {
|
||||||
* TODO: make thread safe */
|
* TODO: make thread safe */
|
||||||
class MemorySecurityDb : public SecurityDb {
|
class MemorySecurityDb : public SecurityDb {
|
||||||
private:
|
private:
|
||||||
struct db_store_t {
|
enum state_t {
|
||||||
db_store_t() { };
|
ENTRY_FREE,
|
||||||
SecurityEntry_t entry;
|
ENTRY_RESERVED,
|
||||||
|
ENTRY_WRITTEN
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entry_t {
|
||||||
|
entry_t() : state(ENTRY_FREE) { };
|
||||||
|
SecurityDistributionFlags_t flags;
|
||||||
SecurityEntryKeys_t peer_keys;
|
SecurityEntryKeys_t peer_keys;
|
||||||
SecurityEntryKeys_t local_keys;
|
SecurityEntryKeys_t local_keys;
|
||||||
|
SecurityEntryIdentity_t peer_identity;
|
||||||
csrk_t csrk;
|
csrk_t csrk;
|
||||||
|
state_t state;
|
||||||
};
|
};
|
||||||
static const size_t MAX_ENTRIES = 5;
|
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:
|
public:
|
||||||
MemorySecurityDb() { };
|
MemorySecurityDb() { };
|
||||||
virtual ~MemorySecurityDb() { };
|
virtual ~MemorySecurityDb() { };
|
||||||
|
|
||||||
virtual SecurityEntry_t* get_entry(
|
virtual const SecurityDistributionFlags_t* get_distribution_flags(
|
||||||
connection_handle_t connection
|
entry_handle_t entry_handle
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = NULL;
|
entry_t* entry = as_entry(entry_handle);
|
||||||
db_store_t *store = get_store(connection);
|
if (!entry) {
|
||||||
if (store) {
|
return NULL;
|
||||||
entry = &store->entry;
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SecurityEntry_t* get_entry(
|
return &entry->flags;
|
||||||
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;
|
entry_t* entry = as_entry(entry_handle);
|
||||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
if (!entry) {
|
||||||
if (!_db[i].entry.connected) {
|
return;
|
||||||
continue;
|
|
||||||
} else if (peer_address == _db[i].entry.peer_address) {
|
|
||||||
entry = &_db[i].entry;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return entry;
|
entry->state = ENTRY_WRITTEN;
|
||||||
|
entry->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* local keys */
|
/* local keys */
|
||||||
|
@ -70,64 +84,63 @@ public:
|
||||||
/* get */
|
/* get */
|
||||||
virtual void get_entry_local_keys(
|
virtual void get_entry_local_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = NULL;
|
entry_t* entry = as_entry(entry_handle);
|
||||||
db_store_t *store = get_store(connection);
|
if (!entry) {
|
||||||
if (store) {
|
return;
|
||||||
entry = &store->entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* validate we have the correct key */
|
/* validate we have the correct key */
|
||||||
if (ediv == store->local_keys.ediv
|
if (ediv == entry->local_keys.ediv && rand == entry->local_keys.rand) {
|
||||||
&& rand == store->local_keys.rand) {
|
cb(entry_handle, &entry->local_keys);
|
||||||
cb(entry, &store->local_keys);
|
|
||||||
} else {
|
} else {
|
||||||
cb(entry, NULL);
|
cb(entry_handle, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void get_entry_local_keys(
|
virtual void get_entry_local_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
connection_handle_t connection
|
entry_handle_t entry_handle
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = NULL;
|
entry_t* entry = as_entry(entry_handle);
|
||||||
db_store_t *store = get_store(connection);
|
if (!entry) {
|
||||||
if (store) {
|
return;
|
||||||
entry = &store->entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* validate we have the correct key */
|
/* validate we have the correct key */
|
||||||
if (entry->secure_connections_paired) {
|
if (entry->flags.secure_connections_paired) {
|
||||||
cb(entry, &store->local_keys);
|
cb(entry_handle, &entry->local_keys);
|
||||||
} else {
|
} else {
|
||||||
cb(entry, NULL);
|
cb(entry_handle, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* set */
|
/* set */
|
||||||
virtual void set_entry_local_ltk(
|
virtual void set_entry_local_ltk(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
store->local_keys.ltk = ltk;
|
entry->state = ENTRY_WRITTEN;
|
||||||
|
entry->local_keys.ltk = ltk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set_entry_local_ediv_rand(
|
virtual void set_entry_local_ediv_rand(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
store->local_keys.ediv = ediv;
|
entry->state = ENTRY_WRITTEN;
|
||||||
store->local_keys.rand = rand;
|
entry->local_keys.ediv = ediv;
|
||||||
|
entry->local_keys.rand = rand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,86 +149,85 @@ public:
|
||||||
/* get */
|
/* get */
|
||||||
virtual void get_entry_peer_csrk(
|
virtual void get_entry_peer_csrk(
|
||||||
SecurityEntryCsrkDbCb_t cb,
|
SecurityEntryCsrkDbCb_t cb,
|
||||||
connection_handle_t connection
|
entry_handle_t entry_handle
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = NULL;
|
|
||||||
csrk_t csrk;
|
csrk_t csrk;
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
entry = &store->entry;
|
csrk = entry->csrk;
|
||||||
csrk = store->csrk;
|
|
||||||
}
|
}
|
||||||
cb(entry->handle, &csrk);
|
cb(entry_handle, &csrk);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void get_entry_peer_keys(
|
virtual void get_entry_peer_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
connection_handle_t connection
|
entry_handle_t entry_handle
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = NULL;
|
|
||||||
SecurityEntryKeys_t *key = NULL;
|
SecurityEntryKeys_t *key = NULL;
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
entry = &store->entry;
|
key = &entry->peer_keys;
|
||||||
key = &store->peer_keys;
|
|
||||||
}
|
}
|
||||||
cb(entry, key);
|
cb(entry_handle, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set */
|
/* set */
|
||||||
|
|
||||||
virtual void set_entry_peer_ltk(
|
virtual void set_entry_peer_ltk(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
store->peer_keys.ltk = ltk;
|
entry->state = ENTRY_WRITTEN;
|
||||||
|
entry->peer_keys.ltk = ltk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set_entry_peer_ediv_rand(
|
virtual void set_entry_peer_ediv_rand(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
store->peer_keys.ediv = ediv;
|
entry->state = ENTRY_WRITTEN;
|
||||||
store->peer_keys.rand = rand;
|
entry->peer_keys.ediv = ediv;
|
||||||
|
entry->peer_keys.rand = rand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set_entry_peer_irk(
|
virtual void set_entry_peer_irk(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const irk_t &irk
|
const irk_t &irk
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
size_t index = store - _db;
|
entry->state = ENTRY_WRITTEN;
|
||||||
_identities[index].irk = irk;
|
entry->peer_identity.irk = irk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set_entry_peer_bdaddr(
|
virtual void set_entry_peer_bdaddr(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
bool address_is_public,
|
bool address_is_public,
|
||||||
const address_t &peer_address
|
const address_t &peer_address
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
size_t index = store - _db;
|
entry->state = ENTRY_WRITTEN;
|
||||||
_identities[index].identity_address = peer_address;
|
entry->peer_identity.identity_address = peer_address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set_entry_peer_csrk(
|
virtual void set_entry_peer_csrk(
|
||||||
connection_handle_t connection,
|
entry_handle_t entry_handle,
|
||||||
const csrk_t &csrk
|
const csrk_t &csrk
|
||||||
) {
|
) {
|
||||||
db_store_t *store = get_store(connection);
|
entry_t *entry = as_entry(entry_handle);
|
||||||
if (store) {
|
if (entry) {
|
||||||
store->csrk = csrk;
|
entry->state = ENTRY_WRITTEN;
|
||||||
|
entry->csrk = csrk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,96 +259,62 @@ public:
|
||||||
_public_key_y = public_key_y;
|
_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 */
|
/* list management */
|
||||||
|
|
||||||
virtual SecurityEntry_t* connect_entry(
|
virtual entry_handle_t open_entry(
|
||||||
connection_handle_t connection,
|
|
||||||
BLEProtocol::AddressType_t peer_address_type,
|
BLEProtocol::AddressType_t peer_address_type,
|
||||||
const address_t &peer_address,
|
const address_t &peer_address
|
||||||
const address_t &local_address
|
|
||||||
) {
|
) {
|
||||||
const bool peer_address_public =
|
const bool peer_address_public =
|
||||||
(peer_address_type == BLEProtocol::AddressType::PUBLIC);
|
(peer_address_type == BLEProtocol::AddressType::PUBLIC);
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||||
if (_db[i].entry.connected) {
|
if (_entries[i].state == ENTRY_FREE) {
|
||||||
continue;
|
continue;
|
||||||
} else if (peer_address == _identities[i].identity_address
|
} else if (peer_address == _entries[i].peer_identity.identity_address
|
||||||
&& _db[i].entry.peer_address_is_public == peer_address_public) {
|
&& _entries[i].flags.peer_address_is_public == peer_address_public) {
|
||||||
return &_db[i].entry;
|
return &_entries[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we din't find one grab the first disconnected slot*/
|
/* if we din't find one grab the first disconnected slot*/
|
||||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||||
if (!_db[i].entry.connected) {
|
if (_entries[i].state == ENTRY_FREE) {
|
||||||
_db[i] = db_store_t();
|
_entries[i] = entry_t();
|
||||||
_identities[i] = SecurityEntryIdentity_t();
|
_entries[i].flags.peer_address = peer_address;
|
||||||
_db[i].entry.peer_address = peer_address;
|
_entries[i].flags.peer_address_is_public = peer_address_public;
|
||||||
_db[i].entry.local_address = local_address;
|
_entries[i].state = ENTRY_RESERVED;
|
||||||
_db[i].entry.peer_address_is_public = peer_address_public;
|
return &_entries[i];
|
||||||
return &_db[i].entry;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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() {
|
virtual void clear_entries() {
|
||||||
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
for (size_t i = 0; i < MAX_ENTRIES; i++) {
|
||||||
_db[i] = db_store_t();
|
_entries[i] = entry_t();
|
||||||
}
|
}
|
||||||
_local_identity = SecurityEntryIdentity_t();
|
_local_identity = SecurityEntryIdentity_t();
|
||||||
_local_csrk = csrk_t();
|
_local_csrk = csrk_t();
|
||||||
|
@ -349,7 +327,7 @@ public:
|
||||||
|
|
||||||
virtual void generate_whitelist_from_bond_table(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist) {
|
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++) {
|
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;
|
whitelist->addresses[i].type = BLEProtocol::AddressType::PUBLIC;
|
||||||
} else {
|
} else {
|
||||||
whitelist->addresses[i].type = BLEProtocol::AddressType::RANDOM_STATIC;
|
whitelist->addresses[i].type = BLEProtocol::AddressType::RANDOM_STATIC;
|
||||||
|
@ -357,7 +335,7 @@ public:
|
||||||
|
|
||||||
memcpy(
|
memcpy(
|
||||||
whitelist->addresses[i].address,
|
whitelist->addresses[i].address,
|
||||||
_identities[i].identity_address.data(),
|
_entries[i].peer_identity.identity_address.data(),
|
||||||
sizeof(BLEProtocol::AddressBytes_t)
|
sizeof(BLEProtocol::AddressBytes_t)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -365,8 +343,6 @@ public:
|
||||||
cb(whitelist);
|
cb(whitelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void update_whitelist(::Gap::Whitelist_t &whitelist) { }
|
|
||||||
|
|
||||||
virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) { };
|
virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) { };
|
||||||
|
|
||||||
virtual void add_whitelist_entry(const address_t &address) { }
|
virtual void add_whitelist_entry(const address_t &address) { }
|
||||||
|
@ -384,32 +360,14 @@ public:
|
||||||
virtual void set_restore(bool reload) { }
|
virtual void set_restore(bool reload) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
entry_t _entries[MAX_ENTRIES];
|
||||||
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];
|
|
||||||
SecurityEntryIdentity_t _local_identity;
|
SecurityEntryIdentity_t _local_identity;
|
||||||
csrk_t _local_csrk;
|
csrk_t _local_csrk;
|
||||||
public_key_t _public_key_x;
|
public_key_t _public_key_x;
|
||||||
public_key_t _public_key_y;
|
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 pal */
|
||||||
} /* namespace ble */
|
} /* namespace ble */
|
||||||
|
|
||||||
#endif /*PAL_MEMORY_SECURITY_MANAGER_DB_H__*/
|
#endif /*PAL_MEMORY_SECURITY_MANAGER_entries_H__*/
|
||||||
|
|
|
@ -26,13 +26,10 @@
|
||||||
namespace ble {
|
namespace ble {
|
||||||
namespace pal {
|
namespace pal {
|
||||||
|
|
||||||
/* separate structs for keys to allow db implementation
|
|
||||||
* to minimise memory usage, only holding live connection
|
|
||||||
* state in memory */
|
|
||||||
|
|
||||||
struct SecurityEntry_t {
|
struct SecurityDistributionFlags_t {
|
||||||
SecurityEntry_t()
|
SecurityDistributionFlags_t() :
|
||||||
: handle(0),
|
peer_address(),
|
||||||
encryption_key_size(0),
|
encryption_key_size(0),
|
||||||
peer_address_is_public(false),
|
peer_address_is_public(false),
|
||||||
local_address_is_public(false),
|
local_address_is_public(false),
|
||||||
|
@ -40,44 +37,9 @@ struct SecurityEntry_t {
|
||||||
csrk_mitm_protected(false),
|
csrk_mitm_protected(false),
|
||||||
ltk_stored(false),
|
ltk_stored(false),
|
||||||
ltk_mitm_protected(false),
|
ltk_mitm_protected(false),
|
||||||
secure_connections_paired(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connection_handle_t handle;
|
|
||||||
address_t peer_address;
|
address_t peer_address;
|
||||||
|
|
||||||
uint8_t encryption_key_size;
|
uint8_t encryption_key_size;
|
||||||
|
@ -89,26 +51,6 @@ struct SecurityEntry_t {
|
||||||
uint8_t ltk_stored:1;
|
uint8_t ltk_stored:1;
|
||||||
uint8_t ltk_mitm_protected:1;
|
uint8_t ltk_mitm_protected:1;
|
||||||
uint8_t secure_connections_paired: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 {
|
struct SecurityEntryKeys_t {
|
||||||
|
@ -122,12 +64,6 @@ struct SecurityEntryIdentity_t {
|
||||||
irk_t irk;
|
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.
|
* SecurityDB holds the state for active connections and bonded devices.
|
||||||
* Keys can be stored in NVM and are returned via callbacks.
|
* 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 {
|
class SecurityDb {
|
||||||
public:
|
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() { };
|
SecurityDb() { };
|
||||||
virtual ~SecurityDb() { };
|
virtual ~SecurityDb() { };
|
||||||
|
|
||||||
|
@ -147,19 +97,16 @@ public:
|
||||||
* @param[in] handle valid connection handle
|
* @param[in] handle valid connection handle
|
||||||
* @return pointer to security entry, NULL if handle was invalid
|
* @return pointer to security entry, NULL if handle was invalid
|
||||||
*/
|
*/
|
||||||
virtual SecurityEntry_t* get_entry(
|
virtual const SecurityDistributionFlags_t* get_distribution_flags(
|
||||||
connection_handle_t connection
|
entry_handle_t db_entry
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return immediately security entry containing the state
|
* Set the distribution flags of the DB entry
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
virtual SecurityEntry_t* get_entry(
|
virtual void set_distribution_flags(
|
||||||
const address_t &peer_address
|
entry_handle_t db_entry,
|
||||||
|
const SecurityDistributionFlags_t& flags
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/* local keys */
|
/* local keys */
|
||||||
|
@ -174,7 +121,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void get_entry_local_keys(
|
virtual void get_entry_local_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) = 0;
|
) = 0;
|
||||||
|
@ -187,7 +134,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void get_entry_local_keys(
|
virtual void get_entry_local_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
connection_handle_t connection
|
entry_handle_t db_entry
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,7 +145,7 @@ public:
|
||||||
* be used when link is encrypted
|
* be used when link is encrypted
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_local_ltk(
|
virtual void set_entry_local_ltk(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
|
@ -210,7 +157,7 @@ public:
|
||||||
* @param[in] rand new RAND value
|
* @param[in] rand new RAND value
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_local_ediv_rand(
|
virtual void set_entry_local_ediv_rand(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) = 0;
|
) = 0;
|
||||||
|
@ -226,7 +173,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void get_entry_peer_csrk(
|
virtual void get_entry_peer_csrk(
|
||||||
SecurityEntryCsrkDbCb_t cb,
|
SecurityEntryCsrkDbCb_t cb,
|
||||||
connection_handle_t connection
|
entry_handle_t db_entry
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,7 +185,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void get_entry_peer_keys(
|
virtual void get_entry_peer_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
connection_handle_t connection
|
entry_handle_t db_entry
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,7 +196,7 @@ public:
|
||||||
* be used when link is encrypted
|
* be used when link is encrypted
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_peer_ltk(
|
virtual void set_entry_peer_ltk(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
|
@ -261,7 +208,7 @@ public:
|
||||||
* @param[in] rand new RAND value
|
* @param[in] rand new RAND value
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_peer_ediv_rand(
|
virtual void set_entry_peer_ediv_rand(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) = 0;
|
) = 0;
|
||||||
|
@ -273,7 +220,7 @@ public:
|
||||||
* @param[in] irk new IRK value
|
* @param[in] irk new IRK value
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_peer_irk(
|
virtual void set_entry_peer_irk(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const irk_t &irk
|
const irk_t &irk
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
|
@ -285,7 +232,7 @@ public:
|
||||||
* @param[in] peer_address the new address
|
* @param[in] peer_address the new address
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_peer_bdaddr(
|
virtual void set_entry_peer_bdaddr(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
bool address_is_public,
|
bool address_is_public,
|
||||||
const address_t &peer_address
|
const address_t &peer_address
|
||||||
) = 0;
|
) = 0;
|
||||||
|
@ -297,7 +244,7 @@ public:
|
||||||
* @param[in] csrk new CSRK value
|
* @param[in] csrk new CSRK value
|
||||||
*/
|
*/
|
||||||
virtual void set_entry_peer_csrk(
|
virtual void set_entry_peer_csrk(
|
||||||
connection_handle_t connection,
|
entry_handle_t db_entry,
|
||||||
const csrk_t &csrk
|
const csrk_t &csrk
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
|
@ -315,9 +262,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param[in] csrk new CSRK value
|
* @param[in] csrk new CSRK value
|
||||||
*/
|
*/
|
||||||
virtual void set_local_csrk(
|
virtual void set_local_csrk(const csrk_t &csrk) = 0;
|
||||||
const csrk_t &csrk
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/* public keys */
|
/* public keys */
|
||||||
|
|
||||||
|
@ -346,118 +291,38 @@ public:
|
||||||
const public_key_t &public_key_y
|
const public_key_t &public_key_y
|
||||||
) = 0;
|
) = 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 */
|
/* list management */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new entry or retrieve existing stored entry
|
* Open a database entry.
|
||||||
* and put it in the live connections store to be retrieved
|
*
|
||||||
* synchronously through connection handle.
|
* 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_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(
|
virtual entry_handle_t open_entry(
|
||||||
connection_handle_t connection,
|
|
||||||
BLEProtocol::AddressType_t peer_address_type,
|
BLEProtocol::AddressType_t peer_address_type,
|
||||||
const address_t &peer_address,
|
const address_t &peer_address
|
||||||
const address_t &local_address
|
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new entry or retrieve existing stored entry
|
* Close a connection entry.
|
||||||
* and put it in the live connections store to be retrieved
|
|
||||||
* synchronously through connection handle.
|
|
||||||
*
|
*
|
||||||
* @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(
|
virtual void close_entry(entry_handle_t db_entry) = 0;
|
||||||
connection_handle_t connection
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove entry for this peer from NVM.
|
* Remove entry for this peer from NVM.
|
||||||
*
|
*
|
||||||
* @param[in] peer_identity_address peer address that no longer needs NVM storage.
|
* @param[in] peer_identity_address peer address that no longer needs NVM storage.
|
||||||
*/
|
*/
|
||||||
virtual void remove_entry(
|
virtual void remove_entry(const address_t peer_identity_address) = 0;
|
||||||
const address_t peer_identity_address
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all entries from the security DB.
|
* Remove all entries from the security DB.
|
||||||
|
@ -495,27 +360,21 @@ public:
|
||||||
*
|
*
|
||||||
* @param[in] whitelist
|
* @param[in] whitelist
|
||||||
*/
|
*/
|
||||||
virtual void set_whitelist(
|
virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) = 0;
|
||||||
const ::Gap::Whitelist_t &whitelist
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new entry to the whitelist in the NVM.
|
* Add a new entry to the whitelist in the NVM.
|
||||||
*
|
*
|
||||||
* @param[in] address new whitelist entry
|
* @param[in] address new whitelist entry
|
||||||
*/
|
*/
|
||||||
virtual void add_whitelist_entry(
|
virtual void add_whitelist_entry(const address_t &address) = 0;
|
||||||
const address_t &address
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove whitelist entry from NVM.
|
* Remove whitelist entry from NVM.
|
||||||
*
|
*
|
||||||
* @param[in] address entry to be removed
|
* @param[in] address entry to be removed
|
||||||
*/
|
*/
|
||||||
virtual void remove_whitelist_entry(
|
virtual void remove_whitelist_entry(const address_t &address) = 0;
|
||||||
const address_t &address
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Remove all whitelist entries stored in the NVM.
|
*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) {
|
ble_error_t GenericSecurityManager::requestPairing(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,15 +113,15 @@ ble_error_t GenericSecurityManager::requestPairing(connection_handle_t connectio
|
||||||
update_oob_presence(connection);
|
update_oob_presence(connection);
|
||||||
|
|
||||||
AuthenticationMask link_authentication(_default_authentication);
|
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);
|
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);
|
link_key_distribution.set_encryption(_master_sends_keys);
|
||||||
|
|
||||||
return _pal.send_pairing_request(
|
return _pal.send_pairing_request(
|
||||||
connection,
|
connection,
|
||||||
entry->oob_present,
|
cb->oob_present,
|
||||||
link_authentication,
|
link_authentication,
|
||||||
link_key_distribution,
|
link_key_distribution,
|
||||||
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) {
|
ble_error_t GenericSecurityManager::acceptPairingRequest(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_oob_presence(connection);
|
update_oob_presence(connection);
|
||||||
|
|
||||||
AuthenticationMask link_authentication(_default_authentication);
|
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);
|
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(
|
return _pal.send_pairing_response(
|
||||||
connection,
|
connection,
|
||||||
entry->oob_present,
|
cb->oob_present,
|
||||||
link_authentication,
|
link_authentication,
|
||||||
link_key_distribution,
|
link_key_distribution,
|
||||||
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);
|
return _pal.cancel_pairing(connection, pairing_failure_t::UNSPECIFIED_REASON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,12 +206,12 @@ ble_error_t GenericSecurityManager::setLinkSecurity(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
SecurityMode_t securityMode
|
SecurityMode_t securityMode
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->encryption_requested) {
|
if (cb->encryption_requested) {
|
||||||
return BLE_ERROR_OPERATION_NOT_PERMITTED;
|
return BLE_ERROR_OPERATION_NOT_PERMITTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,19 +245,19 @@ ble_error_t GenericSecurityManager::enableSigning(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
bool enabled
|
bool enabled
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->signing_requested = enabled;
|
cb->signing_requested = enabled;
|
||||||
|
|
||||||
if (entry->encrypted) {
|
if (cb->encrypted) {
|
||||||
return BLE_ERROR_INVALID_STATE;
|
return BLE_ERROR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
if (!entry->csrk_stored && entry->signing_requested) {
|
if (!cb->csrk_stored && cb->signing_requested) {
|
||||||
init_signing();
|
init_signing();
|
||||||
if (entry->is_master) {
|
if (cb->is_master) {
|
||||||
return requestPairing(connection);
|
return requestPairing(connection);
|
||||||
} else {
|
} else {
|
||||||
return slave_security_request(connection);
|
return slave_security_request(connection);
|
||||||
|
@ -281,18 +281,18 @@ ble_error_t GenericSecurityManager::getLinkEncryption(
|
||||||
link_encryption_t *encryption
|
link_encryption_t *encryption
|
||||||
) {
|
) {
|
||||||
|
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->encrypted) {
|
if (cb->encrypted) {
|
||||||
if (entry->ltk_mitm_protected || entry->mitm_performed) {
|
if (cb->ltk_mitm_protected || cb->mitm_performed) {
|
||||||
*encryption = link_encryption_t::ENCRYPTED_WITH_MITM;
|
*encryption = link_encryption_t::ENCRYPTED_WITH_MITM;
|
||||||
} else {
|
} else {
|
||||||
*encryption = link_encryption_t::ENCRYPTED;
|
*encryption = link_encryption_t::ENCRYPTED;
|
||||||
}
|
}
|
||||||
} else if (entry->encryption_requested) {
|
} else if (cb->encryption_requested) {
|
||||||
*encryption = link_encryption_t::ENCRYPTION_IN_PROGRESS;
|
*encryption = link_encryption_t::ENCRYPTION_IN_PROGRESS;
|
||||||
} else {
|
} else {
|
||||||
*encryption = link_encryption_t::NOT_ENCRYPTED;
|
*encryption = link_encryption_t::NOT_ENCRYPTED;
|
||||||
|
@ -305,8 +305,8 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
link_encryption_t encryption
|
link_encryption_t encryption
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
|
||||||
|
|
||||||
if (encryption == link_encryption_t::NOT_ENCRYPTED) {
|
if (encryption == link_encryption_t::NOT_ENCRYPTED) {
|
||||||
|
|
||||||
if (entry->encrypted) {
|
if (cb->encrypted) {
|
||||||
return _pal.disable_encryption(connection);
|
return _pal.disable_encryption(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,16 +334,16 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
|
||||||
if (current_encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
if (current_encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
entry->encryption_requested = true;
|
cb->encryption_requested = true;
|
||||||
return enable_encryption(connection);
|
return enable_encryption(connection);
|
||||||
|
|
||||||
} else if (encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
} else if (encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
||||||
|
|
||||||
if (entry->ltk_mitm_protected && !entry->encrypted) {
|
if (cb->ltk_mitm_protected && !cb->encrypted) {
|
||||||
entry->encryption_requested = true;
|
cb->encryption_requested = true;
|
||||||
return enable_encryption(connection);
|
return enable_encryption(connection);
|
||||||
} else {
|
} else {
|
||||||
entry->encryption_requested = true;
|
cb->encryption_requested = true;
|
||||||
return requestAuthentication(connection);
|
return requestAuthentication(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +358,9 @@ ble_error_t GenericSecurityManager::getEncryptionKeySize(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
uint8_t *size
|
uint8_t *size
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (entry) {
|
if (cb) {
|
||||||
*size = entry->encryption_key_size;
|
*size = cb->encryption_key_size;
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
} else {
|
} else {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
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) {
|
ble_error_t GenericSecurityManager::getSigningKey(connection_handle_t connection, bool authenticated) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
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
|
/* we have a key that is either authenticated or we don't care if it is
|
||||||
* so retrieve it from the db now */
|
* so retrieve it from the db now */
|
||||||
_db.get_entry_peer_csrk(
|
_db.get_entry_peer_csrk(
|
||||||
mbed::callback(this, &GenericSecurityManager::return_csrk_cb),
|
mbed::callback(this, &GenericSecurityManager::return_csrk_cb),
|
||||||
connection
|
cb->db_entry
|
||||||
);
|
);
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ ble_error_t GenericSecurityManager::getSigningKey(connection_handle_t connection
|
||||||
* keys exchange will create the signingKey event */
|
* keys exchange will create the signingKey event */
|
||||||
if (authenticated) {
|
if (authenticated) {
|
||||||
return requestAuthentication(connection);
|
return requestAuthentication(connection);
|
||||||
} else if (entry->is_master) {
|
} else if (cb->is_master) {
|
||||||
return requestPairing(connection);
|
return requestPairing(connection);
|
||||||
} else {
|
} else {
|
||||||
return slave_security_request(connection);
|
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) {
|
ble_error_t GenericSecurityManager::requestAuthentication(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->ltk_mitm_protected) {
|
if (cb->ltk_mitm_protected) {
|
||||||
if (entry->authenticated) {
|
if (cb->authenticated) {
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
} else {
|
} else {
|
||||||
entry->encryption_requested = true;
|
cb->encryption_requested = true;
|
||||||
return enable_encryption(connection);
|
return enable_encryption(connection);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
entry->mitm_requested = true;
|
cb->mitm_requested = true;
|
||||||
if (entry->is_master) {
|
if (cb->is_master) {
|
||||||
return requestPairing(connection);
|
return requestPairing(connection);
|
||||||
} else {
|
} else {
|
||||||
return slave_security_request(connection);
|
return slave_security_request(connection);
|
||||||
|
@ -450,13 +450,13 @@ ble_error_t GenericSecurityManager::setOOBDataUsage(
|
||||||
bool useOOB,
|
bool useOOB,
|
||||||
bool OOBProvidesMITM
|
bool OOBProvidesMITM
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->attempt_oob = useOOB;
|
cb->attempt_oob = useOOB;
|
||||||
entry->oob_mitm_protection = OOBProvidesMITM;
|
cb->oob_mitm_protection = OOBProvidesMITM;
|
||||||
|
|
||||||
#if defined(MBEDTLS_CMAC_C)
|
#if defined(MBEDTLS_CMAC_C)
|
||||||
if (_public_keys_generated) {
|
if (_public_keys_generated) {
|
||||||
|
@ -496,12 +496,12 @@ ble_error_t GenericSecurityManager::legacyPairingOobReceived(
|
||||||
const oob_tk_t *tk
|
const oob_tk_t *tk
|
||||||
) {
|
) {
|
||||||
if (address && tk) {
|
if (address && tk) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(*address);
|
ControlBlock_t *cb = get_control_block(*address);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
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;
|
return BLE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -512,12 +512,9 @@ ble_error_t GenericSecurityManager::oobReceived(
|
||||||
const oob_confirm_t *confirm
|
const oob_confirm_t *confirm
|
||||||
) {
|
) {
|
||||||
if (address && random && confirm) {
|
if (address && random && confirm) {
|
||||||
_db.set_peer_sc_oob_data(
|
_peer_sc_oob_address = *address;
|
||||||
*address,
|
_peer_sc_oob_random = *random;
|
||||||
*random,
|
_peer_sc_oob_confirm = *confirm;
|
||||||
*confirm
|
|
||||||
);
|
|
||||||
|
|
||||||
return BLE_ERROR_NONE;
|
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) {
|
ble_error_t GenericSecurityManager::slave_security_request(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
AuthenticationMask link_authentication(_default_authentication);
|
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);
|
return _pal.slave_security_request(connection, link_authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connection) {
|
ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return BLE_ERROR_INVALID_PARAM;
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
if (entry->is_master) {
|
if (cb->is_master) {
|
||||||
if (entry->ltk_stored) {
|
if (cb->ltk_stored) {
|
||||||
_db.get_entry_peer_keys(
|
_db.get_entry_peer_keys(
|
||||||
mbed::callback(this, &GenericSecurityManager::enable_encryption_cb),
|
mbed::callback(this, &GenericSecurityManager::enable_encryption_cb),
|
||||||
connection
|
cb->db_entry
|
||||||
);
|
);
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -594,44 +591,48 @@ ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connec
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericSecurityManager::enable_encryption_cb(
|
void GenericSecurityManager::enable_encryption_cb(
|
||||||
const SecurityEntry_t* entry,
|
pal::SecurityDb::entry_handle_t db_entry,
|
||||||
const SecurityEntryKeys_t* entryKeys
|
const SecurityEntryKeys_t* entryKeys
|
||||||
) {
|
) {
|
||||||
if (entry && entryKeys) {
|
ControlBlock_t *cb = get_control_block(db_entry);
|
||||||
if (entry->secure_connections_paired) {
|
|
||||||
_pal.enable_encryption(entry->handle, entryKeys->ltk);
|
if (cb && entryKeys) {
|
||||||
|
if (cb->secure_connections_paired) {
|
||||||
|
_pal.enable_encryption(cb->connection, entryKeys->ltk);
|
||||||
} else {
|
} 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(
|
void GenericSecurityManager::set_ltk_cb(
|
||||||
const SecurityEntry_t* entry,
|
pal::SecurityDb::entry_handle_t db_entry,
|
||||||
const SecurityEntryKeys_t* entryKeys
|
const SecurityEntryKeys_t* entryKeys
|
||||||
) {
|
) {
|
||||||
if (entry) {
|
ControlBlock_t *cb = get_control_block(db_entry);
|
||||||
|
|
||||||
|
if (cb) {
|
||||||
if (entryKeys) {
|
if (entryKeys) {
|
||||||
_pal.set_ltk(entry->handle, entryKeys->ltk);
|
_pal.set_ltk(cb->connection, entryKeys->ltk);
|
||||||
} else {
|
} else {
|
||||||
_pal.set_ltk_not_found(entry->handle);
|
_pal.set_ltk_not_found(cb->connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericSecurityManager::return_csrk_cb(
|
void GenericSecurityManager::return_csrk_cb(
|
||||||
connection_handle_t connection,
|
pal::SecurityDb::entry_handle_t db_entry,
|
||||||
const csrk_t *csrk
|
const csrk_t *csrk
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(db_entry);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eventHandler->signingKey(
|
eventHandler->signingKey(
|
||||||
connection,
|
cb->connection,
|
||||||
csrk,
|
csrk,
|
||||||
entry->csrk_mitm_protected
|
cb->csrk_mitm_protected
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,8 +643,8 @@ void GenericSecurityManager::generate_secure_connections_oob(
|
||||||
oob_confirm_t confirm;
|
oob_confirm_t confirm;
|
||||||
oob_rand_t random;
|
oob_rand_t random;
|
||||||
|
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,31 +661,31 @@ void GenericSecurityManager::generate_secure_connections_oob(
|
||||||
);
|
);
|
||||||
|
|
||||||
eventHandler->oobGenerated(
|
eventHandler->oobGenerated(
|
||||||
&entry->local_address,
|
&cb->local_address,
|
||||||
&random,
|
&random,
|
||||||
&confirm
|
&confirm
|
||||||
);
|
);
|
||||||
|
|
||||||
_db.set_local_sc_oob_random(random);
|
_local_sc_oob_random = random;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void GenericSecurityManager::update_oob_presence(connection_handle_t connection) {
|
void GenericSecurityManager::update_oob_presence(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only update the oob state if we support secure connections,
|
/* only update the oob state if we support secure connections,
|
||||||
* otherwise follow the user set preference for providing legacy
|
* otherwise follow the user set preference for providing legacy
|
||||||
* pairing oob data */
|
* pairing oob data */
|
||||||
entry->oob_present = entry->attempt_oob;
|
cb->oob_present = cb->attempt_oob;
|
||||||
|
|
||||||
if (_default_authentication.get_secure_connections()) {
|
if (_default_authentication.get_secure_connections()) {
|
||||||
entry->oob_present = false;
|
cb->oob_present = false;
|
||||||
#if defined(MBEDTLS_CMAC_C)
|
#if defined(MBEDTLS_CMAC_C)
|
||||||
if (entry->peer_address == _db.get_peer_sc_oob_address()) {
|
if (cb->peer_address == _peer_sc_oob_address) {
|
||||||
entry->oob_present = true;
|
cb->oob_present = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -721,9 +722,9 @@ bool GenericSecurityManager::crypto_toolbox_f4(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void GenericSecurityManager::set_mitm_performed(connection_handle_t connection, bool enable) {
|
void GenericSecurityManager::set_mitm_performed(connection_handle_t connection, bool enable) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (entry) {
|
if (cb) {
|
||||||
entry->mitm_performed = true;
|
cb->mitm_performed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,33 +737,41 @@ void GenericSecurityManager::on_connected(
|
||||||
const BLEProtocol::AddressBytes_t local_address,
|
const BLEProtocol::AddressBytes_t local_address,
|
||||||
const Gap::ConnectionParams_t *connection_params
|
const Gap::ConnectionParams_t *connection_params
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.connect_entry(
|
ControlBlock_t *cb = acquire_control_block(connection);
|
||||||
connection,
|
if (!cb) {
|
||||||
peer_address_type,
|
|
||||||
address_t(peer_address),
|
|
||||||
address_t(local_address)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!entry) {
|
|
||||||
return;
|
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);
|
// get the associated db handle and the distribution flags if any
|
||||||
entry->handle = connection;
|
cb->db_entry = _db.open_entry(peer_address_type, peer_address);
|
||||||
entry->connected = true;
|
|
||||||
|
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(
|
void GenericSecurityManager::on_disconnected(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
Gap::DisconnectionReason_t reason
|
Gap::DisconnectionReason_t reason
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entry->connected = false;
|
|
||||||
|
_db.close_entry(cb->db_entry);
|
||||||
|
release_control_block(cb);
|
||||||
|
|
||||||
_db.sync();
|
_db.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +790,7 @@ void GenericSecurityManager::on_pairing_request(
|
||||||
) {
|
) {
|
||||||
/* cancel pairing if secure connection paring is not possible */
|
/* cancel pairing if secure connection paring is not possible */
|
||||||
if (!_legacy_pairing_allowed && !authentication.get_secure_connections()) {
|
if (!_legacy_pairing_allowed && !authentication.get_secure_connections()) {
|
||||||
canceltPairingRequest(connection);
|
cancelPairingRequest(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_mitm_performed(connection, false);
|
set_mitm_performed(connection, false);
|
||||||
|
@ -804,8 +813,8 @@ void GenericSecurityManager::on_pairing_error(
|
||||||
|
|
||||||
/* if this pairing was triggered by a failed encryption attempt
|
/* if this pairing was triggered by a failed encryption attempt
|
||||||
* inform the application of the encryption failure */
|
* inform the application of the encryption failure */
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (entry && entry->encryption_requested && entry->encryption_failed) {
|
if (cb && cb->encryption_requested && cb->encryption_failed) {
|
||||||
eventHandler->linkEncryptionResult(
|
eventHandler->linkEncryptionResult(
|
||||||
connection,
|
connection,
|
||||||
link_encryption_t::NOT_ENCRYPTED
|
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) {
|
void GenericSecurityManager::on_pairing_completed(connection_handle_t connection) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (entry) {
|
if (cb) {
|
||||||
if (entry->encryption_requested) {
|
if (cb->encryption_requested) {
|
||||||
enable_encryption(connection);
|
enable_encryption(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sc doesn't need to exchange ltk */
|
/* sc doesn't need to exchange ltk */
|
||||||
if (entry->secure_connections_paired) {
|
if (cb->secure_connections_paired) {
|
||||||
entry->ltk_mitm_protected = entry->mitm_performed;
|
cb->ltk_mitm_protected = cb->mitm_performed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the distribution flags in the db
|
||||||
|
_db.set_distribution_flags(cb->db_entry, *cb);
|
||||||
|
|
||||||
eventHandler->pairingResult(
|
eventHandler->pairingResult(
|
||||||
connection,
|
connection,
|
||||||
SecurityManager::SEC_STATUS_SUCCESS
|
SecurityManager::SEC_STATUS_SUCCESS
|
||||||
|
@ -853,20 +865,20 @@ void GenericSecurityManager::on_slave_security_request(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
AuthenticationMask authentication
|
AuthenticationMask authentication
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authentication.get_secure_connections()
|
if (authentication.get_secure_connections()
|
||||||
&& _default_authentication.get_secure_connections()
|
&& _default_authentication.get_secure_connections()
|
||||||
&& !entry->secure_connections_paired) {
|
&& !cb->secure_connections_paired) {
|
||||||
requestPairing(connection);
|
requestPairing(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authentication.get_mitm()
|
if (authentication.get_mitm()
|
||||||
&& !entry->ltk_mitm_protected) {
|
&& !cb->ltk_mitm_protected) {
|
||||||
entry->mitm_requested = true;
|
cb->mitm_requested = true;
|
||||||
requestPairing(connection);
|
requestPairing(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -880,30 +892,30 @@ void GenericSecurityManager::on_link_encryption_result(
|
||||||
link_encryption_t result
|
link_encryption_t result
|
||||||
) {
|
) {
|
||||||
|
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == link_encryption_t::ENCRYPTED) {
|
if (result == link_encryption_t::ENCRYPTED) {
|
||||||
|
|
||||||
entry->encryption_requested = false;
|
cb->encryption_requested = false;
|
||||||
entry->encryption_failed = false;
|
cb->encryption_failed = false;
|
||||||
|
|
||||||
} else if (result == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
} else if (result == link_encryption_t::ENCRYPTED_WITH_MITM) {
|
||||||
|
|
||||||
entry->encryption_requested = false;
|
cb->encryption_requested = false;
|
||||||
entry->encryption_failed = false;
|
cb->encryption_failed = false;
|
||||||
entry->authenticated = true;
|
cb->authenticated = true;
|
||||||
|
|
||||||
} else if (result == link_encryption_t::NOT_ENCRYPTED
|
} else if (result == link_encryption_t::NOT_ENCRYPTED
|
||||||
&& entry->encryption_requested
|
&& cb->encryption_requested
|
||||||
&& !entry->encryption_failed) {
|
&& !cb->encryption_failed) {
|
||||||
|
|
||||||
/* if we failed encryption for the first time
|
/* if we failed encryption for the first time
|
||||||
* retry repairing in case slave lost LTK */
|
* retry repairing in case slave lost LTK */
|
||||||
requestPairing(entry->handle);
|
requestPairing(cb->connection);
|
||||||
entry->encryption_failed = true;
|
cb->encryption_failed = true;
|
||||||
/* don't return an event yet since we are retrying */
|
/* don't return an event yet since we are retrying */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -961,31 +973,20 @@ void GenericSecurityManager::on_oob_data_verification_request(
|
||||||
const public_key_t &peer_public_key_y
|
const public_key_t &peer_public_key_y
|
||||||
) {
|
) {
|
||||||
#if defined(MBEDTLS_CMAC_C)
|
#if defined(MBEDTLS_CMAC_C)
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
|
|
||||||
oob_confirm_t confirm_verify;
|
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(
|
crypto_toolbox_f4(
|
||||||
peer_public_key_x,
|
peer_public_key_x,
|
||||||
peer_public_key_y,
|
peer_public_key_y,
|
||||||
peer_oob_random,
|
_peer_oob_random,
|
||||||
confirm_verify
|
confirm_verify
|
||||||
);
|
);
|
||||||
|
|
||||||
if (entry && (entry->peer_address == peer_oob_address)
|
if (cb && (cb->peer_address == _peer_oob_address)
|
||||||
&& (confirm_verify == peer_oob_confirm)) {
|
&& (confirm_verify == _peer_oob_confirm)) {
|
||||||
_pal.oob_data_verified(connection, local_oob_random, peer_oob_random);
|
_pal.oob_data_verified(connection, _local_oob_random, _peer_oob_random);
|
||||||
} else {
|
} else {
|
||||||
_pal.cancel_pairing(connection, pairing_failure_t::CONFIRM_VALUE_FAILED);
|
_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,
|
connection_handle_t connection,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->ltk_mitm_protected = entry->mitm_performed;
|
cb->ltk_mitm_protected = cb->mitm_performed;
|
||||||
entry->secure_connections_paired = true;
|
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(
|
void GenericSecurityManager::on_keys_distributed_ltk(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entry->ltk_mitm_protected = entry->mitm_performed;
|
cb->ltk_mitm_protected = cb->mitm_performed;
|
||||||
_db.set_entry_peer_ltk(connection, ltk);
|
_db.set_entry_peer_ltk(cb->db_entry, ltk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericSecurityManager::on_keys_distributed_ediv_rand(
|
void GenericSecurityManager::on_keys_distributed_ediv_rand(
|
||||||
|
@ -1036,14 +1037,24 @@ void GenericSecurityManager::on_keys_distributed_ediv_rand(
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
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(
|
void GenericSecurityManager::on_keys_distributed_local_ltk(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
const ltk_t <k
|
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(
|
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 ediv_t &ediv,
|
||||||
const rand_t &rand
|
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(
|
void GenericSecurityManager::on_keys_distributed_irk(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
const irk_t &irk
|
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(
|
void GenericSecurityManager::on_keys_distributed_bdaddr(
|
||||||
|
@ -1066,8 +1087,13 @@ void GenericSecurityManager::on_keys_distributed_bdaddr(
|
||||||
advertising_peer_address_type_t peer_address_type,
|
advertising_peer_address_type_t peer_address_type,
|
||||||
const address_t &peer_identity_address
|
const address_t &peer_identity_address
|
||||||
) {
|
) {
|
||||||
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
|
if (!cb) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_db.set_entry_peer_bdaddr(
|
_db.set_entry_peer_bdaddr(
|
||||||
connection,
|
cb->db_entry,
|
||||||
(peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS),
|
(peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS),
|
||||||
peer_identity_address
|
peer_identity_address
|
||||||
);
|
);
|
||||||
|
@ -1077,19 +1103,19 @@ void GenericSecurityManager::on_keys_distributed_csrk(
|
||||||
connection_handle_t connection,
|
connection_handle_t connection,
|
||||||
const csrk_t &csrk
|
const csrk_t &csrk
|
||||||
) {
|
) {
|
||||||
SecurityEntry_t *entry = _db.get_entry(connection);
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
if (!entry) {
|
if (!cb) {
|
||||||
return;
|
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(
|
eventHandler->signingKey(
|
||||||
connection,
|
connection,
|
||||||
&csrk,
|
&csrk,
|
||||||
entry->csrk_mitm_protected
|
cb->csrk_mitm_protected
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,22 +1124,111 @@ void GenericSecurityManager::on_ltk_request(
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) {
|
) {
|
||||||
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
|
if (!cb) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_db.get_entry_local_keys(
|
_db.get_entry_local_keys(
|
||||||
mbed::callback(this, &GenericSecurityManager::set_ltk_cb),
|
mbed::callback(this, &GenericSecurityManager::set_ltk_cb),
|
||||||
connection,
|
cb->db_entry,
|
||||||
ediv,
|
ediv,
|
||||||
rand
|
rand
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericSecurityManager::on_ltk_request(
|
/* control blocks list management */
|
||||||
connection_handle_t connection
|
|
||||||
) {
|
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(
|
_db.get_entry_local_keys(
|
||||||
mbed::callback(this, &GenericSecurityManager::set_ltk_cb),
|
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 generic */
|
||||||
} /* namespace ble */
|
} /* namespace ble */
|
||||||
|
|
|
@ -94,6 +94,8 @@ add_executable(security-manager-tests
|
||||||
mbed_os_stub/mbed_assert.c
|
mbed_os_stub/mbed_assert.c
|
||||||
generic/SecurityManager/mock/MockPalSecurityManager.cpp
|
generic/SecurityManager/mock/MockPalSecurityManager.cpp
|
||||||
generic/SecurityManager/mock/MockPalSecurityDb.cpp
|
generic/SecurityManager/mock/MockPalSecurityDb.cpp
|
||||||
|
generic/SecurityManager/mock/MockConnectionEventMonitor.cpp
|
||||||
|
generic/SecurityManager/mock/MockSecurityManagerEventHandler.cpp
|
||||||
${PROJECT_SOURCE_DIR}/../source/generic/GenericSecurityManager.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();
|
virtual ~MockPalSecurityDb();
|
||||||
|
|
||||||
MOCK_METHOD1(get_entry, SecurityEntry_t*(connection_handle_t));
|
MOCK_METHOD1(get_distribution_flags,
|
||||||
|
const SecurityDistributionFlags_t*(entry_handle_t db_entry));
|
||||||
MOCK_METHOD1(get_entry, SecurityEntry_t*(const address_t &));
|
MOCK_METHOD2(set_distribution_flags,
|
||||||
|
void(entry_handle_t db_entry, const SecurityDistributionFlags_t& flags));
|
||||||
MOCK_METHOD4(
|
MOCK_METHOD4(get_entry_local_keys,
|
||||||
get_entry_local_keys,
|
void(SecurityEntryKeysDbCb_t cb, entry_handle_t db_entry, const ediv_t &ediv, const rand_t &rand));
|
||||||
void(
|
MOCK_METHOD2(get_entry_local_keys,
|
||||||
SecurityEntryKeysDbCb_t,
|
void(SecurityEntryKeysDbCb_t cb, entry_handle_t db_entry));
|
||||||
connection_handle_t,
|
MOCK_METHOD2(set_entry_local_ltk,
|
||||||
const ediv_t &,
|
void(entry_handle_t db_entry, const ltk_t <k));
|
||||||
const rand_t &
|
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(
|
MOCK_METHOD2(get_entry_peer_keys,
|
||||||
get_entry_local_keys,
|
void(SecurityEntryKeysDbCb_t cb, entry_handle_t db_entry));
|
||||||
void(SecurityEntryKeysDbCb_t, connection_handle_t)
|
MOCK_METHOD2(set_entry_peer_ltk,
|
||||||
);
|
void(entry_handle_t db_entry, const ltk_t <k));
|
||||||
|
MOCK_METHOD3(set_entry_peer_ediv_rand,
|
||||||
MOCK_METHOD2(
|
void(entry_handle_t db_entry, const ediv_t &ediv, const rand_t &rand));
|
||||||
set_entry_local_ltk,
|
MOCK_METHOD2(set_entry_peer_irk,
|
||||||
void(connection_handle_t, const ltk_t &)
|
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_METHOD3(
|
MOCK_METHOD2(set_entry_peer_csrk,
|
||||||
set_entry_local_ediv_rand,
|
void(entry_handle_t db_entry, const csrk_t &csrk));
|
||||||
void(connection_handle_t, const ediv_t &, const rand_t &)
|
MOCK_METHOD0(get_local_csrk,
|
||||||
);
|
const csrk_t*());
|
||||||
|
MOCK_METHOD1(set_local_csrk,
|
||||||
MOCK_METHOD2(
|
void(const csrk_t &csrk));
|
||||||
get_entry_peer_csrk,
|
MOCK_METHOD0(get_public_key_x,
|
||||||
void(SecurityEntryCsrkDbCb_t, connection_handle_t)
|
const public_key_t&());
|
||||||
);
|
MOCK_METHOD0(get_public_key_y,
|
||||||
|
const public_key_t&());
|
||||||
MOCK_METHOD2(
|
MOCK_METHOD2(set_public_key,
|
||||||
get_entry_peer_keys,
|
void(const public_key_t &public_key_x, const public_key_t &public_key_y));
|
||||||
void(SecurityEntryKeysDbCb_t, connection_handle_t)
|
MOCK_METHOD2(open_entry,
|
||||||
);
|
entry_handle_t(BLEProtocol::AddressType_t peer_address_type, const address_t &peer_address));
|
||||||
|
MOCK_METHOD1(close_entry,
|
||||||
MOCK_METHOD2(
|
void(entry_handle_t db_entry));
|
||||||
set_entry_peer_ltk,
|
MOCK_METHOD1(remove_entry,
|
||||||
void(connection_handle_t, const ltk_t &)
|
void(const address_t peer_identity_address));
|
||||||
);
|
MOCK_METHOD0(clear_entries,
|
||||||
|
void());
|
||||||
MOCK_METHOD3(
|
MOCK_METHOD2(get_whitelist,
|
||||||
set_entry_peer_ediv_rand,
|
void(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist));
|
||||||
void(connection_handle_t, const ediv_t &, const rand_t &)
|
MOCK_METHOD2(generate_whitelist_from_bond_table,
|
||||||
);
|
void(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist));
|
||||||
|
MOCK_METHOD1(set_whitelist,
|
||||||
MOCK_METHOD2(
|
void(const ::Gap::Whitelist_t &whitelist));
|
||||||
set_entry_peer_irk,
|
MOCK_METHOD1(add_whitelist_entry,
|
||||||
void(connection_handle_t, const irk_t &)
|
void(const address_t &address));
|
||||||
);
|
MOCK_METHOD1(remove_whitelist_entry,
|
||||||
|
void(const address_t &address));
|
||||||
MOCK_METHOD3(
|
MOCK_METHOD0(clear_whitelist,
|
||||||
set_entry_peer_bdaddr,
|
void());
|
||||||
void(connection_handle_t, bool, const address_t &)
|
MOCK_METHOD0(restore,
|
||||||
);
|
void());
|
||||||
|
MOCK_METHOD0(sync,
|
||||||
MOCK_METHOD2(
|
void());
|
||||||
set_entry_peer_csrk,
|
MOCK_METHOD1(set_restore,
|
||||||
void(connection_handle_t, const csrk_t &)
|
void(bool reload));
|
||||||
);
|
|
||||||
|
|
||||||
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));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ble
|
} // 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