aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/crypto/asymmetric_keys/asymmetric_type.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/asymmetric_keys/asymmetric_type.c')
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c102
1 files changed, 94 insertions, 8 deletions
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 6600181d5d01..e4b0ed386bc8 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ctype.h>
+#include <keys/system_keyring.h>
#include "asymmetric_keys.h"
MODULE_LICENSE("GPL");
@@ -451,15 +452,100 @@ static void asymmetric_key_destroy(struct key *key)
asymmetric_key_free_kids(kids);
}
+static struct key_restriction *asymmetric_restriction_alloc(
+ key_restrict_link_func_t check,
+ struct key *key)
+{
+ struct key_restriction *keyres =
+ kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
+
+ if (!keyres)
+ return ERR_PTR(-ENOMEM);
+
+ keyres->check = check;
+ keyres->key = key;
+ keyres->keytype = &key_type_asymmetric;
+
+ return keyres;
+}
+
+/*
+ * look up keyring restrict functions for asymmetric keys
+ */
+static struct key_restriction *asymmetric_lookup_restriction(
+ const char *restriction)
+{
+ char *restrict_method;
+ char *parse_buf;
+ char *next;
+ struct key_restriction *ret = ERR_PTR(-EINVAL);
+
+ if (strcmp("builtin_trusted", restriction) == 0)
+ return asymmetric_restriction_alloc(
+ restrict_link_by_builtin_trusted, NULL);
+
+ if (strcmp("builtin_and_secondary_trusted", restriction) == 0)
+ return asymmetric_restriction_alloc(
+ restrict_link_by_builtin_and_secondary_trusted, NULL);
+
+ parse_buf = kstrndup(restriction, PAGE_SIZE, GFP_KERNEL);
+ if (!parse_buf)
+ return ERR_PTR(-ENOMEM);
+
+ next = parse_buf;
+ restrict_method = strsep(&next, ":");
+
+ if ((strcmp(restrict_method, "key_or_keyring") == 0) && next) {
+ char *key_text;
+ key_serial_t serial;
+ struct key *key;
+ key_restrict_link_func_t link_fn =
+ restrict_link_by_key_or_keyring;
+ bool allow_null_key = false;
+
+ key_text = strsep(&next, ":");
+
+ if (next) {
+ if (strcmp(next, "chain") != 0)
+ goto out;
+
+ link_fn = restrict_link_by_key_or_keyring_chain;
+ allow_null_key = true;
+ }
+
+ if (kstrtos32(key_text, 0, &serial) < 0)
+ goto out;
+
+ if ((serial == 0) && allow_null_key) {
+ key = NULL;
+ } else {
+ key = key_lookup(serial);
+ if (IS_ERR(key)) {
+ ret = ERR_CAST(key);
+ goto out;
+ }
+ }
+
+ ret = asymmetric_restriction_alloc(link_fn, key);
+ if (IS_ERR(ret))
+ key_put(key);
+ }
+
+out:
+ kfree(parse_buf);
+ return ret;
+}
+
struct key_type key_type_asymmetric = {
- .name = "asymmetric",
- .preparse = asymmetric_key_preparse,
- .free_preparse = asymmetric_key_free_preparse,
- .instantiate = generic_key_instantiate,
- .match_preparse = asymmetric_key_match_preparse,
- .match_free = asymmetric_key_match_free,
- .destroy = asymmetric_key_destroy,
- .describe = asymmetric_key_describe,
+ .name = "asymmetric",
+ .preparse = asymmetric_key_preparse,
+ .free_preparse = asymmetric_key_free_preparse,
+ .instantiate = generic_key_instantiate,
+ .match_preparse = asymmetric_key_match_preparse,
+ .match_free = asymmetric_key_match_free,
+ .destroy = asymmetric_key_destroy,
+ .describe = asymmetric_key_describe,
+ .lookup_restriction = asymmetric_lookup_restriction,
};
EXPORT_SYMBOL_GPL(key_type_asymmetric);