SYNOPSIS
--------
[verse]
-'nvme check-tls-key' [--key=<key> ]
+'nvme check-tls-key' [--keyring=<name> | -k <name> ]
+ [--keytype=<type> | -t <type> ]
+ [--hostnqn=<nqn> | -n <nqn> ]
+ [--subsysnqn=<nqn> | -c <nqn> ]
+ [--keydata=<key> | -d <key> ]
DESCRIPTION
-----------
Checks if the key is a valid NVMe TLS PSK in the PSK interchange format
-NVMeTLSkey-1:01:VRLbtnN9AQb2WXW3c9+wEf/DRLz0QuLdbYvEhwtdWwNf9LrZ:
-
+'NVMeTLSkey-1:01:<base64-encoded data>:', and stores the derived 'retained'
+TLS key in the keyring if the subsystem NQN is specified.
OPTIONS
-------
--k <key>::
---key=<key>::
+-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'.
+
+-n <nqn>::
+--hostnqn=<nqn>::
+ Host NVMe Qualified Name (NQN) to be used to derive the
+ 'retained' TLS key
+
+-c <nqn>::
+--subsysnqn=<nqn>::
+ Subsystem NVMe Qualified Name (NQN) to be used to derive the
+ 'retained' TLS key
+
+-d <key>::
+--keydata=<key>::
Key to be checked.
EXAMPLES
static int check_tls_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Check a TLS key for NVMe PSK Interchange format.\n";
- const char *key = "TLS key (in PSK Interchange format) "\
+ const char *keydata = "TLS key (in PSK Interchange format) "\
"to be validated.";
+ const char *hostnqn = "Host NQN for the retained key.";
+ const char *subsysnqn = "Subsystem NQN for the retained key.";
+ const char *keyring = "Keyring for the retained key.";
+ const char *keytype = "Key type of the retained key.";
unsigned char decoded_key[128];
unsigned int decoded_len;
u_int32_t crc = crc32(0L, NULL, 0);
u_int32_t key_crc;
int err = 0, hmac;
+ long tls_key;
struct config {
- char *key;
+ char *keyring;
+ char *keytype;
+ char *hostnqn;
+ char *subsysnqn;
+ char *keydata;
};
struct config cfg = {
- .key = NULL,
+ .keyring = ".nvme",
+ .keytype = "psk",
+ .hostnqn = NULL,
+ .subsysnqn = NULL,
+ .keydata = NULL,
};
OPT_ARGS(opts) = {
- OPT_STR("key", 'k', &cfg.key, key),
+ OPT_STR("keyring", 'k', &cfg.keyring, keyring),
+ OPT_STR("keytype", 't', &cfg.keytype, keytype),
+ OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
+ OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
+ OPT_STR("keydata", 'd', &cfg.keydata, keydata),
OPT_END()
};
if (err)
return err;
- if (!cfg.key) {
- fprintf(stderr, "Key not specified\n");
+ if (!cfg.keydata) {
+ fprintf(stderr, "No key data\n");
return -EINVAL;
}
- if (sscanf(cfg.key, "NVMeTLSkey-1:%02x:*s", &hmac) != 1) {
- fprintf(stderr, "Invalid key header '%s'\n", cfg.key);
+ if (sscanf(cfg.keydata, "NVMeTLSkey-1:%02x:*s", &hmac) != 1) {
+ fprintf(stderr, "Invalid key '%s'\n", cfg.keydata);
return -EINVAL;
}
switch (hmac) {
case 1:
- if (strlen(cfg.key) != 65) {
+ if (strlen(cfg.keydata) != 65) {
fprintf(stderr, "Invalid key length %zu for SHA(256)\n",
- strlen(cfg.key));
+ strlen(cfg.keydata));
return -EINVAL;
}
break;
case 2:
- if (strlen(cfg.key) != 89) {
+ if (strlen(cfg.keydata) != 89) {
fprintf(stderr, "Invalid key length %zu for SHA(384)\n",
- strlen(cfg.key));
+ strlen(cfg.keydata));
return -EINVAL;
}
break;
break;
}
- err = base64_decode(cfg.key + 16, strlen(cfg.key) - 17,
+ err = base64_decode(cfg.keydata + 16, strlen(cfg.keydata) - 17,
decoded_key);
if (err < 0) {
fprintf(stderr, "Base64 decoding failed (%s, error %d)\n",
- cfg.key + 16, err);
+ cfg.keydata + 16, err);
return err;
}
decoded_len = err;
key_crc, crc);
return -EINVAL;
}
- printf("Key is valid (HMAC %d, length %d, CRC %08x)\n",
- hmac, decoded_len, crc);
+ if (cfg.subsysnqn) {
+ if (!cfg.hostnqn) {
+ cfg.hostnqn = nvmf_hostnqn_from_file();
+ if (!cfg.hostnqn) {
+ fprintf(stderr,
+ "Failed to read host NQN\n");
+ return -EINVAL;
+ }
+ }
+
+ tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype,
+ cfg.hostnqn, cfg.subsysnqn, hmac,
+ decoded_key, decoded_len);
+ if (tls_key < 0) {
+ fprintf(stderr,
+ "Failed to insert key, error %d\n", errno);
+ return -errno;
+ }
+ } else
+ printf("Key is valid (HMAC %d, length %d, CRC %08x)\n",
+ hmac, decoded_len, crc);
return 0;
}