Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/certs/system_keyring.c
26242 views
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 ([email protected])
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/uidgid.h>
15
#include <linux/verification.h>
16
#include <keys/asymmetric-type.h>
17
#include <keys/system_keyring.h>
18
#include <crypto/pkcs7.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_MACHINE_KEYRING
25
static struct key *machine_trusted_keys;
26
#endif
27
#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
28
static struct key *platform_trusted_keys;
29
#endif
30
31
extern __initconst const u8 system_certificate_list[];
32
extern __initconst const unsigned long system_certificate_list_size;
33
extern __initconst const unsigned long module_cert_size;
34
35
/**
36
* restrict_link_by_builtin_trusted - Restrict keyring addition by built-in CA
37
* @dest_keyring: Keyring being linked to.
38
* @type: The type of key being added.
39
* @payload: The payload of the new key.
40
* @restriction_key: A ring of keys that can be used to vouch for the new cert.
41
*
42
* Restrict the addition of keys into a keyring based on the key-to-be-added
43
* being vouched for by a key in the built in system keyring.
44
*/
45
int restrict_link_by_builtin_trusted(struct key *dest_keyring,
46
const struct key_type *type,
47
const union key_payload *payload,
48
struct key *restriction_key)
49
{
50
return restrict_link_by_signature(dest_keyring, type, payload,
51
builtin_trusted_keys);
52
}
53
54
/**
55
* restrict_link_by_digsig_builtin - Restrict digitalSignature key additions by the built-in keyring
56
* @dest_keyring: Keyring being linked to.
57
* @type: The type of key being added.
58
* @payload: The payload of the new key.
59
* @restriction_key: A ring of keys that can be used to vouch for the new cert.
60
*
61
* Restrict the addition of keys into a keyring based on the key-to-be-added
62
* being vouched for by a key in the built in system keyring. The new key
63
* must have the digitalSignature usage field set.
64
*/
65
int restrict_link_by_digsig_builtin(struct key *dest_keyring,
66
const struct key_type *type,
67
const union key_payload *payload,
68
struct key *restriction_key)
69
{
70
return restrict_link_by_digsig(dest_keyring, type, payload,
71
builtin_trusted_keys);
72
}
73
74
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
75
/**
76
* restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
77
* addition by both built-in and secondary keyrings.
78
* @dest_keyring: Keyring being linked to.
79
* @type: The type of key being added.
80
* @payload: The payload of the new key.
81
* @restrict_key: A ring of keys that can be used to vouch for the new cert.
82
*
83
* Restrict the addition of keys into a keyring based on the key-to-be-added
84
* being vouched for by a key in either the built-in or the secondary system
85
* keyrings.
86
*/
87
int restrict_link_by_builtin_and_secondary_trusted(
88
struct key *dest_keyring,
89
const struct key_type *type,
90
const union key_payload *payload,
91
struct key *restrict_key)
92
{
93
/* If we have a secondary trusted keyring, then that contains a link
94
* through to the builtin keyring and the search will follow that link.
95
*/
96
if (type == &key_type_keyring &&
97
dest_keyring == secondary_trusted_keys &&
98
payload == &builtin_trusted_keys->payload)
99
/* Allow the builtin keyring to be added to the secondary */
100
return 0;
101
102
return restrict_link_by_signature(dest_keyring, type, payload,
103
secondary_trusted_keys);
104
}
105
106
/**
107
* restrict_link_by_digsig_builtin_and_secondary - Restrict by digitalSignature.
108
* @dest_keyring: Keyring being linked to.
109
* @type: The type of key being added.
110
* @payload: The payload of the new key.
111
* @restrict_key: A ring of keys that can be used to vouch for the new cert.
112
*
113
* Restrict the addition of keys into a keyring based on the key-to-be-added
114
* being vouched for by a key in either the built-in or the secondary system
115
* keyrings. The new key must have the digitalSignature usage field set.
116
*/
117
int restrict_link_by_digsig_builtin_and_secondary(struct key *dest_keyring,
118
const struct key_type *type,
119
const union key_payload *payload,
120
struct key *restrict_key)
121
{
122
/* If we have a secondary trusted keyring, then that contains a link
123
* through to the builtin keyring and the search will follow that link.
124
*/
125
if (type == &key_type_keyring &&
126
dest_keyring == secondary_trusted_keys &&
127
payload == &builtin_trusted_keys->payload)
128
/* Allow the builtin keyring to be added to the secondary */
129
return 0;
130
131
return restrict_link_by_digsig(dest_keyring, type, payload,
132
secondary_trusted_keys);
133
}
134
135
/*
136
* Allocate a struct key_restriction for the "builtin and secondary trust"
137
* keyring. Only for use in system_trusted_keyring_init().
138
*/
139
static __init struct key_restriction *get_builtin_and_secondary_restriction(void)
140
{
141
struct key_restriction *restriction;
142
143
restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
144
145
if (!restriction)
146
panic("Can't allocate secondary trusted keyring restriction\n");
147
148
if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING))
149
restriction->check = restrict_link_by_builtin_secondary_and_machine;
150
else
151
restriction->check = restrict_link_by_builtin_and_secondary_trusted;
152
153
return restriction;
154
}
155
156
/**
157
* add_to_secondary_keyring - Add to secondary keyring.
158
* @source: Source of key
159
* @data: The blob holding the key
160
* @len: The length of the data blob
161
*
162
* Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
163
* machine or secondary keyring itself.
164
*/
165
void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
166
{
167
key_ref_t key;
168
key_perm_t perm;
169
170
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
171
172
key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
173
"asymmetric",
174
NULL, data, len, perm,
175
KEY_ALLOC_NOT_IN_QUOTA);
176
if (IS_ERR(key)) {
177
pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
178
source, PTR_ERR(key));
179
return;
180
}
181
182
pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
183
key_ref_put(key);
184
}
185
#endif
186
#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
187
void __init set_machine_trusted_keys(struct key *keyring)
188
{
189
machine_trusted_keys = keyring;
190
191
if (key_link(secondary_trusted_keys, machine_trusted_keys) < 0)
192
panic("Can't link (machine) trusted keyrings\n");
193
}
194
195
/**
196
* restrict_link_by_builtin_secondary_and_machine - Restrict keyring addition.
197
* @dest_keyring: Keyring being linked to.
198
* @type: The type of key being added.
199
* @payload: The payload of the new key.
200
* @restrict_key: A ring of keys that can be used to vouch for the new cert.
201
*
202
* Restrict the addition of keys into a keyring based on the key-to-be-added
203
* being vouched for by a key in either the built-in, the secondary, or
204
* the machine keyrings.
205
*/
206
int restrict_link_by_builtin_secondary_and_machine(
207
struct key *dest_keyring,
208
const struct key_type *type,
209
const union key_payload *payload,
210
struct key *restrict_key)
211
{
212
if (machine_trusted_keys && type == &key_type_keyring &&
213
dest_keyring == secondary_trusted_keys &&
214
payload == &machine_trusted_keys->payload)
215
/* Allow the machine keyring to be added to the secondary */
216
return 0;
217
218
return restrict_link_by_builtin_and_secondary_trusted(dest_keyring, type,
219
payload, restrict_key);
220
}
221
#endif
222
223
/*
224
* Create the trusted keyrings
225
*/
226
static __init int system_trusted_keyring_init(void)
227
{
228
pr_notice("Initialise system trusted keyrings\n");
229
230
builtin_trusted_keys =
231
keyring_alloc(".builtin_trusted_keys",
232
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
233
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
234
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
235
KEY_ALLOC_NOT_IN_QUOTA,
236
NULL, NULL);
237
if (IS_ERR(builtin_trusted_keys))
238
panic("Can't allocate builtin trusted keyring\n");
239
240
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
241
secondary_trusted_keys =
242
keyring_alloc(".secondary_trusted_keys",
243
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
244
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
245
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
246
KEY_USR_WRITE),
247
KEY_ALLOC_NOT_IN_QUOTA,
248
get_builtin_and_secondary_restriction(),
249
NULL);
250
if (IS_ERR(secondary_trusted_keys))
251
panic("Can't allocate secondary trusted keyring\n");
252
253
if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0)
254
panic("Can't link trusted keyrings\n");
255
#endif
256
257
return 0;
258
}
259
260
/*
261
* Must be initialised before we try and load the keys into the keyring.
262
*/
263
device_initcall(system_trusted_keyring_init);
264
265
__init int load_module_cert(struct key *keyring)
266
{
267
if (!IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG))
268
return 0;
269
270
pr_notice("Loading compiled-in module X.509 certificates\n");
271
272
return x509_load_certificate_list(system_certificate_list,
273
module_cert_size, keyring);
274
}
275
276
/*
277
* Load the compiled-in list of X.509 certificates.
278
*/
279
static __init int load_system_certificate_list(void)
280
{
281
const u8 *p;
282
unsigned long size;
283
284
pr_notice("Loading compiled-in X.509 certificates\n");
285
286
#ifdef CONFIG_MODULE_SIG
287
p = system_certificate_list;
288
size = system_certificate_list_size;
289
#else
290
p = system_certificate_list + module_cert_size;
291
size = system_certificate_list_size - module_cert_size;
292
#endif
293
294
return x509_load_certificate_list(p, size, builtin_trusted_keys);
295
}
296
late_initcall(load_system_certificate_list);
297
298
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
299
300
/**
301
* verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
302
* @data: The data to be verified (NULL if expecting internal data).
303
* @len: Size of @data.
304
* @pkcs7: The PKCS#7 message that is the signature.
305
* @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
306
* (void *)1UL for all trusted keys).
307
* @usage: The use to which the key is being put.
308
* @view_content: Callback to gain access to content.
309
* @ctx: Context for callback.
310
*/
311
int verify_pkcs7_message_sig(const void *data, size_t len,
312
struct pkcs7_message *pkcs7,
313
struct key *trusted_keys,
314
enum key_being_used_for usage,
315
int (*view_content)(void *ctx,
316
const void *data, size_t len,
317
size_t asn1hdrlen),
318
void *ctx)
319
{
320
int ret;
321
322
/* The data should be detached - so we need to supply it. */
323
if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
324
pr_err("PKCS#7 signature with non-detached data\n");
325
ret = -EBADMSG;
326
goto error;
327
}
328
329
ret = pkcs7_verify(pkcs7, usage);
330
if (ret < 0)
331
goto error;
332
333
ret = is_key_on_revocation_list(pkcs7);
334
if (ret != -ENOKEY) {
335
pr_devel("PKCS#7 key is on revocation list\n");
336
goto error;
337
}
338
339
if (!trusted_keys) {
340
trusted_keys = builtin_trusted_keys;
341
} else if (trusted_keys == VERIFY_USE_SECONDARY_KEYRING) {
342
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
343
trusted_keys = secondary_trusted_keys;
344
#else
345
trusted_keys = builtin_trusted_keys;
346
#endif
347
} else if (trusted_keys == VERIFY_USE_PLATFORM_KEYRING) {
348
#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
349
trusted_keys = platform_trusted_keys;
350
#else
351
trusted_keys = NULL;
352
#endif
353
if (!trusted_keys) {
354
ret = -ENOKEY;
355
pr_devel("PKCS#7 platform keyring is not available\n");
356
goto error;
357
}
358
}
359
ret = pkcs7_validate_trust(pkcs7, trusted_keys);
360
if (ret < 0) {
361
if (ret == -ENOKEY)
362
pr_devel("PKCS#7 signature not signed with a trusted key\n");
363
goto error;
364
}
365
366
if (view_content) {
367
size_t asn1hdrlen;
368
369
ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
370
if (ret < 0) {
371
if (ret == -ENODATA)
372
pr_devel("PKCS#7 message does not contain data\n");
373
goto error;
374
}
375
376
ret = view_content(ctx, data, len, asn1hdrlen);
377
}
378
379
error:
380
pr_devel("<==%s() = %d\n", __func__, ret);
381
return ret;
382
}
383
384
/**
385
* verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
386
* @data: The data to be verified (NULL if expecting internal data).
387
* @len: Size of @data.
388
* @raw_pkcs7: The PKCS#7 message that is the signature.
389
* @pkcs7_len: The size of @raw_pkcs7.
390
* @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
391
* (void *)1UL for all trusted keys).
392
* @usage: The use to which the key is being put.
393
* @view_content: Callback to gain access to content.
394
* @ctx: Context for callback.
395
*/
396
int verify_pkcs7_signature(const void *data, size_t len,
397
const void *raw_pkcs7, size_t pkcs7_len,
398
struct key *trusted_keys,
399
enum key_being_used_for usage,
400
int (*view_content)(void *ctx,
401
const void *data, size_t len,
402
size_t asn1hdrlen),
403
void *ctx)
404
{
405
struct pkcs7_message *pkcs7;
406
int ret;
407
408
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
409
if (IS_ERR(pkcs7))
410
return PTR_ERR(pkcs7);
411
412
ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
413
view_content, ctx);
414
415
pkcs7_free_message(pkcs7);
416
pr_devel("<==%s() = %d\n", __func__, ret);
417
return ret;
418
}
419
EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
420
421
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
422
423
#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
424
void __init set_platform_trusted_keys(struct key *keyring)
425
{
426
platform_trusted_keys = keyring;
427
}
428
#endif
429
430