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_api.h"
|
||||||
#include "att_defs.h"
|
#include "att_defs.h"
|
||||||
|
|
||||||
|
#include "mbed-trace/mbed_trace.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "BLAT"
|
#define TRACE_GROUP "BLAT"
|
||||||
|
|
||||||
namespace ble {
|
namespace ble {
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,14 @@ FileSecurityDb::~FileSecurityDb()
|
||||||
fclose(_db_file);
|
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)
|
FILE* FileSecurityDb::open_db_file(const char *db_path)
|
||||||
{
|
{
|
||||||
if (!db_path) {
|
if (!db_path) {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "SecurityDb.h"
|
#include "SecurityDb.h"
|
||||||
#include "mbed-trace/mbed_trace.h"
|
|
||||||
|
|
||||||
#define TRACE_GROUP "BLDB"
|
|
||||||
|
|
||||||
namespace ble {
|
namespace ble {
|
||||||
|
|
||||||
|
|
@ -40,13 +37,7 @@ private:
|
||||||
size_t file_offset;
|
size_t file_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
static entry_t* as_entry(entry_handle_t db_handle) {
|
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>
|
template<class T>
|
||||||
void db_read(T *value, long int offset) {
|
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()
|
bool KVStoreSecurityDb::open_db()
|
||||||
{
|
{
|
||||||
uint8_t version = 0;
|
uint8_t version = 0;
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,10 @@
|
||||||
#include "mbed_error.h"
|
#include "mbed_error.h"
|
||||||
|
|
||||||
#include "SecurityDb.h"
|
#include "SecurityDb.h"
|
||||||
#include "mbed-trace/mbed_trace.h"
|
|
||||||
|
|
||||||
#define STR_EXPAND(tok) #tok
|
#define STR_EXPAND(tok) #tok
|
||||||
#define STR(tok) STR_EXPAND(tok)
|
#define STR(tok) STR_EXPAND(tok)
|
||||||
|
|
||||||
#define TRACE_GROUP "BLDB"
|
|
||||||
|
|
||||||
namespace ble {
|
namespace ble {
|
||||||
|
|
||||||
/** Filesystem implementation */
|
/** Filesystem implementation */
|
||||||
|
|
@ -66,14 +63,6 @@ private:
|
||||||
static constexpr char DB_VERSION[DB_KEY_SIZE] = { 'v','e','r' };
|
static constexpr char DB_VERSION[DB_KEY_SIZE] = { 'v','e','r' };
|
||||||
static constexpr char DB_RESTORE[DB_KEY_SIZE] = { 'r','e','s' };
|
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>
|
template<class T>
|
||||||
static void db_read(T *value, const char* key) {
|
static void db_read(T *value, const char* key) {
|
||||||
char db_key[DB_FULL_KEY_SIZE];
|
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 "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 {
|
namespace ble {
|
||||||
|
|
||||||
/** Naive memory implementation for verification. */
|
/** Naive memory implementation for verification. */
|
||||||
|
|
@ -44,28 +35,16 @@ private:
|
||||||
SecurityEntrySigning_t peer_signing;
|
SecurityEntrySigning_t peer_signing;
|
||||||
};
|
};
|
||||||
|
|
||||||
static entry_t* as_entry(entry_handle_t db_handle)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MemorySecurityDb() : SecurityDb()
|
MemorySecurityDb();
|
||||||
{
|
|
||||||
tr_info("Using memory security DB (capacity " STR(BLE_SECURITY_DATABASE_MAX_ENTRIES) " entries) - no persistence across reset");
|
|
||||||
}
|
|
||||||
|
|
||||||
~MemorySecurityDb() override = default;
|
~MemorySecurityDb() override = default;
|
||||||
|
|
||||||
SecurityDistributionFlags_t *get_distribution_flags(
|
SecurityDistributionFlags_t *get_distribution_flags(
|
||||||
entry_handle_t db_handle
|
entry_handle_t db_handle
|
||||||
) override {
|
) override;
|
||||||
return reinterpret_cast<SecurityDistributionFlags_t*>(db_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* local keys */
|
/* local keys */
|
||||||
|
|
||||||
|
|
@ -73,27 +52,13 @@ public:
|
||||||
void set_entry_local_ltk(
|
void set_entry_local_ltk(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_entry_local_ediv_rand(
|
void set_entry_local_ediv_rand(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* peer's keys */
|
/* peer's keys */
|
||||||
|
|
||||||
|
|
@ -102,118 +67,51 @@ public:
|
||||||
void set_entry_peer_ltk(
|
void set_entry_peer_ltk(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const ltk_t <k
|
const ltk_t <k
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_entry_peer_ediv_rand(
|
void set_entry_peer_ediv_rand(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
const rand_t &rand
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_entry_peer_irk(
|
void set_entry_peer_irk(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const irk_t &irk
|
const irk_t &irk
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_entry_peer_bdaddr(
|
void set_entry_peer_bdaddr(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
bool address_is_public,
|
bool address_is_public,
|
||||||
const address_t &peer_address
|
const address_t &peer_address
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_entry_peer_csrk(
|
void set_entry_peer_csrk(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const csrk_t &csrk
|
const csrk_t &csrk
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_entry_peer_sign_counter(
|
void set_entry_peer_sign_counter(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
sign_count_t sign_counter
|
sign_count_t sign_counter
|
||||||
) override {
|
) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t get_entry_count() override {
|
uint8_t get_entry_count() override;
|
||||||
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index) 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_entry(entry_handle_t db_entry) override{
|
void reset_entry(entry_handle_t db_entry) override;
|
||||||
auto *entry = reinterpret_cast<entry_t*>(db_entry);
|
|
||||||
*entry = entry_t();
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityEntryIdentity_t* read_in_entry_peer_identity(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;
|
|
||||||
};
|
|
||||||
|
|
||||||
SecurityEntryKeys_t* read_in_entry_peer_keys(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_local_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;
|
|
||||||
};
|
|
||||||
|
|
||||||
SecurityEntrySigning_t* read_in_entry_peer_signing(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;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t get_index(const entry_handle_t db_handle) const
|
uint8_t get_index(const entry_handle_t db_handle) const;
|
||||||
{
|
|
||||||
return reinterpret_cast<entry_t*>(db_handle) - _entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
|
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/common/BLETypes.h"
|
||||||
#include "ble/Gap.h"
|
#include "ble/Gap.h"
|
||||||
|
|
||||||
#include "mbed-trace/mbed_trace.h"
|
|
||||||
#include "common/ble_trace_helpers.h"
|
|
||||||
|
|
||||||
#define TRACE_GROUP "BLDB"
|
|
||||||
|
|
||||||
namespace ble {
|
namespace ble {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -131,7 +126,7 @@ public:
|
||||||
typedef mbed::Callback<void(::ble::whitelist_t*)>
|
typedef mbed::Callback<void(::ble::whitelist_t*)>
|
||||||
WhitelistDbCb_t;
|
WhitelistDbCb_t;
|
||||||
|
|
||||||
SecurityDb() : _local_sign_counter(0) { };
|
SecurityDb();
|
||||||
virtual ~SecurityDb() = default;
|
virtual ~SecurityDb() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -154,12 +149,7 @@ public:
|
||||||
virtual void set_distribution_flags(
|
virtual void set_distribution_flags(
|
||||||
entry_handle_t db_handle,
|
entry_handle_t db_handle,
|
||||||
const SecurityDistributionFlags_t& new_flags
|
const SecurityDistributionFlags_t& new_flags
|
||||||
) {
|
);
|
||||||
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
|
|
||||||
if (flags) {
|
|
||||||
*flags = new_flags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* local keys */
|
/* local keys */
|
||||||
|
|
||||||
|
|
@ -176,38 +166,7 @@ public:
|
||||||
entry_handle_t* db_handle,
|
entry_handle_t* db_handle,
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
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.
|
* Retrieve stored LTK generated during secure connections pairing.
|
||||||
|
|
@ -218,16 +177,7 @@ public:
|
||||||
virtual void get_entry_local_keys(
|
virtual void get_entry_local_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
entry_handle_t db_handle
|
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.
|
* Save new local LTK for a connection.
|
||||||
|
|
@ -266,10 +216,7 @@ public:
|
||||||
virtual void get_entry_peer_csrk(
|
virtual void get_entry_peer_csrk(
|
||||||
SecurityEntrySigningDbCb_t cb,
|
SecurityEntrySigningDbCb_t cb,
|
||||||
entry_handle_t db_handle
|
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
|
* Return asynchronously the peer encryption key through a callback
|
||||||
|
|
@ -281,10 +228,7 @@ public:
|
||||||
virtual void get_entry_peer_keys(
|
virtual void get_entry_peer_keys(
|
||||||
SecurityEntryKeysDbCb_t cb,
|
SecurityEntryKeysDbCb_t cb,
|
||||||
entry_handle_t db_handle
|
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.
|
* Save new LTK received from the peer.
|
||||||
|
|
@ -344,18 +288,7 @@ public:
|
||||||
virtual void get_entry_identity(
|
virtual void get_entry_identity(
|
||||||
SecurityEntryIdentityDbCb_t cb,
|
SecurityEntryIdentityDbCb_t cb,
|
||||||
entry_handle_t db_handle
|
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.
|
* Asynchronously return the identity list stored in NVM through a callback.
|
||||||
|
|
@ -369,25 +302,7 @@ public:
|
||||||
virtual void get_identity_list(
|
virtual void get_identity_list(
|
||||||
IdentitylistDbCb_t cb,
|
IdentitylistDbCb_t cb,
|
||||||
Span<SecurityEntryIdentity_t>& identity_list
|
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.
|
* Update peer signing key.
|
||||||
|
|
@ -418,18 +333,14 @@ public:
|
||||||
*
|
*
|
||||||
* @return pointer to local CSRK
|
* @return pointer to local CSRK
|
||||||
*/
|
*/
|
||||||
virtual const csrk_t* get_local_csrk() {
|
virtual const csrk_t* get_local_csrk();
|
||||||
return &_local_csrk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return local signing counter.
|
* Return local signing counter.
|
||||||
*
|
*
|
||||||
* @return signing counter
|
* @return signing counter
|
||||||
*/
|
*/
|
||||||
virtual sign_count_t get_local_sign_counter() {
|
virtual sign_count_t get_local_sign_counter();
|
||||||
return _local_sign_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update local signing key.
|
* Update local signing key.
|
||||||
|
|
@ -438,9 +349,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void set_local_csrk(
|
virtual void set_local_csrk(
|
||||||
const csrk_t &csrk
|
const csrk_t &csrk
|
||||||
) {
|
);
|
||||||
_local_csrk = csrk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update local signing counter.
|
* Update local signing counter.
|
||||||
|
|
@ -449,9 +358,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void set_local_sign_counter(
|
virtual void set_local_sign_counter(
|
||||||
sign_count_t sign_counter
|
sign_count_t sign_counter
|
||||||
) {
|
);
|
||||||
_local_sign_counter = sign_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* local identity */
|
/* local identity */
|
||||||
/**
|
/**
|
||||||
|
|
@ -463,34 +370,24 @@ public:
|
||||||
const irk_t &irk,
|
const irk_t &irk,
|
||||||
const address_t &identity_address,
|
const address_t &identity_address,
|
||||||
bool public_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 local irk.
|
||||||
*
|
*
|
||||||
* @return irk
|
* @return irk
|
||||||
*/
|
*/
|
||||||
virtual irk_t get_local_irk() {
|
virtual irk_t get_local_irk();
|
||||||
return _local_identity.irk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return local identity address.
|
* Return local identity address.
|
||||||
*/
|
*/
|
||||||
virtual const address_t& get_local_identity_address() {
|
virtual const address_t& get_local_identity_address();
|
||||||
return _local_identity.identity_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if the local identity address is public or not
|
* Return if the local identity address is public or not
|
||||||
*/
|
*/
|
||||||
virtual bool is_local_identity_address_public() {
|
virtual bool is_local_identity_address_public();
|
||||||
return _local_identity.identity_address_is_public;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* list management */
|
/* list management */
|
||||||
|
|
||||||
|
|
@ -509,30 +406,7 @@ public:
|
||||||
virtual entry_handle_t open_entry(
|
virtual entry_handle_t open_entry(
|
||||||
peer_address_type_t peer_address_type,
|
peer_address_type_t peer_address_type,
|
||||||
const address_t &peer_address
|
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.
|
* Find a database entry based on peer address.
|
||||||
|
|
@ -545,43 +419,7 @@ public:
|
||||||
virtual entry_handle_t find_entry_by_peer_address(
|
virtual entry_handle_t find_entry_by_peer_address(
|
||||||
peer_address_type_t peer_address_type,
|
peer_address_type_t peer_address_type,
|
||||||
const address_t &peer_address
|
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.
|
* Find a database entry based on ediv and rand.
|
||||||
|
|
@ -594,27 +432,7 @@ public:
|
||||||
virtual entry_handle_t find_entry_by_peer_ediv_rand(
|
virtual entry_handle_t find_entry_by_peer_ediv_rand(
|
||||||
const ediv_t &ediv,
|
const ediv_t &ediv,
|
||||||
const rand_t &rand
|
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.
|
* @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) {
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove entry for this peer from NVM.
|
* Remove entry for this peer from NVM.
|
||||||
|
|
@ -644,26 +454,12 @@ public:
|
||||||
virtual void remove_entry(
|
virtual void remove_entry(
|
||||||
peer_address_type_t peer_address_type,
|
peer_address_type_t peer_address_type,
|
||||||
const address_t &peer_address
|
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.
|
* Remove all entries from the security DB.
|
||||||
*/
|
*/
|
||||||
virtual void clear_entries() {
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously return the whitelist stored in NVM through a callback.
|
* Asynchronously return the whitelist stored in NVM through a callback.
|
||||||
|
|
@ -676,10 +472,7 @@ public:
|
||||||
virtual void get_whitelist(
|
virtual void get_whitelist(
|
||||||
WhitelistDbCb_t cb,
|
WhitelistDbCb_t cb,
|
||||||
::ble::whitelist_t *whitelist
|
::ble::whitelist_t *whitelist
|
||||||
) {
|
);
|
||||||
/*TODO: fill whitelist*/
|
|
||||||
cb(whitelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously return a whitelist through a callback, generated from the
|
* Asynchronously return a whitelist through a callback, generated from the
|
||||||
|
|
@ -691,93 +484,52 @@ public:
|
||||||
virtual void generate_whitelist_from_bond_table(
|
virtual void generate_whitelist_from_bond_table(
|
||||||
WhitelistDbCb_t cb,
|
WhitelistDbCb_t cb,
|
||||||
::ble::whitelist_t *whitelist
|
::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.
|
* Update the whitelist stored in NVM by replacing it with new one.
|
||||||
*
|
*
|
||||||
* @param[in] whitelist
|
* @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.
|
* 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(const address_t &address) { };
|
virtual void add_whitelist_entry(const address_t &address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(const address_t &address) { };
|
virtual void remove_whitelist_entry(const address_t &address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Remove all whitelist entries stored in the NVM.
|
*Remove all whitelist entries stored in the NVM.
|
||||||
*/
|
*/
|
||||||
virtual void clear_whitelist() { };
|
virtual void clear_whitelist();
|
||||||
|
|
||||||
/* saving and loading from nvm */
|
/* saving and loading from nvm */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read values from storage.
|
* Read values from storage.
|
||||||
*/
|
*/
|
||||||
virtual void restore() { };
|
virtual void restore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush all values which might be stored in memory into NVM.
|
* 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.
|
* Toggle whether values should be preserved across resets.
|
||||||
*
|
*
|
||||||
* @param[in] reload if true values will 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:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
@ -785,34 +537,7 @@ private:
|
||||||
* or use a disconnected entry by reseting all the stored information.
|
* or use a disconnected entry by reseting all the stored information.
|
||||||
* @return empty entry for the new connection
|
* @return empty entry for the new connection
|
||||||
*/
|
*/
|
||||||
virtual SecurityDistributionFlags_t* get_free_entry_flags() {
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How many entries can be stored in the database.
|
* How many entries can be stored in the database.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue