1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Testing module to load key from trusted PKCS#7 message
3  *
4  * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #define pr_fmt(fmt) "PKCS7key: "fmt
9 #include <linux/key.h>
10 #include <linux/err.h>
11 #include <linux/module.h>
12 #include <linux/verification.h>
13 #include <linux/key-type.h>
14 #include <keys/user-type.h>
15 
16 MODULE_LICENSE("GPL");
17 MODULE_DESCRIPTION("PKCS#7 testing key type");
18 MODULE_AUTHOR("Red Hat, Inc.");
19 
20 static unsigned pkcs7_usage;
21 module_param_named(usage, pkcs7_usage, uint, S_IWUSR | S_IRUGO);
22 MODULE_PARM_DESC(pkcs7_usage,
23 		 "Usage to specify when verifying the PKCS#7 message");
24 
25 /*
26  * Retrieve the PKCS#7 message content.
27  */
pkcs7_view_content(void * ctx,const void * data,size_t len,size_t asn1hdrlen)28 static int pkcs7_view_content(void *ctx, const void *data, size_t len,
29 			      size_t asn1hdrlen)
30 {
31 	struct key_preparsed_payload *prep = ctx;
32 	const void *saved_prep_data;
33 	size_t saved_prep_datalen;
34 	int ret;
35 
36 	saved_prep_data = prep->data;
37 	saved_prep_datalen = prep->datalen;
38 	prep->data = data;
39 	prep->datalen = len;
40 
41 	ret = user_preparse(prep);
42 
43 	prep->data = saved_prep_data;
44 	prep->datalen = saved_prep_datalen;
45 	return ret;
46 }
47 
48 /*
49  * Preparse a PKCS#7 wrapped and validated data blob.
50  */
pkcs7_preparse(struct key_preparsed_payload * prep)51 static int pkcs7_preparse(struct key_preparsed_payload *prep)
52 {
53 	enum key_being_used_for usage = pkcs7_usage;
54 
55 	if (usage >= NR__KEY_BEING_USED_FOR) {
56 		pr_err("Invalid usage type %d\n", usage);
57 		return -EINVAL;
58 	}
59 
60 	return verify_pkcs7_signature(NULL, 0,
61 				      prep->data, prep->datalen,
62 				      VERIFY_USE_SECONDARY_KEYRING, usage,
63 				      pkcs7_view_content, prep);
64 }
65 
66 /*
67  * user defined keys take an arbitrary string as the description and an
68  * arbitrary blob of data as the payload
69  */
70 static struct key_type key_type_pkcs7 = {
71 	.name			= "pkcs7_test",
72 	.preparse		= pkcs7_preparse,
73 	.free_preparse		= user_free_preparse,
74 	.instantiate		= generic_key_instantiate,
75 	.revoke			= user_revoke,
76 	.destroy		= user_destroy,
77 	.describe		= user_describe,
78 	.read			= user_read,
79 };
80 
81 /*
82  * Module stuff
83  */
pkcs7_key_init(void)84 static int __init pkcs7_key_init(void)
85 {
86 	return register_key_type(&key_type_pkcs7);
87 }
88 
pkcs7_key_cleanup(void)89 static void __exit pkcs7_key_cleanup(void)
90 {
91 	unregister_key_type(&key_type_pkcs7);
92 }
93 
94 module_init(pkcs7_key_init);
95 module_exit(pkcs7_key_cleanup);
96