mirror of https://github.com/ARMmbed/mbed-os.git
BLE: Move traces out of header file to avoid collisions.
This change required the creation of the implementation files of SecurityDb classes.pull/14198/head
parent
6adaefd9f3
commit
957486e0eb
|
|
@ -27,6 +27,8 @@
|
|||
#include "att_api.h"
|
||||
#include "att_defs.h"
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
|
||||
#define TRACE_GROUP "BLAT"
|
||||
|
||||
namespace ble {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,14 @@ FileSecurityDb::~FileSecurityDb()
|
|||
fclose(_db_file);
|
||||
}
|
||||
|
||||
FileSecurityDb::entry_t* FileSecurityDb::as_entry(entry_handle_t db_handle) {
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
|
||||
if (!entry) {
|
||||
tr_error("Invalid security DB handle used");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
FILE* FileSecurityDb::open_db_file(const char *db_path)
|
||||
{
|
||||
if (!db_path) {
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "SecurityDb.h"
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
|
||||
#define TRACE_GROUP "BLDB"
|
||||
|
||||
namespace ble {
|
||||
|
||||
|
|
@ -40,13 +37,7 @@ private:
|
|||
size_t file_offset;
|
||||
};
|
||||
|
||||
static entry_t* as_entry(entry_handle_t db_handle) {
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
|
||||
if (!entry) {
|
||||
tr_error("Invalid security DB handle used");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
static entry_t* as_entry(entry_handle_t db_handle);
|
||||
|
||||
template<class T>
|
||||
void db_read(T *value, long int offset) {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,14 @@ KVStoreSecurityDb::~KVStoreSecurityDb()
|
|||
{
|
||||
}
|
||||
|
||||
KVStoreSecurityDb::entry_t *KVStoreSecurityDb::as_entry(entry_handle_t db_handle) {
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
|
||||
if (!entry) {
|
||||
tr_error("Invalid security DB handle used");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
bool KVStoreSecurityDb::open_db()
|
||||
{
|
||||
uint8_t version = 0;
|
||||
|
|
|
|||
|
|
@ -25,13 +25,10 @@
|
|||
#include "mbed_error.h"
|
||||
|
||||
#include "SecurityDb.h"
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
|
||||
#define STR_EXPAND(tok) #tok
|
||||
#define STR(tok) STR_EXPAND(tok)
|
||||
|
||||
#define TRACE_GROUP "BLDB"
|
||||
|
||||
namespace ble {
|
||||
|
||||
/** Filesystem implementation */
|
||||
|
|
@ -66,14 +63,6 @@ private:
|
|||
static constexpr char DB_VERSION[DB_KEY_SIZE] = { 'v','e','r' };
|
||||
static constexpr char DB_RESTORE[DB_KEY_SIZE] = { 'r','e','s' };
|
||||
|
||||
static entry_t* as_entry(entry_handle_t db_handle) {
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
|
||||
if (!entry) {
|
||||
tr_error("Invalid security DB handle used");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void db_read(T *value, const char* key) {
|
||||
char db_key[DB_FULL_KEY_SIZE];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,196 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2021 ARM Limited
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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 "MemorySecurityDb.h"
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
#include "common/ble_trace_helpers.h"
|
||||
|
||||
#define TRACE_GROUP "BLDB"
|
||||
|
||||
#define _STR(x) #x
|
||||
#define STR(x) _STR(x)
|
||||
|
||||
|
||||
namespace ble {
|
||||
|
||||
MemorySecurityDb::entry_t *MemorySecurityDb::as_entry(entry_handle_t db_handle)
|
||||
{
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
|
||||
if (!entry) {
|
||||
tr_error("Invalid security DB handle used");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
MemorySecurityDb::MemorySecurityDb() : SecurityDb()
|
||||
{
|
||||
tr_info("Using memory security DB (capacity " STR(BLE_SECURITY_DATABASE_MAX_ENTRIES) " entries) - no persistence across reset");
|
||||
}
|
||||
|
||||
|
||||
SecurityDistributionFlags_t *MemorySecurityDb::get_distribution_flags(
|
||||
entry_handle_t db_handle
|
||||
) {
|
||||
return reinterpret_cast<SecurityDistributionFlags_t*>(db_handle);
|
||||
}
|
||||
|
||||
/* local keys */
|
||||
|
||||
/* set */
|
||||
void MemorySecurityDb::set_entry_local_ltk(
|
||||
entry_handle_t db_handle,
|
||||
const ltk_t <k
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: local ltk %s", get_index(db_handle), to_string(ltk));
|
||||
entry->flags.ltk_sent = true;
|
||||
entry->local_keys.ltk = ltk;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_local_ediv_rand(
|
||||
entry_handle_t db_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: local ediv %s rand %s", get_index(db_handle), to_string(ediv), to_string(rand));
|
||||
entry->local_keys.ediv = ediv;
|
||||
entry->local_keys.rand = rand;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_peer_ltk(
|
||||
entry_handle_t db_handle,
|
||||
const ltk_t <k
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer ltk %s", get_index(db_handle), to_string(ltk));
|
||||
entry->peer_keys.ltk = ltk;
|
||||
entry->flags.ltk_stored = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_peer_ediv_rand(
|
||||
entry_handle_t db_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer ediv %s rand %s", get_index(db_handle), to_string(ediv), to_string(rand));
|
||||
entry->peer_keys.ediv = ediv;
|
||||
entry->peer_keys.rand = rand;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_peer_irk(
|
||||
entry_handle_t db_handle,
|
||||
const irk_t &irk
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer irk %s", get_index(db_handle), to_string(irk));
|
||||
entry->peer_identity.irk = irk;
|
||||
entry->flags.irk_stored = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_peer_bdaddr(
|
||||
entry_handle_t db_handle,
|
||||
bool address_is_public,
|
||||
const address_t &peer_address
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: %s peer address %s", get_index(db_handle), address_is_public? "public" : "private", to_string(peer_address));
|
||||
entry->peer_identity.identity_address = peer_address;
|
||||
entry->peer_identity.identity_address_is_public = address_is_public;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_peer_csrk(
|
||||
entry_handle_t db_handle,
|
||||
const csrk_t &csrk
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer csrk %s", get_index(db_handle), to_string(csrk));
|
||||
entry->flags.csrk_stored = true;
|
||||
entry->peer_signing.csrk = csrk;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::set_entry_peer_sign_counter(
|
||||
entry_handle_t db_handle,
|
||||
sign_count_t sign_counter
|
||||
) {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: sign counter %lu", get_index(db_handle), sign_counter);
|
||||
entry->peer_signing.counter = sign_counter;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t MemorySecurityDb::get_entry_count() {
|
||||
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
|
||||
}
|
||||
|
||||
SecurityDistributionFlags_t *MemorySecurityDb::get_entry_handle_by_index(uint8_t index) {
|
||||
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
|
||||
return &_entries[index].flags;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MemorySecurityDb::reset_entry(entry_handle_t db_entry) {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
*entry = entry_t();
|
||||
}
|
||||
|
||||
SecurityEntryIdentity_t *MemorySecurityDb::read_in_entry_peer_identity(entry_handle_t db_entry) {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->peer_identity;
|
||||
}
|
||||
|
||||
SecurityEntryKeys_t *MemorySecurityDb::read_in_entry_peer_keys(entry_handle_t db_entry) {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->peer_keys;
|
||||
}
|
||||
|
||||
SecurityEntryKeys_t *MemorySecurityDb::read_in_entry_local_keys(entry_handle_t db_entry) {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->local_keys;
|
||||
}
|
||||
|
||||
SecurityEntrySigning_t *MemorySecurityDb::read_in_entry_peer_signing(entry_handle_t db_entry) {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->peer_signing;
|
||||
}
|
||||
|
||||
uint8_t MemorySecurityDb::get_index(const entry_handle_t db_handle) const
|
||||
{
|
||||
return reinterpret_cast<entry_t*>(db_handle) - _entries;
|
||||
}
|
||||
|
||||
} /* namespace ble */
|
||||
|
|
@ -21,15 +21,6 @@
|
|||
|
||||
#include "SecurityDb.h"
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
#include "common/ble_trace_helpers.h"
|
||||
|
||||
#define TRACE_GROUP "BLDB"
|
||||
|
||||
#define _STR(x) #x
|
||||
#define STR(x) _STR(x)
|
||||
|
||||
|
||||
namespace ble {
|
||||
|
||||
/** Naive memory implementation for verification. */
|
||||
|
|
@ -44,28 +35,16 @@ private:
|
|||
SecurityEntrySigning_t peer_signing;
|
||||
};
|
||||
|
||||
static entry_t* as_entry(entry_handle_t db_handle)
|
||||
{
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
|
||||
if (!entry) {
|
||||
tr_error("Invalid security DB handle used");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
static entry_t *as_entry(entry_handle_t db_handle);
|
||||
|
||||
public:
|
||||
MemorySecurityDb() : SecurityDb()
|
||||
{
|
||||
tr_info("Using memory security DB (capacity " STR(BLE_SECURITY_DATABASE_MAX_ENTRIES) " entries) - no persistence across reset");
|
||||
}
|
||||
MemorySecurityDb();
|
||||
|
||||
~MemorySecurityDb() override = default;
|
||||
|
||||
SecurityDistributionFlags_t* get_distribution_flags(
|
||||
SecurityDistributionFlags_t *get_distribution_flags(
|
||||
entry_handle_t db_handle
|
||||
) override {
|
||||
return reinterpret_cast<SecurityDistributionFlags_t*>(db_handle);
|
||||
}
|
||||
) override;
|
||||
|
||||
/* local keys */
|
||||
|
||||
|
|
@ -73,27 +52,13 @@ public:
|
|||
void set_entry_local_ltk(
|
||||
entry_handle_t db_handle,
|
||||
const ltk_t <k
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: local ltk %s", get_index(db_handle), to_string(ltk));
|
||||
entry->flags.ltk_sent = true;
|
||||
entry->local_keys.ltk = ltk;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
void set_entry_local_ediv_rand(
|
||||
entry_handle_t db_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: local ediv %s rand %s", get_index(db_handle), to_string(ediv), to_string(rand));
|
||||
entry->local_keys.ediv = ediv;
|
||||
entry->local_keys.rand = rand;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
/* peer's keys */
|
||||
|
||||
|
|
@ -102,118 +67,51 @@ public:
|
|||
void set_entry_peer_ltk(
|
||||
entry_handle_t db_handle,
|
||||
const ltk_t <k
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer ltk %s", get_index(db_handle), to_string(ltk));
|
||||
entry->peer_keys.ltk = ltk;
|
||||
entry->flags.ltk_stored = true;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
void set_entry_peer_ediv_rand(
|
||||
entry_handle_t db_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer ediv %s rand %s", get_index(db_handle), to_string(ediv), to_string(rand));
|
||||
entry->peer_keys.ediv = ediv;
|
||||
entry->peer_keys.rand = rand;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
void set_entry_peer_irk(
|
||||
entry_handle_t db_handle,
|
||||
const irk_t &irk
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer irk %s", get_index(db_handle), to_string(irk));
|
||||
entry->peer_identity.irk = irk;
|
||||
entry->flags.irk_stored = true;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
void set_entry_peer_bdaddr(
|
||||
entry_handle_t db_handle,
|
||||
bool address_is_public,
|
||||
const address_t &peer_address
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: %s peer address %s", get_index(db_handle), address_is_public? "public" : "private", to_string(peer_address));
|
||||
entry->peer_identity.identity_address = peer_address;
|
||||
entry->peer_identity.identity_address_is_public = address_is_public;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
void set_entry_peer_csrk(
|
||||
entry_handle_t db_handle,
|
||||
const csrk_t &csrk
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: peer csrk %s", get_index(db_handle), to_string(csrk));
|
||||
entry->flags.csrk_stored = true;
|
||||
entry->peer_signing.csrk = csrk;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
void set_entry_peer_sign_counter(
|
||||
entry_handle_t db_handle,
|
||||
sign_count_t sign_counter
|
||||
) override {
|
||||
entry_t *entry = as_entry(db_handle);
|
||||
if (entry) {
|
||||
tr_info("Write DB entry %d: sign counter %lu", get_index(db_handle), sign_counter);
|
||||
entry->peer_signing.counter = sign_counter;
|
||||
}
|
||||
}
|
||||
) override;
|
||||
|
||||
private:
|
||||
uint8_t get_entry_count() override {
|
||||
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
|
||||
}
|
||||
uint8_t get_entry_count() override;
|
||||
|
||||
SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index) override {
|
||||
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
|
||||
return &_entries[index].flags;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
SecurityDistributionFlags_t *get_entry_handle_by_index(uint8_t index) override;
|
||||
|
||||
void reset_entry(entry_handle_t db_entry) override{
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
*entry = entry_t();
|
||||
}
|
||||
void reset_entry(entry_handle_t db_entry) override;
|
||||
|
||||
SecurityEntryIdentity_t* read_in_entry_peer_identity(entry_handle_t db_entry) override {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->peer_identity;
|
||||
};
|
||||
SecurityEntryIdentity_t *read_in_entry_peer_identity(entry_handle_t db_entry) override;
|
||||
|
||||
SecurityEntryKeys_t* read_in_entry_peer_keys(entry_handle_t db_entry) override {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->peer_keys;
|
||||
};
|
||||
SecurityEntryKeys_t *read_in_entry_peer_keys(entry_handle_t db_entry) override;
|
||||
|
||||
SecurityEntryKeys_t* read_in_entry_local_keys(entry_handle_t db_entry) override {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->local_keys;
|
||||
};
|
||||
SecurityEntryKeys_t *read_in_entry_local_keys(entry_handle_t db_entry) override;
|
||||
|
||||
SecurityEntrySigning_t* read_in_entry_peer_signing(entry_handle_t db_entry) override {
|
||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
||||
return &entry->peer_signing;
|
||||
};
|
||||
SecurityEntrySigning_t *read_in_entry_peer_signing(entry_handle_t db_entry) override;
|
||||
|
||||
uint8_t get_index(const entry_handle_t db_handle) const
|
||||
{
|
||||
return reinterpret_cast<entry_t*>(db_handle) - _entries;
|
||||
}
|
||||
uint8_t get_index(const entry_handle_t db_handle) const;
|
||||
|
||||
private:
|
||||
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,428 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2021 ARM Limited
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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 "SecurityDb.h"
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
#include "common/ble_trace_helpers.h"
|
||||
|
||||
#define TRACE_GROUP "BLDB"
|
||||
|
||||
namespace ble {
|
||||
|
||||
SecurityDb::SecurityDb() : _local_sign_counter(0) { };
|
||||
|
||||
void SecurityDb::set_distribution_flags(
|
||||
entry_handle_t db_handle,
|
||||
const SecurityDistributionFlags_t& new_flags
|
||||
)
|
||||
{
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
if (flags) {
|
||||
*flags = new_flags;
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityDb::get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
entry_handle_t* db_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
)
|
||||
{
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(*db_handle);
|
||||
/* validate we have the correct key */
|
||||
if (keys && ediv == keys->ediv && rand == keys->rand) {
|
||||
cb(*db_handle, keys);
|
||||
} else {
|
||||
// Maybe this isn't the correct entry, try to find one that matches
|
||||
entry_handle_t correct_handle = find_entry_by_peer_ediv_rand(ediv, rand);
|
||||
if (!correct_handle) {
|
||||
tr_warn("Failed to find ltk matching given ediv&rand");
|
||||
cb(*db_handle, NULL);
|
||||
return;
|
||||
}
|
||||
tr_warn("Found ltk matching given ediv&rand but it belonged to a different identity, update entry with new identity");
|
||||
// Note: keys should never be null as a matching entry has been retrieved
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(correct_handle);
|
||||
MBED_ASSERT(keys);
|
||||
|
||||
/* set flags connected */
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(correct_handle);
|
||||
flags->connected = true;
|
||||
|
||||
/* update peer address */
|
||||
SecurityDistributionFlags_t* old_flags = get_distribution_flags(*db_handle);
|
||||
flags->peer_address = old_flags->peer_address;
|
||||
flags->peer_address_is_public = old_flags->peer_address_is_public;
|
||||
|
||||
close_entry(*db_handle, false);
|
||||
*db_handle = correct_handle;
|
||||
cb(*db_handle, keys);
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityDb::get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
)
|
||||
{
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
/* validate we have the correct key */
|
||||
if (flags && keys && flags->secure_connections_paired) {
|
||||
cb(db_handle, keys);
|
||||
} else {
|
||||
cb(db_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityDb::get_entry_peer_csrk(
|
||||
SecurityEntrySigningDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
)
|
||||
{
|
||||
SecurityEntrySigning_t* signing = read_in_entry_peer_signing(db_handle);
|
||||
cb(db_handle, signing);
|
||||
}
|
||||
|
||||
void SecurityDb::get_entry_peer_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
)
|
||||
{
|
||||
SecurityEntryKeys_t* keys = read_in_entry_peer_keys(db_handle);
|
||||
cb(db_handle, keys);
|
||||
}
|
||||
|
||||
void SecurityDb::get_entry_identity(
|
||||
SecurityEntryIdentityDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
)
|
||||
{
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
if (flags && flags->irk_stored) {
|
||||
SecurityEntryIdentity_t* peer_identity = read_in_entry_peer_identity(db_handle);
|
||||
if (peer_identity) {
|
||||
cb(db_handle, peer_identity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* avoid duplicate else */
|
||||
cb(db_handle, NULL);
|
||||
}
|
||||
|
||||
void SecurityDb::get_identity_list(
|
||||
IdentitylistDbCb_t cb,
|
||||
Span<SecurityEntryIdentity_t>& identity_list
|
||||
)
|
||||
{
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < get_entry_count() && count < (size_t) identity_list.size(); ++i) {
|
||||
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
|
||||
if (flags && flags->irk_stored) {
|
||||
SecurityEntryIdentity_t* peer_identity = read_in_entry_peer_identity(db_handle);
|
||||
if (peer_identity) {
|
||||
identity_list[count] = *peer_identity;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cb(identity_list, count);
|
||||
}
|
||||
|
||||
const csrk_t *SecurityDb::get_local_csrk()
|
||||
{
|
||||
return &_local_csrk;
|
||||
}
|
||||
|
||||
sign_count_t SecurityDb::get_local_sign_counter()
|
||||
{
|
||||
return _local_sign_counter;
|
||||
}
|
||||
|
||||
void SecurityDb::set_local_csrk(const csrk_t &csrk)
|
||||
{
|
||||
_local_csrk = csrk;
|
||||
}
|
||||
|
||||
void SecurityDb::set_local_sign_counter(
|
||||
sign_count_t sign_counter
|
||||
)
|
||||
{
|
||||
_local_sign_counter = sign_counter;
|
||||
}
|
||||
|
||||
void SecurityDb::set_local_identity(
|
||||
const irk_t &irk,
|
||||
const address_t &identity_address,
|
||||
bool public_address
|
||||
)
|
||||
{
|
||||
_local_identity.irk = irk;
|
||||
_local_identity.identity_address = identity_address;
|
||||
_local_identity.identity_address_is_public = public_address;
|
||||
}
|
||||
|
||||
irk_t SecurityDb::get_local_irk()
|
||||
{
|
||||
return _local_identity.irk;
|
||||
}
|
||||
|
||||
|
||||
const address_t &SecurityDb::get_local_identity_address()
|
||||
{
|
||||
return _local_identity.identity_address;
|
||||
}
|
||||
|
||||
bool SecurityDb::is_local_identity_address_public()
|
||||
{
|
||||
return _local_identity.identity_address_is_public;
|
||||
}
|
||||
|
||||
SecurityDb::entry_handle_t SecurityDb::open_entry(
|
||||
peer_address_type_t peer_address_type,
|
||||
const address_t &peer_address
|
||||
)
|
||||
{
|
||||
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
|
||||
if (db_handle) {
|
||||
tr_debug("Found old DB entry (connected to peer previously)");
|
||||
((SecurityDistributionFlags_t*)db_handle)->connected = true;
|
||||
return db_handle;
|
||||
}
|
||||
|
||||
SecurityDistributionFlags_t* flags = get_free_entry_flags();
|
||||
if (flags) {
|
||||
const bool peer_address_public =
|
||||
(peer_address_type == peer_address_type_t::PUBLIC) ||
|
||||
(peer_address_type == peer_address_type_t::PUBLIC_IDENTITY);
|
||||
/* we need some address to store, so we store even random ones
|
||||
* this address will be used as an id, possibly replaced later
|
||||
* by identity address */
|
||||
flags->peer_address = peer_address;
|
||||
flags->peer_address_is_public = peer_address_public;
|
||||
flags->connected = true;
|
||||
return flags;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SecurityDb::entry_handle_t SecurityDb::find_entry_by_peer_address(
|
||||
peer_address_type_t peer_address_type,
|
||||
const address_t &peer_address
|
||||
)
|
||||
{
|
||||
const bool peer_address_public =
|
||||
(peer_address_type == peer_address_type_t::PUBLIC) ||
|
||||
(peer_address_type == peer_address_type_t::PUBLIC_IDENTITY);
|
||||
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
/* only look among disconnected entries */
|
||||
if (flags && !flags->connected) {
|
||||
if (peer_address_type == peer_address_type_t::PUBLIC_IDENTITY &&
|
||||
flags->irk_stored == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup for connection address used during bonding */
|
||||
if (flags->peer_address == peer_address &&
|
||||
flags->peer_address_is_public == peer_address_public) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* look for the identity address if stored */
|
||||
if (flags->irk_stored) {
|
||||
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
|
||||
|
||||
if (identity &&
|
||||
identity->identity_address == peer_address &&
|
||||
identity->identity_address_is_public == peer_address_public) {
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SecurityDb::entry_handle_t SecurityDb::find_entry_by_peer_ediv_rand(
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
)
|
||||
{
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
if (!flags || flags->connected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle);
|
||||
if (!keys) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keys->ediv == ediv && keys->rand == rand) {
|
||||
return db_handle;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SecurityDb::close_entry(entry_handle_t db_handle, bool require_sync) {
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
if (flags) {
|
||||
flags->connected = false;
|
||||
}
|
||||
if (require_sync) {
|
||||
sync(db_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityDb::remove_entry(
|
||||
peer_address_type_t peer_address_type,
|
||||
const address_t &peer_address
|
||||
) {
|
||||
tr_info("Clearing entry for address %s", to_string(peer_address));
|
||||
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
|
||||
if (db_handle) {
|
||||
reset_entry(db_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityDb::clear_entries()
|
||||
{
|
||||
tr_info("Clearing all entries");
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
reset_entry(db_handle);
|
||||
}
|
||||
_local_identity = SecurityEntryIdentity_t();
|
||||
_local_csrk = csrk_t();
|
||||
}
|
||||
|
||||
void SecurityDb::get_whitelist(
|
||||
WhitelistDbCb_t cb,
|
||||
::ble::whitelist_t *whitelist
|
||||
) {
|
||||
/*TODO: fill whitelist*/
|
||||
cb(whitelist);
|
||||
}
|
||||
|
||||
void SecurityDb::generate_whitelist_from_bond_table(
|
||||
WhitelistDbCb_t cb,
|
||||
::ble::whitelist_t *whitelist
|
||||
) {
|
||||
for (size_t i = 0; i < get_entry_count() && whitelist->size < whitelist->capacity; i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
if (!flags || !flags->irk_stored) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the connection address
|
||||
whitelist->addresses[whitelist->size].address = flags->peer_address.data();
|
||||
|
||||
if (flags->peer_address_is_public) {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::PUBLIC;
|
||||
} else {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::RANDOM;
|
||||
}
|
||||
|
||||
whitelist->size++;
|
||||
if (whitelist->size == whitelist->capacity) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the identity address
|
||||
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
|
||||
if (!identity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
whitelist->addresses[whitelist->size].address = identity->identity_address;
|
||||
|
||||
if (identity->identity_address_is_public) {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::PUBLIC_IDENTITY;
|
||||
} else {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::RANDOM_STATIC_IDENTITY;
|
||||
}
|
||||
|
||||
whitelist->size++;
|
||||
}
|
||||
|
||||
cb(whitelist);
|
||||
}
|
||||
|
||||
void SecurityDb::set_whitelist(const ::ble::whitelist_t &whitelist) { };
|
||||
|
||||
void SecurityDb::add_whitelist_entry(const address_t &address) { };
|
||||
|
||||
void SecurityDb::remove_whitelist_entry(const address_t &address) { };
|
||||
|
||||
void SecurityDb::clear_whitelist() { };
|
||||
|
||||
void SecurityDb::restore() { };
|
||||
|
||||
void SecurityDb::sync(entry_handle_t db_handle) { };
|
||||
|
||||
void SecurityDb::set_restore(bool reload) { };
|
||||
|
||||
SecurityDistributionFlags_t* SecurityDb::get_free_entry_flags() {
|
||||
/* get a free one if available */
|
||||
tr_debug("Retrieve a disconnected entry to use as a new entry in DB.");
|
||||
SecurityDistributionFlags_t* match = nullptr;
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
if (flags && !flags->connected) {
|
||||
/* we settle for any disconnected if we don't find an empty one */
|
||||
match = flags;
|
||||
if (!flags->csrk_stored
|
||||
&& !flags->ltk_stored
|
||||
&& !flags->ltk_sent
|
||||
&& !flags->irk_stored) {
|
||||
/* empty one found, stop looking*/
|
||||
tr_debug("Using a previously unused entry as a new entry in DB.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
reset_entry(match);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
} /* namespace ble */
|
||||
|
|
@ -25,11 +25,6 @@
|
|||
#include "ble/common/BLETypes.h"
|
||||
#include "ble/Gap.h"
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
#include "common/ble_trace_helpers.h"
|
||||
|
||||
#define TRACE_GROUP "BLDB"
|
||||
|
||||
namespace ble {
|
||||
|
||||
/**
|
||||
|
|
@ -131,7 +126,7 @@ public:
|
|||
typedef mbed::Callback<void(::ble::whitelist_t*)>
|
||||
WhitelistDbCb_t;
|
||||
|
||||
SecurityDb() : _local_sign_counter(0) { };
|
||||
SecurityDb();
|
||||
virtual ~SecurityDb() = default;
|
||||
|
||||
/**
|
||||
|
|
@ -154,12 +149,7 @@ public:
|
|||
virtual void set_distribution_flags(
|
||||
entry_handle_t db_handle,
|
||||
const SecurityDistributionFlags_t& new_flags
|
||||
) {
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
if (flags) {
|
||||
*flags = new_flags;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/* local keys */
|
||||
|
||||
|
|
@ -176,38 +166,7 @@ public:
|
|||
entry_handle_t* db_handle,
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(*db_handle);
|
||||
/* validate we have the correct key */
|
||||
if (keys && ediv == keys->ediv && rand == keys->rand) {
|
||||
cb(*db_handle, keys);
|
||||
} else {
|
||||
// Maybe this isn't the correct entry, try to find one that matches
|
||||
entry_handle_t correct_handle = find_entry_by_peer_ediv_rand(ediv, rand);
|
||||
if (!correct_handle) {
|
||||
tr_warn("Failed to find ltk matching given ediv&rand");
|
||||
cb(*db_handle, NULL);
|
||||
return;
|
||||
}
|
||||
tr_warn("Found ltk matching given ediv&rand but it belonged to a different identity, update entry with new identity");
|
||||
// Note: keys should never be null as a matching entry has been retrieved
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(correct_handle);
|
||||
MBED_ASSERT(keys);
|
||||
|
||||
/* set flags connected */
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(correct_handle);
|
||||
flags->connected = true;
|
||||
|
||||
/* update peer address */
|
||||
SecurityDistributionFlags_t* old_flags = get_distribution_flags(*db_handle);
|
||||
flags->peer_address = old_flags->peer_address;
|
||||
flags->peer_address_is_public = old_flags->peer_address_is_public;
|
||||
|
||||
close_entry(*db_handle, false);
|
||||
*db_handle = correct_handle;
|
||||
cb(*db_handle, keys);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve stored LTK generated during secure connections pairing.
|
||||
|
|
@ -218,16 +177,7 @@ public:
|
|||
virtual void get_entry_local_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
) {
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
/* validate we have the correct key */
|
||||
if (flags && keys && flags->secure_connections_paired) {
|
||||
cb(db_handle, keys);
|
||||
} else {
|
||||
cb(db_handle, NULL);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Save new local LTK for a connection.
|
||||
|
|
@ -266,10 +216,7 @@ public:
|
|||
virtual void get_entry_peer_csrk(
|
||||
SecurityEntrySigningDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
) {
|
||||
SecurityEntrySigning_t* signing = read_in_entry_peer_signing(db_handle);
|
||||
cb(db_handle, signing);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Return asynchronously the peer encryption key through a callback
|
||||
|
|
@ -281,10 +228,7 @@ public:
|
|||
virtual void get_entry_peer_keys(
|
||||
SecurityEntryKeysDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
) {
|
||||
SecurityEntryKeys_t* keys = read_in_entry_peer_keys(db_handle);
|
||||
cb(db_handle, keys);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Save new LTK received from the peer.
|
||||
|
|
@ -344,18 +288,7 @@ public:
|
|||
virtual void get_entry_identity(
|
||||
SecurityEntryIdentityDbCb_t cb,
|
||||
entry_handle_t db_handle
|
||||
) {
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
if (flags && flags->irk_stored) {
|
||||
SecurityEntryIdentity_t* peer_identity = read_in_entry_peer_identity(db_handle);
|
||||
if (peer_identity) {
|
||||
cb(db_handle, peer_identity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* avoid duplicate else */
|
||||
cb(db_handle, NULL);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Asynchronously return the identity list stored in NVM through a callback.
|
||||
|
|
@ -369,25 +302,7 @@ public:
|
|||
virtual void get_identity_list(
|
||||
IdentitylistDbCb_t cb,
|
||||
Span<SecurityEntryIdentity_t>& identity_list
|
||||
) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < get_entry_count() && count < (size_t) identity_list.size(); ++i) {
|
||||
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
|
||||
if (flags && flags->irk_stored) {
|
||||
SecurityEntryIdentity_t* peer_identity = read_in_entry_peer_identity(db_handle);
|
||||
if (peer_identity) {
|
||||
identity_list[count] = *peer_identity;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cb(identity_list, count);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Update peer signing key.
|
||||
|
|
@ -418,18 +333,14 @@ public:
|
|||
*
|
||||
* @return pointer to local CSRK
|
||||
*/
|
||||
virtual const csrk_t* get_local_csrk() {
|
||||
return &_local_csrk;
|
||||
}
|
||||
virtual const csrk_t* get_local_csrk();
|
||||
|
||||
/**
|
||||
* Return local signing counter.
|
||||
*
|
||||
* @return signing counter
|
||||
*/
|
||||
virtual sign_count_t get_local_sign_counter() {
|
||||
return _local_sign_counter;
|
||||
}
|
||||
virtual sign_count_t get_local_sign_counter();
|
||||
|
||||
/**
|
||||
* Update local signing key.
|
||||
|
|
@ -438,9 +349,7 @@ public:
|
|||
*/
|
||||
virtual void set_local_csrk(
|
||||
const csrk_t &csrk
|
||||
) {
|
||||
_local_csrk = csrk;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Update local signing counter.
|
||||
|
|
@ -449,9 +358,7 @@ public:
|
|||
*/
|
||||
virtual void set_local_sign_counter(
|
||||
sign_count_t sign_counter
|
||||
) {
|
||||
_local_sign_counter = sign_counter;
|
||||
}
|
||||
);
|
||||
|
||||
/* local identity */
|
||||
/**
|
||||
|
|
@ -463,34 +370,24 @@ public:
|
|||
const irk_t &irk,
|
||||
const address_t &identity_address,
|
||||
bool public_address
|
||||
) {
|
||||
_local_identity.irk = irk;
|
||||
_local_identity.identity_address = identity_address;
|
||||
_local_identity.identity_address_is_public = public_address;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Return local irk.
|
||||
*
|
||||
* @return irk
|
||||
*/
|
||||
virtual irk_t get_local_irk() {
|
||||
return _local_identity.irk;
|
||||
}
|
||||
virtual irk_t get_local_irk();
|
||||
|
||||
/**
|
||||
* Return local identity address.
|
||||
*/
|
||||
virtual const address_t& get_local_identity_address() {
|
||||
return _local_identity.identity_address;
|
||||
}
|
||||
virtual const address_t& get_local_identity_address();
|
||||
|
||||
/**
|
||||
* Return if the local identity address is public or not
|
||||
*/
|
||||
virtual bool is_local_identity_address_public() {
|
||||
return _local_identity.identity_address_is_public;
|
||||
}
|
||||
virtual bool is_local_identity_address_public();
|
||||
|
||||
/* list management */
|
||||
|
||||
|
|
@ -509,30 +406,7 @@ public:
|
|||
virtual entry_handle_t open_entry(
|
||||
peer_address_type_t peer_address_type,
|
||||
const address_t &peer_address
|
||||
) {
|
||||
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
|
||||
if (db_handle) {
|
||||
tr_debug("Found old DB entry (connected to peer previously)");
|
||||
((SecurityDistributionFlags_t*)db_handle)->connected = true;
|
||||
return db_handle;
|
||||
}
|
||||
|
||||
SecurityDistributionFlags_t* flags = get_free_entry_flags();
|
||||
if (flags) {
|
||||
const bool peer_address_public =
|
||||
(peer_address_type == peer_address_type_t::PUBLIC) ||
|
||||
(peer_address_type == peer_address_type_t::PUBLIC_IDENTITY);
|
||||
/* we need some address to store, so we store even random ones
|
||||
* this address will be used as an id, possibly replaced later
|
||||
* by identity address */
|
||||
flags->peer_address = peer_address;
|
||||
flags->peer_address_is_public = peer_address_public;
|
||||
flags->connected = true;
|
||||
return flags;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Find a database entry based on peer address.
|
||||
|
|
@ -545,43 +419,7 @@ public:
|
|||
virtual entry_handle_t find_entry_by_peer_address(
|
||||
peer_address_type_t peer_address_type,
|
||||
const address_t &peer_address
|
||||
) {
|
||||
const bool peer_address_public =
|
||||
(peer_address_type == peer_address_type_t::PUBLIC) ||
|
||||
(peer_address_type == peer_address_type_t::PUBLIC_IDENTITY);
|
||||
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
/* only look among disconnected entries */
|
||||
if (flags && !flags->connected) {
|
||||
if (peer_address_type == peer_address_type_t::PUBLIC_IDENTITY &&
|
||||
flags->irk_stored == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup for connection address used during bonding */
|
||||
if (flags->peer_address == peer_address &&
|
||||
flags->peer_address_is_public == peer_address_public) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* look for the identity address if stored */
|
||||
if (flags->irk_stored) {
|
||||
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
|
||||
|
||||
if (identity &&
|
||||
identity->identity_address == peer_address &&
|
||||
identity->identity_address_is_public == peer_address_public) {
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Find a database entry based on ediv and rand.
|
||||
|
|
@ -594,27 +432,7 @@ public:
|
|||
virtual entry_handle_t find_entry_by_peer_ediv_rand(
|
||||
const ediv_t &ediv,
|
||||
const rand_t &rand
|
||||
) {
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
if (!flags || flags->connected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle);
|
||||
if (!keys) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keys->ediv == ediv && keys->rand == rand) {
|
||||
return db_handle;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -622,15 +440,7 @@ public:
|
|||
*
|
||||
* @param[in] db_handle this handle will be freed up from the security db.
|
||||
*/
|
||||
virtual void close_entry(entry_handle_t db_handle, bool require_sync = true) {
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
if (flags) {
|
||||
flags->connected = false;
|
||||
}
|
||||
if (require_sync) {
|
||||
sync(db_handle);
|
||||
}
|
||||
}
|
||||
virtual void close_entry(entry_handle_t db_handle, bool require_sync = true);
|
||||
|
||||
/**
|
||||
* Remove entry for this peer from NVM.
|
||||
|
|
@ -644,26 +454,12 @@ public:
|
|||
virtual void remove_entry(
|
||||
peer_address_type_t peer_address_type,
|
||||
const address_t &peer_address
|
||||
) {
|
||||
tr_info("Clearing entry for address %s", to_string(peer_address));
|
||||
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
|
||||
if (db_handle) {
|
||||
reset_entry(db_handle);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Remove all entries from the security DB.
|
||||
*/
|
||||
virtual void clear_entries() {
|
||||
tr_info("Clearing all entries");
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
reset_entry(db_handle);
|
||||
}
|
||||
_local_identity = SecurityEntryIdentity_t();
|
||||
_local_csrk = csrk_t();
|
||||
}
|
||||
virtual void clear_entries();
|
||||
|
||||
/**
|
||||
* Asynchronously return the whitelist stored in NVM through a callback.
|
||||
|
|
@ -676,10 +472,7 @@ public:
|
|||
virtual void get_whitelist(
|
||||
WhitelistDbCb_t cb,
|
||||
::ble::whitelist_t *whitelist
|
||||
) {
|
||||
/*TODO: fill whitelist*/
|
||||
cb(whitelist);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Asynchronously return a whitelist through a callback, generated from the
|
||||
|
|
@ -691,93 +484,52 @@ public:
|
|||
virtual void generate_whitelist_from_bond_table(
|
||||
WhitelistDbCb_t cb,
|
||||
::ble::whitelist_t *whitelist
|
||||
) {
|
||||
for (size_t i = 0; i < get_entry_count() && whitelist->size < whitelist->capacity; i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
if (!flags || !flags->irk_stored) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the connection address
|
||||
whitelist->addresses[whitelist->size].address = flags->peer_address.data();
|
||||
|
||||
if (flags->peer_address_is_public) {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::PUBLIC;
|
||||
} else {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::RANDOM;
|
||||
}
|
||||
|
||||
whitelist->size++;
|
||||
if (whitelist->size == whitelist->capacity) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the identity address
|
||||
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
|
||||
if (!identity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
whitelist->addresses[whitelist->size].address = identity->identity_address;
|
||||
|
||||
if (identity->identity_address_is_public) {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::PUBLIC_IDENTITY;
|
||||
} else {
|
||||
whitelist->addresses[whitelist->size].type = peer_address_type_t::RANDOM_STATIC_IDENTITY;
|
||||
}
|
||||
|
||||
whitelist->size++;
|
||||
}
|
||||
|
||||
cb(whitelist);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Update the whitelist stored in NVM by replacing it with new one.
|
||||
*
|
||||
* @param[in] whitelist
|
||||
*/
|
||||
virtual void set_whitelist(const ::ble::whitelist_t &whitelist) { };
|
||||
virtual void set_whitelist(const ::ble::whitelist_t &whitelist);
|
||||
|
||||
/**
|
||||
* Add a new entry to the whitelist in the NVM.
|
||||
*
|
||||
* @param[in] address new whitelist entry
|
||||
*/
|
||||
virtual void add_whitelist_entry(const address_t &address) { };
|
||||
virtual void add_whitelist_entry(const address_t &address);
|
||||
|
||||
/**
|
||||
* Remove whitelist entry from NVM.
|
||||
*
|
||||
* @param[in] address entry to be removed
|
||||
*/
|
||||
virtual void remove_whitelist_entry(const address_t &address) { };
|
||||
virtual void remove_whitelist_entry(const address_t &address);
|
||||
|
||||
/**
|
||||
*Remove all whitelist entries stored in the NVM.
|
||||
*/
|
||||
virtual void clear_whitelist() { };
|
||||
virtual void clear_whitelist();
|
||||
|
||||
/* saving and loading from nvm */
|
||||
|
||||
/**
|
||||
* Read values from storage.
|
||||
*/
|
||||
virtual void restore() { };
|
||||
virtual void restore();
|
||||
|
||||
/**
|
||||
* Flush all values which might be stored in memory into NVM.
|
||||
*/
|
||||
virtual void sync(entry_handle_t db_handle) { };
|
||||
virtual void sync(entry_handle_t db_handle);
|
||||
|
||||
/**
|
||||
* Toggle whether values should be preserved across resets.
|
||||
*
|
||||
* @param[in] reload if true values will be preserved across resets.
|
||||
*/
|
||||
virtual void set_restore(bool reload) { };
|
||||
virtual void set_restore(bool reload);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
@ -785,34 +537,7 @@ private:
|
|||
* or use a disconnected entry by reseting all the stored information.
|
||||
* @return empty entry for the new connection
|
||||
*/
|
||||
virtual SecurityDistributionFlags_t* get_free_entry_flags() {
|
||||
/* get a free one if available */
|
||||
tr_debug("Retrieve a disconnected entry to use as a new entry in DB.");
|
||||
SecurityDistributionFlags_t* match = nullptr;
|
||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
||||
entry_handle_t db_handle = get_entry_handle_by_index(i);
|
||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
||||
|
||||
if (flags && !flags->connected) {
|
||||
/* we settle for any disconnected if we don't find an empty one */
|
||||
match = flags;
|
||||
if (!flags->csrk_stored
|
||||
&& !flags->ltk_stored
|
||||
&& !flags->ltk_sent
|
||||
&& !flags->irk_stored) {
|
||||
/* empty one found, stop looking*/
|
||||
tr_debug("Using a previously unused entry as a new entry in DB.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
reset_entry(match);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
virtual SecurityDistributionFlags_t* get_free_entry_flags();
|
||||
|
||||
/**
|
||||
* How many entries can be stored in the database.
|
||||
|
|
|
|||
Loading…
Reference in New Issue