[PATCH BlueZ v6 2/2] mesh: Add key storage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This implements internal key storage add/delete/fetch for the three
basic key types managed in Mesh: Network, Application and Device.

This key storage is separate from keys assigned to nodes within the
mesh, and are used to support Configuration Client functionality.
---
 Makefile.mesh  |   1 +
 mesh/keyring.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 mesh/keyring.h |  49 ++++++++++
 3 files changed, 348 insertions(+)
 create mode 100644 mesh/keyring.c
 create mode 100644 mesh/keyring.h

diff --git a/Makefile.mesh b/Makefile.mesh
index 76e424b92..bccd4d946 100644
--- a/Makefile.mesh
+++ b/Makefile.mesh
@@ -25,6 +25,7 @@ mesh_sources = mesh/mesh.h mesh/mesh.c \
 				mesh/agent.h mesh/agent.c \
 				mesh/prov-acceptor.c mesh/prov-initiator.c \
 				mesh/pb-adv.h mesh/pb-adv.c \
+				mesh/keyring.h mesh/keyring.c \
 				mesh/mesh-defs.h
 libexec_PROGRAMS += mesh/bluetooth-meshd
 
diff --git a/mesh/keyring.c b/mesh/keyring.c
new file mode 100644
index 000000000..59aa1eaf4
--- /dev/null
+++ b/mesh/keyring.c
@@ -0,0 +1,298 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2019  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <libgen.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ell/ell.h>
+
+#include "mesh/mesh-defs.h"
+
+#include "mesh/net.h"
+#include "mesh/keyring.h"
+#include "mesh/mesh.h"
+#include "mesh/node.h"
+
+const char *dev_key_dir = "/dev_keys";
+const char *app_key_dir = "/app_keys";
+const char *net_key_dir = "/net_keys";
+
+bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
+						struct keyring_net_key *key)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	bool result = false;
+	int fd;
+
+	if (!node || !key)
+		return false;
+
+	node_path = node_path_get(node);
+
+	if (strlen(node_path) + strlen(net_key_dir) + 1 + 3 >= PATH_MAX)
+		return false;
+
+	snprintf(key_file, PATH_MAX, "%s%s", node_path, net_key_dir);
+	mkdir(key_file, 0755);
+	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
+								net_idx);
+	l_debug("Put Net Key %s", key_file);
+
+	fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
+	if (fd >= 0) {
+		if (write(fd, key, sizeof(*key)) == sizeof(*key))
+			result = true;
+
+		close(fd);
+	}
+
+	return result;
+}
+
+bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
+				uint16_t net_idx, struct keyring_app_key *key)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	bool result = false;
+	int fd;
+
+	if (!node || !key)
+		return false;
+
+	node_path = node_path_get(node);
+
+	if (strlen(node_path) + strlen(app_key_dir) + 1 + 3 >= PATH_MAX)
+		return false;
+
+	snprintf(key_file, PATH_MAX, "%s%s", node_path, app_key_dir);
+	mkdir(key_file, 0755);
+	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
+								app_idx);
+	l_debug("Put App Key %s", key_file);
+
+	fd = open(key_file, O_RDWR);
+	if (fd >= 0) {
+		struct keyring_app_key old_key;
+
+		if (read(fd, &old_key, sizeof(old_key)) == sizeof(old_key)) {
+			if (old_key.net_idx != net_idx) {
+				close(fd);
+				return false;
+			}
+		}
+		lseek(fd, 0, SEEK_SET);
+	} else
+		fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
+
+	if (fd >= 0) {
+		if (write(fd, key, sizeof(*key)) == sizeof(*key))
+			result = true;
+
+		close(fd);
+	}
+
+	return result;
+}
+
+bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+					uint8_t count, uint8_t dev_key[16])
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	bool result = true;
+	int fd, i;
+
+	if (!node)
+		return false;
+
+	node_path = node_path_get(node);
+
+	if (strlen(node_path) + strlen(dev_key_dir) + 1 + 4 >= PATH_MAX)
+		return false;
+
+	snprintf(key_file, PATH_MAX, "%s%s", node_path, dev_key_dir);
+	mkdir(key_file, 0755);
+
+	for (i = 0; i < count; i++) {
+		snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path,
+						dev_key_dir, unicast + i);
+		l_debug("Put Dev Key %s", key_file);
+
+		fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
+		if (fd >= 0) {
+			if (write(fd, dev_key, 16) != 16)
+				result = false;
+
+			close(fd);
+		} else
+			result = false;
+	}
+
+	return result;
+}
+
+bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
+						struct keyring_net_key *key)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	bool result = false;
+	int fd;
+
+	if (!node || !key)
+		return false;
+
+	node_path = node_path_get(node);
+	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
+								net_idx);
+
+	fd = open(key_file, O_RDONLY);
+	if (fd >= 0) {
+		if (read(fd, key, sizeof(*key)) == sizeof(*key))
+			result = true;
+
+		close(fd);
+	}
+
+	return result;
+}
+
+bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
+						struct keyring_app_key *key)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	bool result = false;
+	int fd;
+
+	if (!node || !key)
+		return false;
+
+	node_path = node_path_get(node);
+	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
+								app_idx);
+
+	fd = open(key_file, O_RDONLY);
+	if (fd >= 0) {
+		if (read(fd, key, sizeof(*key)) == sizeof(*key))
+			result = true;
+
+		close(fd);
+	}
+
+	return result;
+}
+
+bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+							uint8_t dev_key[16])
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	bool result = false;
+	int fd;
+
+	if (!node)
+		return false;
+
+	node_path = node_path_get(node);
+	snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, dev_key_dir,
+								unicast);
+
+	fd = open(key_file, O_RDONLY);
+	if (fd >= 0) {
+		if (read(fd, dev_key, 16) == 16)
+			result = true;
+
+		close(fd);
+	}
+
+	return result;
+}
+
+bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+
+	if (!node)
+		return false;
+
+	node_path = node_path_get(node);
+	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
+								net_idx);
+	l_debug("RM Net Key %s", key_file);
+	remove(key_file);
+
+	/* TODO: See if it is easiest to delete all bound App keys here */
+	/* TODO: see nftw() */
+
+	return true;
+}
+
+bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+
+	if (!node)
+		return false;
+
+	node_path = node_path_get(node);
+	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
+								app_idx);
+	l_debug("RM App Key %s", key_file);
+	remove(key_file);
+
+	return true;
+}
+
+bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+								uint8_t count)
+{
+	char *node_path;
+	char key_file[PATH_MAX];
+	int i;
+
+	if (!node)
+		return false;
+
+	node_path = node_path_get(node);
+	for (i = 0; i < count; i++) {
+		snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path,
+						dev_key_dir, unicast + i);
+		l_debug("RM Dev Key %s", key_file);
+		remove(key_file);
+	}
+
+	return true;
+}
diff --git a/mesh/keyring.h b/mesh/keyring.h
new file mode 100644
index 000000000..167191013
--- /dev/null
+++ b/mesh/keyring.h
@@ -0,0 +1,49 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2019  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ */
+
+struct keyring_net_key {
+	uint16_t net_idx;
+	uint8_t phase;
+	uint8_t old_key[16];
+	uint8_t new_key[16];
+};
+
+struct keyring_app_key {
+	uint16_t app_idx;
+	uint16_t net_idx;
+	uint8_t old_key[16];
+	uint8_t new_key[16];
+};
+
+bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
+						struct keyring_net_key *key);
+bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
+						struct keyring_net_key *key);
+bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx);
+bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
+				uint16_t net_idx, struct keyring_app_key *key);
+bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
+						struct keyring_app_key *key);
+bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx);
+bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+							uint8_t dev_key[16]);
+bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+					uint8_t count, uint8_t dev_key[16]);
+bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+								uint8_t count);
-- 
2.14.5




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux