]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
linux: Add nvme_scan_tls_keys()
authorHannes Reinecke <hare@suse.de>
Tue, 27 Feb 2024 07:28:05 +0000 (08:28 +0100)
committerDaniel Wagner <wagi@monom.org>
Thu, 7 Mar 2024 13:49:46 +0000 (14:49 +0100)
Add a function to iterate existing TLS keys in a given keyring.

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

index 79aff78f72370059bd2a92a36baeec767fb26f7b..2751fe6db6a2eed994fa9462f660ecc0cdf8a7f5 100644 (file)
@@ -1244,6 +1244,67 @@ long nvme_update_key(long keyring_id, const char *key_type,
        return key;
 }
 
+struct __scan_keys_data {
+       nvme_scan_tls_keys_cb_t cb;
+       key_serial_t keyring;
+       void *data;
+};
+
+int __scan_keys_cb(key_serial_t parent, key_serial_t key,
+                  char *desc, int desc_len, void *data)
+{
+       struct __scan_keys_data *d = data;
+       int ver, hmac, uid, gid, perm;
+       char type, *ptr;
+
+       if (desc_len < 6)
+               return 0;
+       if (sscanf(desc, "psk;%d;%d;%08x;NVMe%01d%c%02d %*s",
+                  &uid, &gid, &perm, &ver, &type, &hmac) != 6)
+               return 0;
+       /* skip key type */
+       ptr = strchr(desc, ';');
+       if (!ptr)
+               return 0;
+       /* skip key uid */
+       ptr = strchr(ptr + 1, ';');
+       if (!ptr)
+               return 0;
+       /* skip key gid */
+       ptr = strchr(ptr + 1, ';');
+       if (!ptr)
+               return 0;
+       /* skip key permissions */
+       ptr = strchr(ptr + 1, ';');
+       if (!ptr)
+               return 0;
+       /* Only use the key description for the callback */
+       (d->cb)(d->keyring, key, ptr + 1, strlen(ptr) - 1, d->data);
+       return 1;
+}
+
+int nvme_scan_tls_keys(const char *keyring, nvme_scan_tls_keys_cb_t cb,
+                      void *data)
+{
+       struct __scan_keys_data d;
+       key_serial_t keyring_id = nvme_lookup_keyring(keyring);
+       int ret;
+
+       if (!keyring_id) {
+               errno = EINVAL;
+               return -1;
+       }
+       ret = nvme_set_keyring(keyring_id);
+       if (ret < 0)
+               return ret;
+
+       d.keyring = keyring_id;
+       d.cb = cb;
+       d.data = data;
+       ret = recursive_key_scan(keyring_id, __scan_keys_cb, &d);
+       return ret;
+}
+
 long nvme_insert_tls_key_versioned(const char *keyring, const char *key_type,
                                   const char *hostnqn, const char *subsysnqn,
                                   int version, int hmac,
@@ -1341,6 +1402,13 @@ long nvme_update_key(long keyring_id, const char *key_type,
        return 0;
 }
 
+int nvme_scan_tls_keys(const char *keyring, nvme_scan_tls_keys_cb_t cb,
+                      void *data)
+{
+       errno = ENOTSUP;
+       return -1;
+}
+
 long nvme_insert_tls_key_versioned(const char *keyring, const char *key_type,
                                   const char *hostnqn, const char *subsysnqn,
                                   int version, int hmac,
index bf64b7de824df78c02c3e50132f2427c7c683971..bd742620f695fdf8fb995d2b03395cb5d0b038ef 100644 (file)
@@ -308,6 +308,37 @@ long nvme_update_key(long keyring_id, const char *key_type,
                     const char *identity, unsigned char *key_data,
                     int key_len);
 
+/**
+ * typedef nvme_scan_tls_keys_cb_t - Callback for iterating TLS keys
+ * @keyring:   Keyring which has been iterated
+ * @key:       Key for which the callback has been invoked
+ * @desc:      Description of the key
+ * @desc_len:  Length of @desc
+ * @data:      Pointer for caller data
+ *
+ * Called for each TLS PSK in the keyring.
+ */
+typedef void (*nvme_scan_tls_keys_cb_t)(long keyring, long key,
+                                       char *desc, int desc_len, void *data);
+
+/**
+ * nvme_scan_tls_keys() - Iterate over TLS keys in a keyring
+ * @keyring:   Keyring holding TLS keys
+ * @cb:                Callback function
+ * @data:      Pointer for data to be passed to @cb
+ *
+ * Iterates @keyring and call @cb for each TLS key. When @keyring is NULL
+ * the default '.nvme' keyring is used.
+ * A TLS key must be of type 'psk' and the description must be of the
+ * form 'NVMe<0|1><R|G>0<1|2> <identity>', otherwise it will be skipped
+ * during iteration.
+ *
+ * Return: Number of keys for which @cb was called, or -1 with errno set
+ * on error.
+ */
+int nvme_scan_tls_keys(const char *keyring, nvme_scan_tls_keys_cb_t cb,
+                      void *data);
+
 /**
  * nvme_insert_tls_key() - Derive and insert TLS key
  * @keyring:    Keyring to use