GNU Linux-libre 5.10.217-gnu1
[releases.git] / certs / system_keyring.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* System trusted keyring for trusted public keys
3  *
4  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7
8 #include <linux/export.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/cred.h>
12 #include <linux/err.h>
13 #include <linux/slab.h>
14 #include <linux/verification.h>
15 #include <keys/asymmetric-type.h>
16 #include <keys/system_keyring.h>
17 #include <crypto/pkcs7.h>
18 #include "common.h"
19
20 static struct key *builtin_trusted_keys;
21 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
22 static struct key *secondary_trusted_keys;
23 #endif
24 #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
25 static struct key *platform_trusted_keys;
26 #endif
27
28 extern __initconst const u8 system_certificate_list[];
29 extern __initconst const unsigned long system_certificate_list_size;
30
31 /**
32  * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
33  *
34  * Restrict the addition of keys into a keyring based on the key-to-be-added
35  * being vouched for by a key in the built in system keyring.
36  */
37 int restrict_link_by_builtin_trusted(struct key *dest_keyring,
38                                      const struct key_type *type,
39                                      const union key_payload *payload,
40                                      struct key *restriction_key)
41 {
42         return restrict_link_by_signature(dest_keyring, type, payload,
43                                           builtin_trusted_keys);
44 }
45
46 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
47 /**
48  * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
49  *   addition by both builtin and secondary keyrings
50  *
51  * Restrict the addition of keys into a keyring based on the key-to-be-added
52  * being vouched for by a key in either the built-in or the secondary system
53  * keyrings.
54  */
55 int restrict_link_by_builtin_and_secondary_trusted(
56         struct key *dest_keyring,
57         const struct key_type *type,
58         const union key_payload *payload,
59         struct key *restrict_key)
60 {
61         /* If we have a secondary trusted keyring, then that contains a link
62          * through to the builtin keyring and the search will follow that link.
63          */
64         if (type == &key_type_keyring &&
65             dest_keyring == secondary_trusted_keys &&
66             payload == &builtin_trusted_keys->payload)
67                 /* Allow the builtin keyring to be added to the secondary */
68                 return 0;
69
70         return restrict_link_by_signature(dest_keyring, type, payload,
71                                           secondary_trusted_keys);
72 }
73
74 /**
75  * Allocate a struct key_restriction for the "builtin and secondary trust"
76  * keyring. Only for use in system_trusted_keyring_init().
77  */
78 static __init struct key_restriction *get_builtin_and_secondary_restriction(void)
79 {
80         struct key_restriction *restriction;
81
82         restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
83
84         if (!restriction)
85                 panic("Can't allocate secondary trusted keyring restriction\n");
86
87         restriction->check = restrict_link_by_builtin_and_secondary_trusted;
88
89         return restriction;
90 }
91 #endif
92
93 /*
94  * Create the trusted keyrings
95  */
96 static __init int system_trusted_keyring_init(void)
97 {
98         pr_notice("Initialise system trusted keyrings\n");
99
100         builtin_trusted_keys =
101                 keyring_alloc(".builtin_trusted_keys",
102                               KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
103                               ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
104                               KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
105                               KEY_ALLOC_NOT_IN_QUOTA,
106                               NULL, NULL);
107         if (IS_ERR(builtin_trusted_keys))
108                 panic("Can't allocate builtin trusted keyring\n");
109
110 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
111         secondary_trusted_keys =
112                 keyring_alloc(".secondary_trusted_keys",
113                               KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
114                               ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
115                                KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
116                                KEY_USR_WRITE),
117                               KEY_ALLOC_NOT_IN_QUOTA,
118                               get_builtin_and_secondary_restriction(),
119                               NULL);
120         if (IS_ERR(secondary_trusted_keys))
121                 panic("Can't allocate secondary trusted keyring\n");
122
123         if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0)
124                 panic("Can't link trusted keyrings\n");
125 #endif
126
127         return 0;
128 }
129
130 /*
131  * Must be initialised before we try and load the keys into the keyring.
132  */
133 device_initcall(system_trusted_keyring_init);
134
135 /*
136  * Load the compiled-in list of X.509 certificates.
137  */
138 static __init int load_system_certificate_list(void)
139 {
140         pr_notice("Loading compiled-in X.509 certificates\n");
141
142         return load_certificate_list(system_certificate_list, system_certificate_list_size,
143                                      builtin_trusted_keys);
144 }
145 late_initcall(load_system_certificate_list);
146
147 #ifdef CONFIG_SYSTEM_DATA_VERIFICATION
148
149 /**
150  * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
151  * @data: The data to be verified (NULL if expecting internal data).
152  * @len: Size of @data.
153  * @pkcs7: The PKCS#7 message that is the signature.
154  * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
155  *                                      (void *)1UL for all trusted keys).
156  * @usage: The use to which the key is being put.
157  * @view_content: Callback to gain access to content.
158  * @ctx: Context for callback.
159  */
160 int verify_pkcs7_message_sig(const void *data, size_t len,
161                              struct pkcs7_message *pkcs7,
162                              struct key *trusted_keys,
163                              enum key_being_used_for usage,
164                              int (*view_content)(void *ctx,
165                                                  const void *data, size_t len,
166                                                  size_t asn1hdrlen),
167                              void *ctx)
168 {
169         int ret;
170
171         /* The data should be detached - so we need to supply it. */
172         if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
173                 pr_err("PKCS#7 signature with non-detached data\n");
174                 ret = -EBADMSG;
175                 goto error;
176         }
177
178         ret = pkcs7_verify(pkcs7, usage);
179         if (ret < 0)
180                 goto error;
181
182         if (!trusted_keys) {
183                 trusted_keys = builtin_trusted_keys;
184         } else if (trusted_keys == VERIFY_USE_SECONDARY_KEYRING) {
185 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
186                 trusted_keys = secondary_trusted_keys;
187 #else
188                 trusted_keys = builtin_trusted_keys;
189 #endif
190         } else if (trusted_keys == VERIFY_USE_PLATFORM_KEYRING) {
191 #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
192                 trusted_keys = platform_trusted_keys;
193 #else
194                 trusted_keys = NULL;
195 #endif
196                 if (!trusted_keys) {
197                         ret = -ENOKEY;
198                         pr_devel("PKCS#7 platform keyring is not available\n");
199                         goto error;
200                 }
201
202                 ret = is_key_on_revocation_list(pkcs7);
203                 if (ret != -ENOKEY) {
204                         pr_devel("PKCS#7 platform key is on revocation list\n");
205                         goto error;
206                 }
207         }
208         ret = pkcs7_validate_trust(pkcs7, trusted_keys);
209         if (ret < 0) {
210                 if (ret == -ENOKEY)
211                         pr_devel("PKCS#7 signature not signed with a trusted key\n");
212                 goto error;
213         }
214
215         if (view_content) {
216                 size_t asn1hdrlen;
217
218                 ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
219                 if (ret < 0) {
220                         if (ret == -ENODATA)
221                                 pr_devel("PKCS#7 message does not contain data\n");
222                         goto error;
223                 }
224
225                 ret = view_content(ctx, data, len, asn1hdrlen);
226         }
227
228 error:
229         pr_devel("<==%s() = %d\n", __func__, ret);
230         return ret;
231 }
232
233 /**
234  * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
235  * @data: The data to be verified (NULL if expecting internal data).
236  * @len: Size of @data.
237  * @raw_pkcs7: The PKCS#7 message that is the signature.
238  * @pkcs7_len: The size of @raw_pkcs7.
239  * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
240  *                                      (void *)1UL for all trusted keys).
241  * @usage: The use to which the key is being put.
242  * @view_content: Callback to gain access to content.
243  * @ctx: Context for callback.
244  */
245 int verify_pkcs7_signature(const void *data, size_t len,
246                            const void *raw_pkcs7, size_t pkcs7_len,
247                            struct key *trusted_keys,
248                            enum key_being_used_for usage,
249                            int (*view_content)(void *ctx,
250                                                const void *data, size_t len,
251                                                size_t asn1hdrlen),
252                            void *ctx)
253 {
254         struct pkcs7_message *pkcs7;
255         int ret;
256
257         pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
258         if (IS_ERR(pkcs7))
259                 return PTR_ERR(pkcs7);
260
261         ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
262                                        view_content, ctx);
263
264         pkcs7_free_message(pkcs7);
265         pr_devel("<==%s() = %d\n", __func__, ret);
266         return ret;
267 }
268 EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
269
270 #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
271
272 #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
273 void __init set_platform_trusted_keys(struct key *keyring)
274 {
275         platform_trusted_keys = keyring;
276 }
277 #endif