]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme-check-tls-key: add options to derive a 'retained' TLS key
authorHannes Reinecke <hare@suse.de>
Wed, 22 Mar 2023 14:58:27 +0000 (15:58 +0100)
committerDaniel Wagner <wagi@monom.org>
Mon, 27 Mar 2023 15:56:52 +0000 (17:56 +0200)
Add options to derive a 'retained' TLS key and store it into the given keyring.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Documentation/nvme-check-tls-key.txt
nvme.c

index 9ef6679ba465ad35665cf458140c4c62352cc678..a676f0436c8eaf9649eff48bfe62a8f9603874a6 100644 (file)
@@ -8,18 +8,42 @@ nvme-check-tls-key - Check a generated NVMe TLS PSK
 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
diff --git a/nvme.c b/nvme.c
index 4c0d44ff7f0cafc7993a4398b398788f2918eb2e..26ddc24dce739a646bab39042dd4bb4cc498fec5 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -8961,24 +8961,41 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
 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()
        };
 
@@ -8986,27 +9003,27 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
        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;
@@ -9016,11 +9033,11 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
                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;
@@ -9039,8 +9056,27 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
                        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;
 }