hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/certs/system_keyring.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* System trusted keyring for trusted public keys
23 *
34 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public Licence
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the Licence, or (at your option) any later version.
106 */
117
128 #include <linux/export.h>
....@@ -19,10 +15,14 @@
1915 #include <keys/asymmetric-type.h>
2016 #include <keys/system_keyring.h>
2117 #include <crypto/pkcs7.h>
18
+#include "common.h"
2219
2320 static struct key *builtin_trusted_keys;
2421 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
2522 static struct key *secondary_trusted_keys;
23
+#endif
24
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
25
+static struct key *platform_trusted_keys;
2626 #endif
2727
2828 extern __initconst const u8 system_certificate_list[];
....@@ -137,58 +137,98 @@
137137 */
138138 static __init int load_system_certificate_list(void)
139139 {
140
- key_ref_t key;
141
- const u8 *p, *end;
142
- size_t plen;
143
-
144140 pr_notice("Loading compiled-in X.509 certificates\n");
145141
146
- p = system_certificate_list;
147
- end = p + system_certificate_list_size;
148
- while (p < end) {
149
- /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
150
- * than 256 bytes in size.
151
- */
152
- if (end - p < 4)
153
- goto dodgy_cert;
154
- if (p[0] != 0x30 &&
155
- p[1] != 0x82)
156
- goto dodgy_cert;
157
- plen = (p[2] << 8) | p[3];
158
- plen += 4;
159
- if (plen > end - p)
160
- goto dodgy_cert;
161
-
162
- key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1),
163
- "asymmetric",
164
- NULL,
165
- p,
166
- plen,
167
- ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
168
- KEY_USR_VIEW | KEY_USR_READ),
169
- KEY_ALLOC_NOT_IN_QUOTA |
170
- KEY_ALLOC_BUILT_IN |
171
- KEY_ALLOC_BYPASS_RESTRICTION);
172
- if (IS_ERR(key)) {
173
- pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
174
- PTR_ERR(key));
175
- } else {
176
- pr_notice("Loaded X.509 cert '%s'\n",
177
- key_ref_to_ptr(key)->description);
178
- key_ref_put(key);
179
- }
180
- p += plen;
181
- }
182
-
183
- return 0;
184
-
185
-dodgy_cert:
186
- pr_err("Problem parsing in-kernel X.509 certificate list\n");
187
- return 0;
142
+ return load_certificate_list(system_certificate_list, system_certificate_list_size,
143
+ builtin_trusted_keys);
188144 }
189145 late_initcall(load_system_certificate_list);
190146
191147 #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
+}
192232
193233 /**
194234 * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
....@@ -218,47 +258,9 @@
218258 if (IS_ERR(pkcs7))
219259 return PTR_ERR(pkcs7);
220260
221
- /* The data should be detached - so we need to supply it. */
222
- if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
223
- pr_err("PKCS#7 signature with non-detached data\n");
224
- ret = -EBADMSG;
225
- goto error;
226
- }
261
+ ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
262
+ view_content, ctx);
227263
228
- ret = pkcs7_verify(pkcs7, usage);
229
- if (ret < 0)
230
- goto error;
231
-
232
- if (!trusted_keys) {
233
- trusted_keys = builtin_trusted_keys;
234
- } else if (trusted_keys == VERIFY_USE_SECONDARY_KEYRING) {
235
-#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
236
- trusted_keys = secondary_trusted_keys;
237
-#else
238
- trusted_keys = builtin_trusted_keys;
239
-#endif
240
- }
241
- ret = pkcs7_validate_trust(pkcs7, trusted_keys);
242
- if (ret < 0) {
243
- if (ret == -ENOKEY)
244
- pr_err("PKCS#7 signature not signed with a trusted key\n");
245
- goto error;
246
- }
247
-
248
- if (view_content) {
249
- size_t asn1hdrlen;
250
-
251
- ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
252
- if (ret < 0) {
253
- if (ret == -ENODATA)
254
- pr_devel("PKCS#7 message does not contain data\n");
255
- goto error;
256
- }
257
-
258
- ret = view_content(ctx, data, len, asn1hdrlen);
259
- }
260
-
261
-error:
262264 pkcs7_free_message(pkcs7);
263265 pr_devel("<==%s() = %d\n", __func__, ret);
264266 return ret;
....@@ -266,3 +268,10 @@
266268 EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
267269
268270 #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