]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
json: import TLS key from PSK interchange format
authorHannes Reinecke <hare@suse.de>
Wed, 21 Feb 2024 14:31:00 +0000 (15:31 +0100)
committerDaniel Wagner <wagi@monom.org>
Thu, 7 Mar 2024 13:49:46 +0000 (14:49 +0100)
As now the JSON configuration file holds the TLS key in PSK interchange
format we should be parsing that key and inserting it into the kernel
keystore to make it available for TLS.

Signed-off-by: Hannes Reinecke <hare@suse.de>
src/nvme/json.c

index 6bd7660bea4664fa358d81c541657ffab56f3b58..ec811e5d2b3e16822e66b6052d93bfdcc43759d8 100644 (file)
 #define JSON_UPDATE_BOOL_OPTION(c, k, a, o)                            \
        if (!strcmp(# a, k ) && !c->a) c->a = json_object_get_boolean(o);
 
+static void json_import_nvme_tls_key(nvme_ctrl_t c, const char *keyring_str,
+                                    const char *encoded_key)
+{
+       struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c);
+       const char *hostnqn = nvme_host_get_hostnqn(c->s->h);
+       const char *subsysnqn = nvme_ctrl_get_subsysnqn(c);
+       int key_len;
+       unsigned int hmac;
+       long key_id;
+       _cleanup_free_ unsigned char *key_data;
+
+       if (!hostnqn || !subsysnqn) {
+               nvme_msg(NULL, LOG_ERR, "Invalid NQNs (%s, %s)\n",
+                        hostnqn, subsysnqn);
+               return;
+       }
+       key_data = nvme_import_tls_key(encoded_key, &key_len, &hmac);
+       if (!key_data) {
+               nvme_msg(NULL, LOG_ERR, "Failed to decode TLS Key '%s'\n",
+                       encoded_key);
+               return;
+       }
+       key_id = nvme_insert_tls_key_versioned(keyring_str, "psk",
+                                              hostnqn, subsysnqn,
+                                              0, hmac, key_data, key_len);
+       if (key_id <= 0)
+               nvme_msg(NULL, LOG_ERR, "Failed to insert TLS KEY, error %d\n",
+                        errno);
+       else {
+               cfg->tls_key = key_id;
+               cfg->tls = true;
+       }
+}
+
 static void json_export_nvme_tls_key(long keyring_id, long tls_key,
                                     struct json_object *obj)
 {
@@ -46,6 +80,7 @@ static void json_update_attributes(nvme_ctrl_t c,
                                   struct json_object *ctrl_obj)
 {
        struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c);
+       const char *keyring_str = NULL, *encoded_key = NULL;
 
        json_object_object_foreach(ctrl_obj, key_str, val_obj) {
                JSON_UPDATE_INT_OPTION(cfg, key_str,
@@ -92,21 +127,24 @@ static void json_update_attributes(nvme_ctrl_t c,
                if (!strcmp("keyring", key_str) && cfg->keyring == 0) {
                        long keyring;
 
-                       keyring = nvme_lookup_keyring(json_object_get_string(val_obj));
+                       keyring_str = json_object_get_string(val_obj);
+                       keyring = nvme_lookup_keyring(keyring_str);
                        if (keyring) {
                                cfg->keyring = keyring;
                                nvme_set_keyring(cfg->keyring);
                        }
                }
-               if (!strcmp("tls_key", key_str) && cfg->tls_key == 0) {
-                       long key;
-
-                       key = nvme_lookup_key("psk",
-                                             json_object_get_string(val_obj));
-                       if (key)
-                               cfg->tls_key = key;
-               }
+               if (!strcmp("tls_key", key_str) && cfg->tls_key == 0)
+                       encoded_key = json_object_get_string(val_obj);
        }
+
+       /*
+        * We might need the keyring information from the above loop,
+        * so we can only import the TLS key once all entries are
+        * processed.
+        */
+       if (encoded_key)
+               json_import_nvme_tls_key(c, keyring_str, encoded_key);
 }
 
 static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj)