xref: /spdk/module/keyring/file/keyring.c (revision e93c991503c742297c066b07913baa76c6dcacf7)
18db51b4eSKonrad Sztyber /* SPDX-License-Identifier: BSD-3-Clause
28db51b4eSKonrad Sztyber  * Copyright (c) 2024 Intel Corporation. All rights reserved.
38db51b4eSKonrad Sztyber  */
48db51b4eSKonrad Sztyber 
58db51b4eSKonrad Sztyber #include "spdk/keyring_module.h"
6*e93c9915SKonrad Sztyber #include "spdk/module/keyring/file.h"
78db51b4eSKonrad Sztyber #include "spdk/log.h"
88db51b4eSKonrad Sztyber #include "spdk/string.h"
98db51b4eSKonrad Sztyber #include "spdk/util.h"
108db51b4eSKonrad Sztyber 
118db51b4eSKonrad Sztyber struct keyring_file_key {
128db51b4eSKonrad Sztyber 	char *path;
138db51b4eSKonrad Sztyber };
148db51b4eSKonrad Sztyber 
15*e93c9915SKonrad Sztyber static struct spdk_keyring_module g_keyring_file;
16*e93c9915SKonrad Sztyber 
178db51b4eSKonrad Sztyber static int
188db51b4eSKonrad Sztyber keyring_file_check_path(const char *path, int *size)
198db51b4eSKonrad Sztyber {
208db51b4eSKonrad Sztyber 	struct stat st;
218db51b4eSKonrad Sztyber 	int rc, errsv;
228db51b4eSKonrad Sztyber 
238db51b4eSKonrad Sztyber 	if (path[0] != '/') {
248db51b4eSKonrad Sztyber 		SPDK_ERRLOG("Non-absolute paths are not allowed: %s\n", path);
258db51b4eSKonrad Sztyber 		return -EPERM;
268db51b4eSKonrad Sztyber 	}
278db51b4eSKonrad Sztyber 
288db51b4eSKonrad Sztyber 	rc = stat(path, &st);
298db51b4eSKonrad Sztyber 	if (rc != 0) {
308db51b4eSKonrad Sztyber 		errsv = errno;
318db51b4eSKonrad Sztyber 		SPDK_ERRLOG("Could not stat key file '%s': %s\n", path, spdk_strerror(errsv));
328db51b4eSKonrad Sztyber 		return -errsv;
338db51b4eSKonrad Sztyber 	}
348db51b4eSKonrad Sztyber 
358db51b4eSKonrad Sztyber 	if ((st.st_mode & 077) || st.st_uid != getuid()) {
368db51b4eSKonrad Sztyber 		SPDK_ERRLOG("Invalid permissions for key file '%s': 0%o\n", path, st.st_mode);
378db51b4eSKonrad Sztyber 		return -EPERM;
388db51b4eSKonrad Sztyber 	}
398db51b4eSKonrad Sztyber 
408db51b4eSKonrad Sztyber 	if (size != NULL) {
418db51b4eSKonrad Sztyber 		*size = st.st_size;
428db51b4eSKonrad Sztyber 	}
438db51b4eSKonrad Sztyber 
448db51b4eSKonrad Sztyber 	return 0;
458db51b4eSKonrad Sztyber }
468db51b4eSKonrad Sztyber 
4705172c75SKonrad Sztyber static void
4805172c75SKonrad Sztyber keyring_file_write_key_config(void *ctx, struct spdk_key *key)
4905172c75SKonrad Sztyber {
5005172c75SKonrad Sztyber 	struct spdk_json_write_ctx *w = ctx;
5105172c75SKonrad Sztyber 	struct keyring_file_key *kkey;
5205172c75SKonrad Sztyber 
5305172c75SKonrad Sztyber 	if (spdk_key_get_module(key) != &g_keyring_file) {
5405172c75SKonrad Sztyber 		return;
5505172c75SKonrad Sztyber 	}
5605172c75SKonrad Sztyber 
5705172c75SKonrad Sztyber 	kkey = spdk_key_get_ctx(key);
5805172c75SKonrad Sztyber 
5905172c75SKonrad Sztyber 	spdk_json_write_object_begin(w);
6005172c75SKonrad Sztyber 	spdk_json_write_named_string(w, "method", "keyring_file_add_key");
6105172c75SKonrad Sztyber 	spdk_json_write_named_object_begin(w, "params");
6205172c75SKonrad Sztyber 	spdk_json_write_named_string(w, "name", spdk_key_get_name(key));
6305172c75SKonrad Sztyber 	spdk_json_write_named_string(w, "path", kkey->path);
6405172c75SKonrad Sztyber 	spdk_json_write_object_end(w);
6505172c75SKonrad Sztyber 	spdk_json_write_object_end(w);
6605172c75SKonrad Sztyber }
6705172c75SKonrad Sztyber 
6805172c75SKonrad Sztyber static void
6905172c75SKonrad Sztyber keyring_file_write_config(struct spdk_json_write_ctx *w)
7005172c75SKonrad Sztyber {
7105172c75SKonrad Sztyber 	spdk_keyring_for_each_key(NULL, w, keyring_file_write_key_config, 0);
7205172c75SKonrad Sztyber }
7305172c75SKonrad Sztyber 
7405172c75SKonrad Sztyber static void
7505172c75SKonrad Sztyber keyring_file_dump_info(struct spdk_key *key, struct spdk_json_write_ctx *w)
7605172c75SKonrad Sztyber {
7705172c75SKonrad Sztyber 	struct keyring_file_key *kkey = spdk_key_get_ctx(key);
7805172c75SKonrad Sztyber 
7905172c75SKonrad Sztyber 	spdk_json_write_named_string(w, "path", kkey->path);
8005172c75SKonrad Sztyber }
8105172c75SKonrad Sztyber 
828db51b4eSKonrad Sztyber static size_t
838db51b4eSKonrad Sztyber keyring_file_get_ctx_size(void)
848db51b4eSKonrad Sztyber {
858db51b4eSKonrad Sztyber 	return sizeof(struct keyring_file_key);
868db51b4eSKonrad Sztyber }
878db51b4eSKonrad Sztyber 
888db51b4eSKonrad Sztyber static int
898db51b4eSKonrad Sztyber keyring_file_get_key(struct spdk_key *key, void *buf, int len)
908db51b4eSKonrad Sztyber {
918db51b4eSKonrad Sztyber 	struct keyring_file_key *kkey = spdk_key_get_ctx(key);
928db51b4eSKonrad Sztyber 	FILE *file;
938db51b4eSKonrad Sztyber 	int rc, errsv, size = 0;
948db51b4eSKonrad Sztyber 
958db51b4eSKonrad Sztyber 	rc = keyring_file_check_path(kkey->path, &size);
968db51b4eSKonrad Sztyber 	if (rc != 0) {
978db51b4eSKonrad Sztyber 		return rc;
988db51b4eSKonrad Sztyber 	}
998db51b4eSKonrad Sztyber 
1008db51b4eSKonrad Sztyber 	if (size > len) {
1018db51b4eSKonrad Sztyber 		SPDK_ERRLOG("Invalid key '%s' size: %d > %d\n", spdk_key_get_name(key), size, len);
1028db51b4eSKonrad Sztyber 		return -ENOBUFS;
1038db51b4eSKonrad Sztyber 	}
1048db51b4eSKonrad Sztyber 
1058db51b4eSKonrad Sztyber 	file = fopen(kkey->path, "r");
1068db51b4eSKonrad Sztyber 	if (!file) {
1078db51b4eSKonrad Sztyber 		errsv = errno;
1088db51b4eSKonrad Sztyber 		SPDK_ERRLOG("Could not open key '%s': %s\n", spdk_key_get_name(key),
1098db51b4eSKonrad Sztyber 			    spdk_strerror(errsv));
1108db51b4eSKonrad Sztyber 		return -errsv;
1118db51b4eSKonrad Sztyber 	}
1128db51b4eSKonrad Sztyber 
1138db51b4eSKonrad Sztyber 	rc = (int)fread(buf, 1, size, file);
1148db51b4eSKonrad Sztyber 	if (rc != size) {
1158db51b4eSKonrad Sztyber 		SPDK_ERRLOG("Could not load key '%s'\n", spdk_key_get_name(key));
1168db51b4eSKonrad Sztyber 		rc = -EIO;
1178db51b4eSKonrad Sztyber 	}
1188db51b4eSKonrad Sztyber 
1198db51b4eSKonrad Sztyber 	fclose(file);
1208db51b4eSKonrad Sztyber 
1218db51b4eSKonrad Sztyber 	return rc;
1228db51b4eSKonrad Sztyber }
1238db51b4eSKonrad Sztyber 
1248db51b4eSKonrad Sztyber static void
1258db51b4eSKonrad Sztyber keyring_file_remove_key(struct spdk_key *key)
1268db51b4eSKonrad Sztyber {
1278db51b4eSKonrad Sztyber 	struct keyring_file_key *kkey = spdk_key_get_ctx(key);
1288db51b4eSKonrad Sztyber 
1298db51b4eSKonrad Sztyber 	free(kkey->path);
1308db51b4eSKonrad Sztyber }
1318db51b4eSKonrad Sztyber 
1328db51b4eSKonrad Sztyber static int
1338db51b4eSKonrad Sztyber keyring_file_add_key(struct spdk_key *key, void *ctx)
1348db51b4eSKonrad Sztyber {
1358db51b4eSKonrad Sztyber 	struct keyring_file_key *kkey = spdk_key_get_ctx(key);
136*e93c9915SKonrad Sztyber 	const char *path = ctx;
1378db51b4eSKonrad Sztyber 	int rc;
1388db51b4eSKonrad Sztyber 
139*e93c9915SKonrad Sztyber 	rc = keyring_file_check_path(path, NULL);
1408db51b4eSKonrad Sztyber 	if (rc != 0) {
1418db51b4eSKonrad Sztyber 		return rc;
1428db51b4eSKonrad Sztyber 	}
1438db51b4eSKonrad Sztyber 
144*e93c9915SKonrad Sztyber 	kkey->path = strdup(path);
1458db51b4eSKonrad Sztyber 	if (kkey->path == NULL) {
1468db51b4eSKonrad Sztyber 		return -ENOMEM;
1478db51b4eSKonrad Sztyber 	}
1488db51b4eSKonrad Sztyber 
1498db51b4eSKonrad Sztyber 	return 0;
1508db51b4eSKonrad Sztyber }
1518db51b4eSKonrad Sztyber 
152*e93c9915SKonrad Sztyber int
153*e93c9915SKonrad Sztyber spdk_keyring_file_add_key(const char *name, const char *path)
154*e93c9915SKonrad Sztyber {
155*e93c9915SKonrad Sztyber 	struct spdk_key_opts opts = {};
156*e93c9915SKonrad Sztyber 
157*e93c9915SKonrad Sztyber 	opts.size = SPDK_SIZEOF(&opts, ctx);
158*e93c9915SKonrad Sztyber 	opts.name = name;
159*e93c9915SKonrad Sztyber 	opts.module = &g_keyring_file;
160*e93c9915SKonrad Sztyber 	opts.ctx = (void *)path;
161*e93c9915SKonrad Sztyber 
162*e93c9915SKonrad Sztyber 	return spdk_keyring_add_key(&opts);
163*e93c9915SKonrad Sztyber }
164*e93c9915SKonrad Sztyber 
165*e93c9915SKonrad Sztyber int
166*e93c9915SKonrad Sztyber spdk_keyring_file_remove_key(const char *name)
167*e93c9915SKonrad Sztyber {
168*e93c9915SKonrad Sztyber 	return spdk_keyring_remove_key(name, &g_keyring_file);
169*e93c9915SKonrad Sztyber }
170*e93c9915SKonrad Sztyber 
171*e93c9915SKonrad Sztyber static struct spdk_keyring_module g_keyring_file = {
1728db51b4eSKonrad Sztyber 	.name = "keyring_file",
1738db51b4eSKonrad Sztyber 	.add_key = keyring_file_add_key,
1748db51b4eSKonrad Sztyber 	.remove_key = keyring_file_remove_key,
1758db51b4eSKonrad Sztyber 	.get_key = keyring_file_get_key,
1768db51b4eSKonrad Sztyber 	.get_ctx_size = keyring_file_get_ctx_size,
17705172c75SKonrad Sztyber 	.dump_info = keyring_file_dump_info,
17805172c75SKonrad Sztyber 	.write_config = keyring_file_write_config,
1798db51b4eSKonrad Sztyber };
1808db51b4eSKonrad Sztyber 
1818db51b4eSKonrad Sztyber SPDK_KEYRING_REGISTER_MODULE(keyring_file, &g_keyring_file);
182