linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ v5 0/5]  Add possibility to use remote device keys
@ 2019-07-04 12:33 Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models Michał Lowas-Rzechonek
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-04 12:33 UTC (permalink / raw)
  To: linux-bluetooth

+Fix build/checkpatch errors
+Remove unused APP_IDX_NET and APP_IDX_ANY
+Fix handling of incoming packets marked with APP_IDX_DEV_REMOTE
+Fix usage of l_dbus_message_new_method_return
+Fix usage of l_dbus_message_builder APIs


This patchset adds support for sending and receiving messages encrypted
with remote device keys.

This plugs a 'loophole' in the API where it was possible to exchange
such messages using Send()/MessageReceived() API by using 0x7fff app key
index.

In order to allow the application to receive responses from a local
Config Server model, messages originating from a local node and
encrypted using local device key are also forwarded to the application
via D-Bus (assuming they were not handled by one of internal models).

Michał Lowas-Rzechonek (5):
  mesh: Cleanup l_dbus_message_... API usage in models
  mesh: Cleanup D-Bus method returns with empty result
  mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE
  mesh: Implement DevKeySend() method on Node interface
  mesh: Handle messages encrypted with a remote device key

 mesh/cfgmod-server.c |  15 +++---
 mesh/model.c         | 124 ++++++++++++++++++++++++++++++-------------
 mesh/net.h           |   8 +--
 mesh/node.c          |  71 +++++++++++++++++++------
 4 files changed, 154 insertions(+), 64 deletions(-)

-- 
2.19.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models
  2019-07-04 12:33 [PATCH BlueZ v5 0/5] Add possibility to use remote device keys Michał Lowas-Rzechonek
@ 2019-07-04 12:33 ` Michał Lowas-Rzechonek
  2019-07-04 18:00   ` Gix, Brian
  2019-07-04 12:33 ` [PATCH BlueZ v5 2/5] mesh: Cleanup D-Bus method returns with empty result Michał Lowas-Rzechonek
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-04 12:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland

---
 mesh/model.c | 34 ++++++++++++----------------------
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/mesh/model.c b/mesh/model.c
index 7401dcecb..868fe9e52 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -249,10 +249,10 @@ static void config_update_model_pub_period(struct mesh_node *node,
 								&period);
 
 	l_dbus_message_builder_leave_array(builder);
-	if (l_dbus_message_builder_finalize(builder))
-		l_dbus_send(dbus, msg);
-
+	l_dbus_message_builder_finalize(builder);
 	l_dbus_message_builder_destroy(builder);
+
+	l_dbus_send(dbus, msg);
 }
 
 static void append_dict_uint16_array(struct l_dbus_message_builder *builder,
@@ -291,10 +291,10 @@ static void config_update_model_bindings(struct mesh_node *node,
 	append_dict_uint16_array(builder, mod->bindings, "Bindings");
 
 	l_dbus_message_builder_leave_array(builder);
-	if (l_dbus_message_builder_finalize(builder))
-		l_dbus_send(dbus, msg);
-
+	l_dbus_message_builder_finalize(builder);
 	l_dbus_message_builder_destroy(builder);
+
+	l_dbus_send(dbus, msg);
 }
 
 static void forward_model(void *a, void *b)
@@ -714,25 +714,15 @@ static void send_msg_rcvd(struct mesh_node *node, uint8_t ele_idx, bool is_sub,
 
 	builder = l_dbus_message_builder_new(msg);
 
-	if (!l_dbus_message_builder_append_basic(builder, 'q', &src))
-		goto error;
+	l_dbus_message_builder_append_basic(builder, 'q', &src);
+	l_dbus_message_builder_append_basic(builder, 'q', &key_idx);
+	l_dbus_message_builder_append_basic(builder, 'b', &is_sub);
+	dbus_append_byte_array(builder, data, size);
 
-	if (!l_dbus_message_builder_append_basic(builder, 'q', &key_idx))
-		goto error;
-
-	if (!l_dbus_message_builder_append_basic(builder, 'b', &is_sub))
-		goto error;
-
-	if (!dbus_append_byte_array(builder, data, size))
-		goto error;
-
-	if (!l_dbus_message_builder_finalize(builder))
-		goto error;
+	l_dbus_message_builder_finalize(builder);
+	l_dbus_message_builder_destroy(builder);
 
 	l_dbus_send(dbus, msg);
-
-error:
-	l_dbus_message_builder_destroy(builder);
 }
 
 bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ v5 2/5] mesh: Cleanup D-Bus method returns with empty result
  2019-07-04 12:33 [PATCH BlueZ v5 0/5] Add possibility to use remote device keys Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models Michał Lowas-Rzechonek
@ 2019-07-04 12:33 ` Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 3/5] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-04 12:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland

---
 mesh/node.c | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/mesh/node.c b/mesh/node.c
index 1dcb74b4f..53876ef5a 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -1949,7 +1949,6 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus,
 	uint16_t dst, app_idx, src;
 	uint8_t *data;
 	uint32_t len;
-	struct l_dbus_message *reply;
 
 	l_debug("Send");
 
@@ -1978,10 +1977,7 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus,
 				mesh_net_get_default_ttl(node->net), data, len))
 		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
 
-	reply = l_dbus_message_new_method_return(msg);
-	l_dbus_message_set_arguments(reply, "");
-
-	return reply;
+	return l_dbus_message_new_method_return(msg);
 }
 
 static struct l_dbus_message *publish_call(struct l_dbus *dbus,
@@ -1995,7 +1991,6 @@ static struct l_dbus_message *publish_call(struct l_dbus *dbus,
 	struct node_element *ele;
 	uint8_t *data;
 	uint32_t len;
-	struct l_dbus_message *reply;
 	int result;
 
 	l_debug("Publish");
@@ -2027,10 +2022,7 @@ static struct l_dbus_message *publish_call(struct l_dbus *dbus,
 	if (result != MESH_ERROR_NONE)
 		return dbus_error(msg, result, NULL);
 
-	reply = l_dbus_message_new_method_return(msg);
-	l_dbus_message_set_arguments(reply, "");
-
-	return reply;
+	return l_dbus_message_new_method_return(msg);
 }
 
 static struct l_dbus_message *vendor_publish_call(struct l_dbus *dbus,
@@ -2046,7 +2038,6 @@ static struct l_dbus_message *vendor_publish_call(struct l_dbus *dbus,
 	struct node_element *ele;
 	uint8_t *data = NULL;
 	uint32_t len;
-	struct l_dbus_message *reply;
 	int result;
 
 	l_debug("Publish");
@@ -2079,10 +2070,7 @@ static struct l_dbus_message *vendor_publish_call(struct l_dbus *dbus,
 	if (result != MESH_ERROR_NONE)
 		return dbus_error(msg, result, NULL);
 
-	reply = l_dbus_message_new_method_return(msg);
-	l_dbus_message_set_arguments(reply, "");
-
-	return reply;
+	return  l_dbus_message_new_method_return(msg);
 }
 
 static void setup_node_interface(struct l_dbus_interface *iface)
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ v5 3/5] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE
  2019-07-04 12:33 [PATCH BlueZ v5 0/5] Add possibility to use remote device keys Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 2/5] mesh: Cleanup D-Bus method returns with empty result Michał Lowas-Rzechonek
@ 2019-07-04 12:33 ` Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 4/5] mesh: Implement DevKeySend() method on Node interface Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 5/5] mesh: Handle messages encrypted with a remote device key Michał Lowas-Rzechonek
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-04 12:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland, Brian Gix

This is needed to distinguish incoming messages encrypted using a device
key: if the key is local, the message can be forwarded to internal
models. If the key is a known remote one, it will be forwarded to the
application via DevKeyMessageReceived() API.
---
 mesh/cfgmod-server.c | 15 ++++++++-------
 mesh/model.c         | 22 +++++++++++++---------
 mesh/net.h           |  8 ++++----
 3 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 634ac006b..a849b5e99 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -69,7 +69,8 @@ static void send_pub_status(struct mesh_node *node, uint16_t src, uint16_t dst,
 		n += 2;
 	}
 
-	mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n);
+	mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL,
+								msg, n);
 }
 
 static bool config_pub_get(struct mesh_node *node, uint16_t src, uint16_t dst,
@@ -254,7 +255,7 @@ static void send_sub_status(struct mesh_node *node, uint16_t src, uint16_t dst,
 		n += 2;
 	}
 
-	mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n);
+	mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n);
 }
 
 static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst,
@@ -312,7 +313,7 @@ static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst,
 
 	*msg_status = (uint8_t) status;
 
-	mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n);
+	mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n);
 	return true;
 }
 
@@ -487,7 +488,7 @@ static void send_model_app_status(struct mesh_node *node, uint16_t src,
 	l_put_le16(id, msg + n);
 	n += 2;
 
-	mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n);
+	mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n);
 }
 
 static void model_app_list(struct mesh_node *node, uint16_t src, uint16_t dst,
@@ -540,7 +541,7 @@ static void model_app_list(struct mesh_node *node, uint16_t src, uint16_t dst,
 
 	if (result >= 0) {
 		*status = result;
-		mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL,
+		mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL,
 								msg, n);
 	}
 
@@ -758,7 +759,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst,
 	uint16_t interval;
 	uint16_t n;
 
-	if (idx != APP_IDX_DEV)
+	if (idx != APP_IDX_DEV_LOCAL)
 		return false;
 
 	if (mesh_model_opcode_get(pkt, size, &opcode, &n)) {
@@ -1259,7 +1260,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst,
 	if (n) {
 		/* print_packet("App Tx", long_msg ? long_msg : msg, n); */
 		mesh_model_send(node, unicast, src,
-				APP_IDX_DEV, DEFAULT_TTL,
+				APP_IDX_DEV_LOCAL, DEFAULT_TTL,
 				long_msg ? long_msg : msg, n);
 	}
 	l_free(long_msg);
diff --git a/mesh/model.c b/mesh/model.c
index 868fe9e52..ee26a8105 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -306,7 +306,9 @@ static void forward_model(void *a, void *b)
 	bool result;
 
 	l_debug("model %8.8x with idx %3.3x", mod->id, fwd->idx);
-	if (fwd->idx != APP_IDX_DEV && !has_binding(mod->bindings, fwd->idx))
+
+	if (fwd->idx != APP_IDX_DEV_LOCAL &&
+					!has_binding(mod->bindings, fwd->idx))
 		return;
 
 	dst = fwd->dst;
@@ -356,15 +358,15 @@ static int dev_packet_decrypt(struct mesh_node *node, const uint8_t *data,
 				uint16_t dst, uint8_t key_id, uint32_t seq,
 				uint32_t iv_idx, uint8_t *out)
 {
-	const uint8_t *dev_key;
+	const uint8_t *key;
 
-	dev_key = node_get_device_key(node);
-	if (!dev_key)
+	key = node_get_device_key(node);
+	if (!key)
 		return false;
 
 	if (mesh_crypto_payload_decrypt(NULL, 0, data, size, szmict, src,
-					dst, key_id, seq, iv_idx, out, dev_key))
-		return APP_IDX_DEV;
+					dst, key_id, seq, iv_idx, out, key))
+		return APP_IDX_DEV_LOCAL;
 
 	return -1;
 }
@@ -942,7 +944,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
 	if (IS_UNASSIGNED(target))
 		return false;
 
-	if (app_idx == APP_IDX_DEV) {
+	if (app_idx == APP_IDX_DEV_LOCAL) {
 		key = node_get_device_key(node);
 		if (!key)
 			return false;
@@ -1371,12 +1373,14 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
 		if (ele_idx != PRIMARY_ELE_IDX)
 			return NULL;
 
-		l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV));
+		l_queue_push_head(mod->bindings,
+					L_UINT_TO_PTR(APP_IDX_DEV_LOCAL));
 		return mod;
 	}
 
 	if (db_mod->id == CONFIG_CLI_MODEL) {
-		l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV));
+		l_queue_push_head(mod->bindings,
+					L_UINT_TO_PTR(APP_IDX_DEV_LOCAL));
 		return mod;
 	}
 
diff --git a/mesh/net.h b/mesh/net.h
index f19024766..8848e6df0 100644
--- a/mesh/net.h
+++ b/mesh/net.h
@@ -37,10 +37,10 @@ struct mesh_node;
 #define SEQ_MASK	0xffffff
 
 #define CREDFLAG_MASK	0x1000
-#define APP_IDX_MASK	0x0fff
-#define APP_IDX_DEV	0x7fff
-#define APP_IDX_ANY	0x8000
-#define APP_IDX_NET	0xffff
+
+#define APP_IDX_MASK		0x0fff
+#define APP_IDX_DEV_REMOTE	0x6fff
+#define APP_IDX_DEV_LOCAL	0x7fff
 
 #define NET_IDX_INVALID	0xffff
 #define NET_NID_INVALID	0xff
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ v5 4/5] mesh: Implement DevKeySend() method on Node interface
  2019-07-04 12:33 [PATCH BlueZ v5 0/5] Add possibility to use remote device keys Michał Lowas-Rzechonek
                   ` (2 preceding siblings ...)
  2019-07-04 12:33 ` [PATCH BlueZ v5 3/5] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek
@ 2019-07-04 12:33 ` Michał Lowas-Rzechonek
  2019-07-04 12:33 ` [PATCH BlueZ v5 5/5] mesh: Handle messages encrypted with a remote device key Michał Lowas-Rzechonek
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-04 12:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland

This patch implements D-Bus DevKeySend() method of org.bluez.mesh.Node1
interface, allowing the application to send messages encrypted using
a known remote device key.

At the moment the call ignores net_index argument and sends messages
using the primary subnet.

Also, it's no longer possible to use 'magic' key_index value 0x7fff
(denoting local device key) when calling regular Send(). Applications
should use DevKeySend() instead.
---
 mesh/model.c |  9 ++++++++-
 mesh/node.c  | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/mesh/model.c b/mesh/model.c
index ee26a8105..edb820cc9 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -39,6 +39,7 @@
 #include "mesh/dbus.h"
 #include "mesh/util.h"
 #include "mesh/model.h"
+#include "mesh/keyring.h"
 
 /* Divide and round to ceiling (up) to calculate segment count */
 #define CEILDIV(val, div) (((val) + (div) - 1) / (div))
@@ -931,6 +932,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
 					const void *msg, uint16_t msg_len)
 {
 	uint8_t key_id;
+	uint8_t dev_key[16];
 	const uint8_t *key;
 
 	/* print_packet("Mod Tx", msg, msg_len); */
@@ -949,7 +951,12 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
 		if (!key)
 			return false;
 
-		l_debug("(%x)", app_idx);
+		key_id = APP_ID_DEV;
+	} else if (app_idx == APP_IDX_DEV_REMOTE) {
+		if (!keyring_get_remote_dev_key(node, target, dev_key))
+			return false;
+
+		key = dev_key;
 		key_id = APP_ID_DEV;
 	} else {
 		key = appkey_get_key(node_get_net(node), app_idx, &key_id);
diff --git a/mesh/node.c b/mesh/node.c
index 53876ef5a..803bd2f30 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -1973,13 +1973,60 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus,
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
 							"Incorrect data");
 
-	if (!mesh_model_send(node, src, dst, app_idx,
+	if ((app_idx & APP_IDX_MASK) != app_idx)
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
+						"Invalid key_index");
+
+	if (!mesh_model_send(node, src, dst, app_idx & APP_IDX_MASK,
 				mesh_net_get_default_ttl(node->net), data, len))
 		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
 
 	return l_dbus_message_new_method_return(msg);
 }
 
+static struct l_dbus_message *dev_key_send_call(struct l_dbus *dbus,
+						struct l_dbus_message *msg,
+						void *user_data)
+{
+	struct mesh_node *node = user_data;
+	const char *sender, *ele_path;
+	struct l_dbus_message_iter iter_data;
+	struct node_element *ele;
+	uint16_t dst, net_idx, src;
+	uint8_t *data;
+	uint32_t len;
+
+	l_debug("DevKeySend");
+
+	sender = l_dbus_message_get_sender(msg);
+
+	if (strcmp(sender, node->owner))
+		return dbus_error(msg, MESH_ERROR_NOT_AUTHORIZED, NULL);
+
+	if (!l_dbus_message_get_arguments(msg, "oqqay", &ele_path, &dst,
+							&net_idx, &iter_data))
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	ele = l_queue_find(node->elements, match_element_path, ele_path);
+	if (!ele)
+		return dbus_error(msg, MESH_ERROR_NOT_FOUND,
+							"Element not found");
+
+	src = node_get_primary(node) + ele->idx;
+
+	if (!l_dbus_message_iter_get_fixed_array(&iter_data, &data, &len) ||
+					!len || len > MESH_MAX_ACCESS_PAYLOAD)
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
+							"Incorrect data");
+
+	/* TODO: use net_idx */
+	if (!mesh_model_send(node, src, dst, APP_IDX_DEV_REMOTE,
+				mesh_net_get_default_ttl(node->net), data, len))
+		return dbus_error(msg, MESH_ERROR_NOT_FOUND, NULL);
+
+	return l_dbus_message_new_method_return(msg);
+}
+
 static struct l_dbus_message *publish_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
@@ -2077,7 +2124,11 @@ static void setup_node_interface(struct l_dbus_interface *iface)
 {
 	l_dbus_interface_method(iface, "Send", 0, send_call, "", "oqqay",
 						"element_path", "destination",
-						"key", "data");
+						"key_index", "data");
+	l_dbus_interface_method(iface, "DevKeySend", 0, dev_key_send_call,
+						"", "oqqay", "element_path",
+						"destination", "net_index",
+						"data");
 	l_dbus_interface_method(iface, "Publish", 0, publish_call, "", "oqay",
 					"element_path", "model_id", "data");
 	l_dbus_interface_method(iface, "VendorPublish", 0, vendor_publish_call,
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ v5 5/5] mesh: Handle messages encrypted with a remote device key
  2019-07-04 12:33 [PATCH BlueZ v5 0/5] Add possibility to use remote device keys Michał Lowas-Rzechonek
                   ` (3 preceding siblings ...)
  2019-07-04 12:33 ` [PATCH BlueZ v5 4/5] mesh: Implement DevKeySend() method on Node interface Michał Lowas-Rzechonek
@ 2019-07-04 12:33 ` Michał Lowas-Rzechonek
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-04 12:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland

This adds ability to receive messages encrypted using known remote
device key. Such a key must be added to the node's keyring using
ImportRemoteNode() method of org.bluez.mesh.Management1 interface.

Decrypted messages are then forwarded to the application using
DevKeyMessageReceived() D-Bus API.

Also, messages originating from a local node and encrypted using local
device key are forwarde to the application as well, if they weren't
handled by internal model. This allows e.g. receiving status messages
from a local Config Server in the application.
---
 mesh/model.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 55 insertions(+), 6 deletions(-)

diff --git a/mesh/model.c b/mesh/model.c
index edb820cc9..959465cd3 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -308,7 +308,7 @@ static void forward_model(void *a, void *b)
 
 	l_debug("model %8.8x with idx %3.3x", mod->id, fwd->idx);
 
-	if (fwd->idx != APP_IDX_DEV_LOCAL &&
+	if (fwd->idx != APP_IDX_DEV_LOCAL && fwd->idx != APP_IDX_DEV_REMOTE &&
 					!has_binding(mod->bindings, fwd->idx))
 		return;
 
@@ -359,16 +359,25 @@ static int dev_packet_decrypt(struct mesh_node *node, const uint8_t *data,
 				uint16_t dst, uint8_t key_id, uint32_t seq,
 				uint32_t iv_idx, uint8_t *out)
 {
+	uint8_t dev_key[16];
 	const uint8_t *key;
 
 	key = node_get_device_key(node);
 	if (!key)
-		return false;
+		return -1;
 
 	if (mesh_crypto_payload_decrypt(NULL, 0, data, size, szmict, src,
 					dst, key_id, seq, iv_idx, out, key))
 		return APP_IDX_DEV_LOCAL;
 
+	if (!keyring_get_remote_dev_key(node, src, dev_key))
+		return -1;
+
+	key = dev_key;
+	if (mesh_crypto_payload_decrypt(NULL, 0, data, size, szmict, src,
+					dst, key_id, seq, iv_idx, out, key))
+		return APP_IDX_DEV_REMOTE;
+
 	return -1;
 }
 
@@ -695,6 +704,39 @@ static int add_sub(struct mesh_net *net, struct mesh_model *mod,
 	return MESH_STATUS_SUCCESS;
 }
 
+static void send_dev_key_msg_rcvd(struct mesh_node *node, uint8_t ele_idx,
+					uint16_t src, uint16_t net_idx,
+					uint16_t size, const uint8_t *data)
+{
+	struct l_dbus *dbus = dbus_get_bus();
+	struct l_dbus_message *msg;
+	struct l_dbus_message_builder *builder;
+	const char *owner;
+	const char *path;
+
+	owner = node_get_owner(node);
+	path = node_get_element_path(node, ele_idx);
+	if (!path || !owner)
+		return;
+
+	l_debug("Send \"DevKeyMessageReceived\"");
+
+	msg = l_dbus_message_new_method_call(dbus, owner, path,
+						MESH_ELEMENT_INTERFACE,
+						"DevKeyMessageReceived");
+
+	builder = l_dbus_message_builder_new(msg);
+
+	l_dbus_message_builder_append_basic(builder, 'q', &src);
+	l_dbus_message_builder_append_basic(builder, 'q', &net_idx);
+	dbus_append_byte_array(builder, data, size);
+
+	l_dbus_message_builder_finalize(builder);
+	l_dbus_message_builder_destroy(builder);
+
+	l_dbus_send(dbus, msg);
+}
+
 static void send_msg_rcvd(struct mesh_node *node, uint8_t ele_idx, bool is_sub,
 					uint16_t src, uint16_t key_idx,
 					uint16_t size, const uint8_t *data)
@@ -833,10 +875,17 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
 		 * Cycle through external models if the message has not been
 		 * handled by internal models
 		 */
-		if (forward.has_dst && !forward.done)
-			send_msg_rcvd(node, i, is_subscription, src,
-					forward.idx, forward.size,
-					forward.data);
+		if (forward.has_dst && !forward.done) {
+			if ((decrypt_idx & APP_IDX_MASK) == decrypt_idx)
+				send_msg_rcvd(node, i, is_subscription, src,
+						forward.idx, forward.size,
+						forward.data);
+			else if (decrypt_idx == APP_IDX_DEV_REMOTE ||
+				(decrypt_idx == APP_IDX_DEV_LOCAL &&
+				 mesh_net_is_local_address(net, src)))
+				send_dev_key_msg_rcvd(node, i, src, 0,
+						forward.size, forward.data);
+		}
 
 		/*
 		 * Either the message has been processed internally or
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models
  2019-07-04 12:33 ` [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models Michał Lowas-Rzechonek
@ 2019-07-04 18:00   ` Gix, Brian
  0 siblings, 0 replies; 7+ messages in thread
From: Gix, Brian @ 2019-07-04 18:00 UTC (permalink / raw)
  To: michal.lowas-rzechonek, linux-bluetooth; +Cc: Stotland, Inga

Applied entire patch-set *except* patch 1, which is a functional
duplicate of the same l_dbus clean-up that Inga submitted.

This has been run and build tested, but since this affects hard to
reproduce *error* handling, please double-check the final result.



On Thu, 2019-07-04 at 14:33 +0200, Michał Lowas-Rzechonek wrote:
> ---
>  mesh/model.c | 34 ++++++++++++----------------------
>  1 file changed, 12 insertions(+), 22 deletions(-)
> 
> diff --git a/mesh/model.c b/mesh/model.c
> index 7401dcecb..868fe9e52 100644
> --- a/mesh/model.c
> +++ b/mesh/model.c
> @@ -249,10 +249,10 @@ static void
> config_update_model_pub_period(struct mesh_node *node,
>  								&period
> );
>  
>  	l_dbus_message_builder_leave_array(builder);
> -	if (l_dbus_message_builder_finalize(builder))
> -		l_dbus_send(dbus, msg);
> -
> +	l_dbus_message_builder_finalize(builder);
>  	l_dbus_message_builder_destroy(builder);
> +
> +	l_dbus_send(dbus, msg);
>  }
>  
>  static void append_dict_uint16_array(struct l_dbus_message_builder
> *builder,
> @@ -291,10 +291,10 @@ static void config_update_model_bindings(struct
> mesh_node *node,
>  	append_dict_uint16_array(builder, mod->bindings, "Bindings");
>  
>  	l_dbus_message_builder_leave_array(builder);
> -	if (l_dbus_message_builder_finalize(builder))
> -		l_dbus_send(dbus, msg);
> -
> +	l_dbus_message_builder_finalize(builder);
>  	l_dbus_message_builder_destroy(builder);
> +
> +	l_dbus_send(dbus, msg);
>  }
>  
>  static void forward_model(void *a, void *b)
> @@ -714,25 +714,15 @@ static void send_msg_rcvd(struct mesh_node
> *node, uint8_t ele_idx, bool is_sub,
>  
>  	builder = l_dbus_message_builder_new(msg);
>  
> -	if (!l_dbus_message_builder_append_basic(builder, 'q', &src))
> -		goto error;
> +	l_dbus_message_builder_append_basic(builder, 'q', &src);
> +	l_dbus_message_builder_append_basic(builder, 'q', &key_idx);
> +	l_dbus_message_builder_append_basic(builder, 'b', &is_sub);
> +	dbus_append_byte_array(builder, data, size);
>  
> -	if (!l_dbus_message_builder_append_basic(builder, 'q',
> &key_idx))
> -		goto error;
> -
> -	if (!l_dbus_message_builder_append_basic(builder, 'b',
> &is_sub))
> -		goto error;
> -
> -	if (!dbus_append_byte_array(builder, data, size))
> -		goto error;
> -
> -	if (!l_dbus_message_builder_finalize(builder))
> -		goto error;
> +	l_dbus_message_builder_finalize(builder);
> +	l_dbus_message_builder_destroy(builder);
>  
>  	l_dbus_send(dbus, msg);
> -
> -error:
> -	l_dbus_message_builder_destroy(builder);
>  }
>  
>  bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t
> seq0,

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-07-04 18:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-04 12:33 [PATCH BlueZ v5 0/5] Add possibility to use remote device keys Michał Lowas-Rzechonek
2019-07-04 12:33 ` [PATCH BlueZ v5 1/5] mesh: Cleanup l_dbus_message_... API usage in models Michał Lowas-Rzechonek
2019-07-04 18:00   ` Gix, Brian
2019-07-04 12:33 ` [PATCH BlueZ v5 2/5] mesh: Cleanup D-Bus method returns with empty result Michał Lowas-Rzechonek
2019-07-04 12:33 ` [PATCH BlueZ v5 3/5] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek
2019-07-04 12:33 ` [PATCH BlueZ v5 4/5] mesh: Implement DevKeySend() method on Node interface Michał Lowas-Rzechonek
2019-07-04 12:33 ` [PATCH BlueZ v5 5/5] mesh: Handle messages encrypted with a remote device key Michał Lowas-Rzechonek

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