linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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).