Skip to content

Commit

Permalink
nvme: add new function 'tls_key'
Browse files Browse the repository at this point in the history
Add a new function 'tls_key' to import and export keys from the
keyring.

Signed-off-by: Hannes Reinecke <[email protected]>
  • Loading branch information
hreinecke committed Mar 19, 2024
1 parent 5c1e9b4 commit 4caa6bd
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
69 changes: 69 additions & 0 deletions Documentation/nvme-tls-key.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
nvme-tls-key(1)
======================

NAME
----
nvme-tls-key - Manage NVMe TLS PSKs

SYNOPSIS
--------
[verse]
'nvme tls-key' [--keyring=<name> | -k <name>]
[--keytype=<type> | -t <type>]
[--keyfile=<file> | -f <file>]
[--import | -i] [--export | -e]
[--verbose | -v]

DESCRIPTION
-----------
Import or export NVMe TLS pre-shared keys (PSKs) from the
system keystore. When the '--export' option is given, all
NVMe TLS PSKs are exported in the form

<descriptions> <psk>

where '<description>' is the key description from the
exported key and '<psk>' is the key data in PSK interchange
format 'NVMeTLSkey-1:01:<base64 encoded data>:'.
Each key is exported in a single line.
When the '--import' option is given key data is read in the
same format and imported into the kernel keystore.

OPTIONS
-------
-k <name>::
--keyring=<name>::
Name of the keyring into which the 'retained' TLS key should be
stored. Default is '.nvme'.

-t <type>::
--keytype=<type>::
Type of the key for resulting TLS key.
Default is 'psk'.

-k <file>::
--keyfile=<file>::
File to read the keys from or write the keys to instead of
stdin / stdout.

-i::
--import::
Read the key data from the file specified by '--keyfile'
or stdin if not present.

-e::
--export::
Write the key data to the file specified by '--keyfile'
or stdou if not present.

-v::
--verbose::
Increase the information detail in the output.

EXAMPLES
--------
No Examples

NVME
----
Part of the nvme-user suite
1 change: 1 addition & 0 deletions nvme-builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ COMMAND_LIST(
ENTRY("check-dhchap-key", "Validate NVMeoF DH-HMAC-CHAP host key", check_dhchap_key)
ENTRY("gen-tls-key", "Generate NVMeoF TLS PSK", gen_tls_key)
ENTRY("check-tls-key", "Validate NVMeoF TLS PSK", check_tls_key)
ENTRY("tls-key", "Manipulate NVMeoF TLS PSK", tls_key)
ENTRY("dir-receive", "Submit a Directive Receive command, return results", dir_receive)
ENTRY("dir-send", "Submit a Directive Send command, return results", dir_send)
ENTRY("virt-mgmt", "Manage Flexible Resources between Primary and Secondary Controller", virtual_mgmt)
Expand Down
118 changes: 118 additions & 0 deletions nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -8776,6 +8776,124 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
return 0;
}

static void __scan_tls_key(long keyring_id, long key_id,
char *desc, int desc_len, void *data)
{
FILE *fd = data;
_cleanup_free_ const unsigned char *key_data = NULL;

Check failure on line 8783 in nvme.c

View workflow job for this annotation

GitHub Actions / checkpatch review

WARNING: Missing a blank line after declarations
_cleanup_free_ char *encoded_key = NULL;
int key_len;

key_data = nvme_read_key(keyring_id, key_id, &key_len);
if (!key_data)
return;
encoded_key = nvme_export_tls_key(key_data, key_len);
if (!encoded_key)
return;
fprintf(fd, "%s %s\n", desc, encoded_key);
}

static int tls_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Manipulation of TLS keys.\n";
const char *keyring = "Keyring for the retained key.";
const char *keytype = "Key type of the retained key.";
const char *keyfile = "File for list of keys.";
const char *import = "Import all keys into the keyring.";
const char *export = "Export all keys from the keyring.";

FILE *fd;
int err = 0;

struct config {
char *keyring;
char *keytype;
char *keyfile;
bool import;
bool export;
};

struct config cfg = {
.keyring = ".nvme",
.keytype = "psk",
.keyfile = NULL,
.import = false,
.export = false,
};

NVME_ARGS(opts,
OPT_STR("keyring", 'k', &cfg.keyring, keyring),
OPT_STR("keytype", 't', &cfg.keytype, keytype),
OPT_STR("keyfile", 'f', &cfg.keyfile, keyfile),
OPT_FLAG("import", 'i', &cfg.import, import),
OPT_FLAG("export", 'e', &cfg.export, export));

err = argconfig_parse(argc, argv, desc, opts);
if (err)
return err;

if (cfg.keyfile) {
fd = fopen(cfg.keyfile, "r");
if (!fd) {
nvme_show_error("Cannot open keyfile %s, error %d\n",
cfg.keyfile, errno);
return -errno;
}
} else
fd = stdin;

if (cfg.export && cfg.import) {
nvme_show_error("Cannot specify both --import and --export");
err = -EINVAL;
} else if (cfg.export) {
nvme_scan_tls_keys(cfg.keyring, __scan_tls_key, fd);
} else if (cfg.import) {
long keyring_id;
char tls_str[512];
char *tls_key;
unsigned char *psk;
unsigned int hmac;
int linenum = -1, key_len;

keyring_id = nvme_lookup_keyring(cfg.keyring);
if (!keyring_id) {
nvme_show_error("Invalid keyring '%s'", cfg.keyring);
err = -ENOKEY;
goto out;
}

while (fgets(tls_str, 512, fd)) {
linenum++;
tls_key = strrchr(tls_str, ' ');
if (!tls_key) {
nvme_show_error("Parse error in line %d",
linenum);
continue;
}
*tls_key = '\0';
tls_key++;
psk = nvme_import_tls_key(tls_key, &key_len, &hmac);
if (!psk) {
nvme_show_error("Failed to import key in line %d",
linenum);
continue;
}
nvme_update_key(keyring_id, "psk", tls_str,
psk, key_len);
free(psk);
}
} else {
nvme_show_error("Must specify either --import or --export");
err = -EINVAL;
}

out:
if (cfg.keyfile)
fclose(fd);

return err;
}

static int show_topology_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Show the topology\n";
Expand Down

0 comments on commit 4caa6bd

Please sign in to comment.