]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blobdiff - crypto/asymmetric_keys/asymmetric_type.c
KEYS: Implement asymmetric key type
[can-eth-gw-linux.git] / crypto / asymmetric_keys / asymmetric_type.c
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
new file mode 100644 (file)
index 0000000..bfb0424
--- /dev/null
@@ -0,0 +1,156 @@
+/* Asymmetric public-key cryptography key type
+ *
+ * See Documentation/security/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#include <keys/asymmetric-subtype.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "asymmetric_keys.h"
+
+MODULE_LICENSE("GPL");
+
+/*
+ * Match asymmetric keys on (part of) their name
+ * We have some shorthand methods for matching keys.  We allow:
+ *
+ *     "<desc>"        - request a key by description
+ *     "id:<id>"       - request a key matching the ID
+ *     "<subtype>:<id>" - request a key of a subtype
+ */
+static int asymmetric_key_match(const struct key *key, const void *description)
+{
+       const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
+       const char *spec = description;
+       const char *id, *kid;
+       ptrdiff_t speclen;
+       size_t idlen, kidlen;
+
+       if (!subtype || !spec || !*spec)
+               return 0;
+
+       /* See if the full key description matches as is */
+       if (key->description && strcmp(key->description, description) == 0)
+               return 1;
+
+       /* All tests from here on break the criterion description into a
+        * specifier, a colon and then an identifier.
+        */
+       id = strchr(spec, ':');
+       if (!id)
+               return 0;
+
+       speclen = id - spec;
+       id++;
+
+       /* Anything after here requires a partial match on the ID string */
+       kid = asymmetric_key_id(key);
+       if (!kid)
+               return 0;
+
+       idlen = strlen(id);
+       kidlen = strlen(kid);
+       if (idlen > kidlen)
+               return 0;
+
+       kid += kidlen - idlen;
+       if (strcasecmp(id, kid) != 0)
+               return 0;
+
+       if (speclen == 2 &&
+           memcmp(spec, "id", 2) == 0)
+               return 1;
+
+       if (speclen == subtype->name_len &&
+           memcmp(spec, subtype->name, speclen) == 0)
+               return 1;
+
+       return 0;
+}
+
+/*
+ * Describe the asymmetric key
+ */
+static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
+{
+       const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
+       const char *kid = asymmetric_key_id(key);
+       size_t n;
+
+       seq_puts(m, key->description);
+
+       if (subtype) {
+               seq_puts(m, ": ");
+               subtype->describe(key, m);
+
+               if (kid) {
+                       seq_putc(m, ' ');
+                       n = strlen(kid);
+                       if (n <= 8)
+                               seq_puts(m, kid);
+                       else
+                               seq_puts(m, kid + n - 8);
+               }
+
+               seq_puts(m, " [");
+               /* put something here to indicate the key's capabilities */
+               seq_putc(m, ']');
+       }
+}
+
+/*
+ * Instantiate a asymmetric_key defined key.  The key was preparsed, so we just
+ * have to transfer the data here.
+ */
+static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
+{
+       return -EOPNOTSUPP;
+}
+
+/*
+ * dispose of the data dangling from the corpse of a asymmetric key
+ */
+static void asymmetric_key_destroy(struct key *key)
+{
+       struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
+       if (subtype) {
+               subtype->destroy(key->payload.data);
+               module_put(subtype->owner);
+               key->type_data.p[0] = NULL;
+       }
+       kfree(key->type_data.p[1]);
+       key->type_data.p[1] = NULL;
+}
+
+struct key_type key_type_asymmetric = {
+       .name           = "asymmetric",
+       .instantiate    = asymmetric_key_instantiate,
+       .match          = asymmetric_key_match,
+       .destroy        = asymmetric_key_destroy,
+       .describe       = asymmetric_key_describe,
+};
+EXPORT_SYMBOL_GPL(key_type_asymmetric);
+
+/*
+ * Module stuff
+ */
+static int __init asymmetric_key_init(void)
+{
+       return register_key_type(&key_type_asymmetric);
+}
+
+static void __exit asymmetric_key_cleanup(void)
+{
+       unregister_key_type(&key_type_asymmetric);
+}
+
+module_init(asymmetric_key_init);
+module_exit(asymmetric_key_cleanup);