From: Inga Stotland <inga.stotland@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: brian.gix@intel.com, johan.hedberg@gmail.com,
luiz.dentz@gmail.com, Inga Stotland <inga.stotland@intel.com>
Subject: [PATCH BlueZ 5/5 v2] mesh: Save newly added or updated net key to config file
Date: Wed, 6 Feb 2019 19:55:37 -0800 [thread overview]
Message-ID: <20190207035537.20375-6-inga.stotland@intel.com> (raw)
In-Reply-To: <20190207035537.20375-1-inga.stotland@intel.com>
This separates mesh_db_net_key_add() into distinct functions:
mesh_db_net_key_add() and mesh_db_net_key_update() which will be called
based on whether a network key was newly added or updated.
---
mesh/mesh-db.c | 122 +++++++++++++++++++++----------------------------
mesh/mesh-db.h | 4 +-
mesh/net.c | 9 ++--
mesh/node.c | 15 ++++--
mesh/storage.c | 7 ++-
mesh/storage.h | 5 +-
6 files changed, 80 insertions(+), 82 deletions(-)
diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index b9bbef912..6486f7cff 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -51,7 +51,7 @@ static bool get_int(json_object *jobj, const char *keyword, int *value)
return true;
}
-static bool add_key(json_object *jobject, const char *desc,
+static bool add_key_value(json_object *jobject, const char *desc,
const uint8_t key[16])
{
json_object *jstring;
@@ -382,7 +382,7 @@ bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
}
bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
- const uint8_t key[16], int phase)
+ const uint8_t key[16])
{
json_object *jarray, *jentry = NULL, *jstring;
char buf[5];
@@ -392,91 +392,75 @@ bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
if (jarray)
jentry = get_key_object(jarray, idx);
- if (jentry) {
- uint8_t buf[16];
- json_object *jvalue;
- char *str;
-
- json_object_object_get_ex(jentry, "key", &jvalue);
- if (!jvalue)
- return false;
-
- str = (char *)json_object_get_string(jvalue);
- if (!str2hex(str, strlen(str), buf, sizeof(buf)))
- return false;
-
- /* If the same key, return success */
- if (memcmp(key, buf, 16) == 0)
- return true;
+ /* Do not allow direct overwrite */
+ if (jentry)
+ return false;
+ jentry = json_object_new_object();
+ if (!jentry)
return false;
- }
- if (!jentry) {
- jentry = json_object_new_object();
- if (!jentry)
- goto fail;
+ snprintf(buf, 5, "%4.4x", idx);
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ goto fail;
- snprintf(buf, 5, "%4.4x", idx);
- jstring = json_object_new_string(buf);
- if (!jstring)
- goto fail;
+ json_object_object_add(jentry, "index", jstring);
- json_object_object_add(jentry, "index", jstring);
+ if (!add_key_value(jentry, "key", key))
+ goto fail;
- snprintf(buf, 5, "%4.4x", idx);
- jstring = json_object_new_string(buf);
- if (!jstring)
- goto fail;
+ json_object_object_add(jentry, "keyRefresh",
+ json_object_new_int(KEY_REFRESH_PHASE_NONE));
- if (!add_key(jentry, "key", key))
+ if (!jarray) {
+ jarray = json_object_new_array();
+ if (!jarray)
goto fail;
+ json_object_object_add(jobj, "netKeys", jarray);
+ }
- /* If Key Refresh underway, add placeholder for "Old Key" */
- if (phase != KEY_REFRESH_PHASE_NONE) {
- uint8_t buf[16];
- uint8_t i;
+ json_object_array_add(jarray, jentry);
- /* Flip Bits to differentiate */
- for (i = 0; i < sizeof(buf); i++)
- buf[i] = key[i] ^ 0xff;
+ return true;
+fail:
+ if (jentry)
+ json_object_put(jentry);
- if (!add_key(jentry, "oldKey", buf))
- goto fail;
- }
+ return false;
+}
- if (!jarray) {
- jarray = json_object_new_array();
- if (!jarray)
- goto fail;
- json_object_object_add(jobj, "netKeys", jarray);
- }
+bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+ const uint8_t key[16])
+{
+ json_object *jarray, *jentry, *jstring;
+ const char *str;
- json_object_array_add(jarray, jentry);
+ json_object_object_get_ex(jobj, "netKeys", &jarray);
- } else {
+ if (!jarray)
+ return false;
- if (!json_object_object_get_ex(jentry, "key", &jstring))
- return false;
+ jentry = get_key_object(jarray, idx);
+ /* Net key must be already recorded */
+ if (!jentry)
+ return false;
- json_object_object_add(jentry, "oldKey", jstring);
- json_object_object_del(jentry, "key");
+ if (!json_object_object_get_ex(jentry, "key", &jstring))
+ return false;
- if (!add_key(jentry, "key", key))
- return false;
- }
+ str = json_object_get_string(jstring);
+ jstring = json_object_new_string(str);
+ json_object_object_add(jentry, "oldKey", jstring);
+ json_object_object_del(jentry, "key");
+ if (!add_key_value(jentry, "key", key))
+ return false;
json_object_object_add(jentry, "keyRefresh",
- json_object_new_int(phase));
+ json_object_new_int(KEY_REFRESH_PHASE_ONE));
return true;
-fail:
-
- if (jentry)
- json_object_put(jentry);
-
- return false;
}
bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
@@ -513,7 +497,7 @@ bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
{
- return add_key(jnode, "deviceKey", key);
+ return add_key_value(jnode, "deviceKey", key);
}
bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
@@ -572,7 +556,7 @@ bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
json_object_object_add(jentry, "boundNetKey", jstring);
- if (!add_key(jentry, "key", key))
+ if (!add_key_value(jentry, "key", key))
goto fail;
if (!jarray) {
@@ -592,7 +576,7 @@ bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
json_object_object_add(jentry, "oldKey", jstring);
json_object_object_del(jentry, "key");
- if (!add_key(jentry, "key", key))
+ if (!add_key_value(jentry, "key", key))
return false;
}
@@ -1421,7 +1405,7 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
return false;
/* Device UUID */
- if (!add_key(jnode, "UUID", node->uuid))
+ if (!add_key_value(jnode, "UUID", node->uuid))
return false;
/* Features: relay, LPN, friend, proxy*/
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index db7ea6045..513ad3861 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -133,7 +133,9 @@ bool mesh_db_app_key_add(json_object *jnode, uint16_t net_idx, uint16_t app_idx,
const uint8_t key[16], bool update);
bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
bool mesh_db_net_key_add(json_object *jobj, uint16_t net_idx,
- const uint8_t key[16], int phase);
+ const uint8_t key[16]);
+bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+ const uint8_t key[16]);
bool mesh_db_net_key_del(json_object *jobj, uint16_t net_idx);
bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase);
bool mesh_db_write_address(json_object *jobj, uint16_t address);
diff --git a/mesh/net.c b/mesh/net.c
index 3229d20d4..f00ef7df7 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -1016,7 +1016,7 @@ int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
if (status != MESH_STATUS_SUCCESS)
return status;
- if (!storage_net_key_add(net, idx, value, KEY_REFRESH_PHASE_NONE)) {
+ if (!storage_net_key_add(net, idx, value, false)) {
l_queue_remove(net->subnets, subnet);
subnet_free(subnet);
return MESH_STATUS_STORAGE_FAIL;
@@ -3704,13 +3704,16 @@ int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
L_UINT_TO_PTR(idx));
if (!subnet)
- return MESH_STATUS_CANNOT_UPDATE;
+ return MESH_STATUS_INVALID_NETKEY;
/* Check if the key has been already successfully updated */
if (subnet->kr_phase == KEY_REFRESH_PHASE_ONE &&
net_key_confirm(subnet->net_key_upd, value))
return MESH_STATUS_SUCCESS;
+ if (subnet->kr_phase != KEY_REFRESH_PHASE_NONE)
+ return MESH_STATUS_CANNOT_UPDATE;
+
if (subnet->net_key_upd) {
net_key_unref(subnet->net_key_upd);
l_info("Warning: overwriting new keys");
@@ -3734,7 +3737,7 @@ int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
l_info("key refresh phase 1: Key ID %d", subnet->net_key_upd);
- if (!storage_net_key_add(net, idx, value, KEY_REFRESH_PHASE_ONE))
+ if (!storage_net_key_add(net, idx, value, true))
return MESH_STATUS_STORAGE_FAIL;
subnet->kr_phase = KEY_REFRESH_PHASE_ONE;
diff --git a/mesh/node.c b/mesh/node.c
index 1845f9a32..c815acf2e 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -1730,9 +1730,16 @@ bool node_add_pending_local(struct mesh_node *node, void *prov_node_info,
MESH_STATUS_SUCCESS)
return false;
- if (!storage_net_key_add(node->net, info->net_index, info->net_key,
- kr ? KEY_REFRESH_PHASE_TWO : KEY_REFRESH_PHASE_NONE))
- return false;
+ if (kr) {
+ /* Duplicate net key, if the key refresh is on */
+ if (mesh_net_update_key(node->net, info->net_index,
+ info->net_key) != MESH_STATUS_SUCCESS)
+ return false;
+
+ if (!mesh_db_net_key_set_phase(node->jconfig, info->net_index,
+ KEY_REFRESH_PHASE_TWO))
+ return false;
+ }
if (!storage_save_config(node, true, NULL, NULL))
return false;
@@ -1752,7 +1759,7 @@ void node_jconfig_set(struct mesh_node *node, void *jconfig)
void *node_jconfig_get(struct mesh_node *node)
{
- return node->jconfig;
+ return node->jconfig;
}
void node_cfg_file_set(struct mesh_node *node, char *cfg)
diff --git a/mesh/storage.c b/mesh/storage.c
index e1d86960a..d6b566a80 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -296,12 +296,15 @@ bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
}
bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
- const uint8_t key[16], int phase)
+ const uint8_t key[16], bool update)
{
struct mesh_node *node = mesh_net_node_get(net);
json_object *jnode = node_jconfig_get(node);
- return mesh_db_net_key_add(jnode, net_idx, key, phase);
+ if (!update)
+ return mesh_db_net_key_add(jnode, net_idx, key);
+ else
+ return mesh_db_net_key_update(jnode, net_idx, key);
}
bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
diff --git a/mesh/storage.h b/mesh/storage.h
index 7dad2762e..85f7899bc 100644
--- a/mesh/storage.h
+++ b/mesh/storage.h
@@ -33,10 +33,9 @@ bool storage_set_relay(json_object *jnode, bool enable, uint8_t count,
uint8_t interval);
bool storage_set_transmit_params(json_object *jnode, uint8_t count,
uint8_t interval);
-bool storage_set_mode(json_object *jnode, uint8_t mode,
- const char *mode_name);
+bool storage_set_mode(json_object *jnode, uint8_t mode, const char *mode_name);
bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
- const uint8_t key[16], int phase);
+ const uint8_t key[16], bool update);
bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx);
bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
uint16_t app_idx, const uint8_t key[16], bool update);
--
2.17.2
next prev parent reply other threads:[~2019-02-07 4:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-07 3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
2019-02-07 3:55 ` [PATCH BlueZ 1/5 v2] mesh: Separate functions for net key add and update Inga Stotland
2019-02-07 3:55 ` [PATCH BlueZ 2/5 v2] mesh: Add function to restore net key state from storage Inga Stotland
2019-02-07 3:55 ` [PATCH BlueZ 3/5 v2] mesh: Declare internal functions as static Inga Stotland
2019-02-07 3:55 ` [PATCH BlueZ 4/5 v2] mesh: Save key refresh phase state to node config file Inga Stotland
2019-02-07 3:55 ` Inga Stotland [this message]
2019-02-12 23:42 ` [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Gix, Brian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190207035537.20375-6-inga.stotland@intel.com \
--to=inga.stotland@intel.com \
--cc=brian.gix@intel.com \
--cc=johan.hedberg@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).