Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/crypto/asymmetric_keys/restrict.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* Instantiate a public key crypto key from an X.509 Certificate
3
*
4
* Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
5
* Written by David Howells ([email protected])
6
*/
7
8
#define pr_fmt(fmt) "ASYM: "fmt
9
#include <linux/module.h>
10
#include <linux/kernel.h>
11
#include <linux/err.h>
12
#include <crypto/public_key.h>
13
#include "asymmetric_keys.h"
14
15
static bool use_builtin_keys;
16
static struct asymmetric_key_id *ca_keyid;
17
18
#ifndef MODULE
19
static struct {
20
struct asymmetric_key_id id;
21
unsigned char data[10];
22
} cakey;
23
24
static int __init ca_keys_setup(char *str)
25
{
26
if (!str) /* default system keyring */
27
return 1;
28
29
if (strncmp(str, "id:", 3) == 0) {
30
struct asymmetric_key_id *p = &cakey.id;
31
size_t hexlen = (strlen(str) - 3) / 2;
32
int ret;
33
34
if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
35
pr_err("Missing or invalid ca_keys id\n");
36
return 1;
37
}
38
39
ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
40
if (ret < 0)
41
pr_err("Unparsable ca_keys id hex string\n");
42
else
43
ca_keyid = p; /* owner key 'id:xxxxxx' */
44
} else if (strcmp(str, "builtin") == 0) {
45
use_builtin_keys = true;
46
}
47
48
return 1;
49
}
50
__setup("ca_keys=", ca_keys_setup);
51
#endif
52
53
/**
54
* restrict_link_by_signature - Restrict additions to a ring of public keys
55
* @dest_keyring: Keyring being linked to.
56
* @type: The type of key being added.
57
* @payload: The payload of the new key.
58
* @trust_keyring: A ring of keys that can be used to vouch for the new cert.
59
*
60
* Check the new certificate against the ones in the trust keyring. If one of
61
* those is the signing key and validates the new certificate, then mark the
62
* new certificate as being trusted.
63
*
64
* Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
65
* matching parent certificate in the trusted list, -EKEYREJECTED if the
66
* signature check fails or the key is blacklisted, -ENOPKG if the signature
67
* uses unsupported crypto, or some other error if there is a matching
68
* certificate but the signature check cannot be performed.
69
*/
70
int restrict_link_by_signature(struct key *dest_keyring,
71
const struct key_type *type,
72
const union key_payload *payload,
73
struct key *trust_keyring)
74
{
75
const struct public_key_signature *sig;
76
struct key *key;
77
int ret;
78
79
pr_devel("==>%s()\n", __func__);
80
81
if (!trust_keyring)
82
return -ENOKEY;
83
84
if (type != &key_type_asymmetric)
85
return -EOPNOTSUPP;
86
87
sig = payload->data[asym_auth];
88
if (!sig)
89
return -ENOPKG;
90
if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
91
return -ENOKEY;
92
93
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
94
return -EPERM;
95
96
/* See if we have a key that signed this one. */
97
key = find_asymmetric_key(trust_keyring,
98
sig->auth_ids[0], sig->auth_ids[1],
99
sig->auth_ids[2], false);
100
if (IS_ERR(key))
101
return -ENOKEY;
102
103
if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
104
ret = -ENOKEY;
105
else if (IS_BUILTIN(CONFIG_SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN) &&
106
!strcmp(dest_keyring->description, ".secondary_trusted_keys") &&
107
!test_bit(KEY_FLAG_BUILTIN, &key->flags))
108
ret = -ENOKEY;
109
else
110
ret = verify_signature(key, sig);
111
key_put(key);
112
return ret;
113
}
114
115
/**
116
* restrict_link_by_ca - Restrict additions to a ring of CA keys
117
* @dest_keyring: Keyring being linked to.
118
* @type: The type of key being added.
119
* @payload: The payload of the new key.
120
* @trust_keyring: Unused.
121
*
122
* Check if the new certificate is a CA. If it is a CA, then mark the new
123
* certificate as being ok to link.
124
*
125
* Returns 0 if the new certificate was accepted, -ENOKEY if the
126
* certificate is not a CA. -ENOPKG if the signature uses unsupported
127
* crypto, or some other error if there is a matching certificate but
128
* the signature check cannot be performed.
129
*/
130
int restrict_link_by_ca(struct key *dest_keyring,
131
const struct key_type *type,
132
const union key_payload *payload,
133
struct key *trust_keyring)
134
{
135
const struct public_key *pkey;
136
137
if (type != &key_type_asymmetric)
138
return -EOPNOTSUPP;
139
140
pkey = payload->data[asym_crypto];
141
if (!pkey)
142
return -ENOPKG;
143
if (!test_bit(KEY_EFLAG_CA, &pkey->key_eflags))
144
return -ENOKEY;
145
if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags))
146
return -ENOKEY;
147
if (!IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING_MAX))
148
return 0;
149
if (test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags))
150
return -ENOKEY;
151
152
return 0;
153
}
154
155
/**
156
* restrict_link_by_digsig - Restrict additions to a ring of digsig keys
157
* @dest_keyring: Keyring being linked to.
158
* @type: The type of key being added.
159
* @payload: The payload of the new key.
160
* @trust_keyring: A ring of keys that can be used to vouch for the new cert.
161
*
162
* Check if the new certificate has digitalSignature usage set. If it is,
163
* then mark the new certificate as being ok to link. Afterwards verify
164
* the new certificate against the ones in the trust_keyring.
165
*
166
* Returns 0 if the new certificate was accepted, -ENOKEY if the
167
* certificate is not a digsig. -ENOPKG if the signature uses unsupported
168
* crypto, or some other error if there is a matching certificate but
169
* the signature check cannot be performed.
170
*/
171
int restrict_link_by_digsig(struct key *dest_keyring,
172
const struct key_type *type,
173
const union key_payload *payload,
174
struct key *trust_keyring)
175
{
176
const struct public_key *pkey;
177
178
if (type != &key_type_asymmetric)
179
return -EOPNOTSUPP;
180
181
pkey = payload->data[asym_crypto];
182
183
if (!pkey)
184
return -ENOPKG;
185
186
if (!test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags))
187
return -ENOKEY;
188
189
if (test_bit(KEY_EFLAG_CA, &pkey->key_eflags))
190
return -ENOKEY;
191
192
if (test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags))
193
return -ENOKEY;
194
195
return restrict_link_by_signature(dest_keyring, type, payload,
196
trust_keyring);
197
}
198
199
static bool match_either_id(const struct asymmetric_key_id **pair,
200
const struct asymmetric_key_id *single)
201
{
202
return (asymmetric_key_id_same(pair[0], single) ||
203
asymmetric_key_id_same(pair[1], single));
204
}
205
206
static int key_or_keyring_common(struct key *dest_keyring,
207
const struct key_type *type,
208
const union key_payload *payload,
209
struct key *trusted, bool check_dest)
210
{
211
const struct public_key_signature *sig;
212
struct key *key = NULL;
213
int ret;
214
215
pr_devel("==>%s()\n", __func__);
216
217
if (!dest_keyring)
218
return -ENOKEY;
219
else if (dest_keyring->type != &key_type_keyring)
220
return -EOPNOTSUPP;
221
222
if (!trusted && !check_dest)
223
return -ENOKEY;
224
225
if (type != &key_type_asymmetric)
226
return -EOPNOTSUPP;
227
228
sig = payload->data[asym_auth];
229
if (!sig)
230
return -ENOPKG;
231
if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
232
return -ENOKEY;
233
234
if (trusted) {
235
if (trusted->type == &key_type_keyring) {
236
/* See if we have a key that signed this one. */
237
key = find_asymmetric_key(trusted, sig->auth_ids[0],
238
sig->auth_ids[1],
239
sig->auth_ids[2], false);
240
if (IS_ERR(key))
241
key = NULL;
242
} else if (trusted->type == &key_type_asymmetric) {
243
const struct asymmetric_key_id **signer_ids;
244
245
signer_ids = (const struct asymmetric_key_id **)
246
asymmetric_key_ids(trusted)->id;
247
248
/*
249
* The auth_ids come from the candidate key (the
250
* one that is being considered for addition to
251
* dest_keyring) and identify the key that was
252
* used to sign.
253
*
254
* The signer_ids are identifiers for the
255
* signing key specified for dest_keyring.
256
*
257
* The first auth_id is the preferred id, 2nd and
258
* 3rd are the fallbacks. If exactly one of
259
* auth_ids[0] and auth_ids[1] is present, it may
260
* match either signer_ids[0] or signed_ids[1].
261
* If both are present the first one may match
262
* either signed_id but the second one must match
263
* the second signer_id. If neither of them is
264
* available, auth_ids[2] is matched against
265
* signer_ids[2] as a fallback.
266
*/
267
if (!sig->auth_ids[0] && !sig->auth_ids[1]) {
268
if (asymmetric_key_id_same(signer_ids[2],
269
sig->auth_ids[2]))
270
key = __key_get(trusted);
271
272
} else if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
273
const struct asymmetric_key_id *auth_id;
274
275
auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
276
if (match_either_id(signer_ids, auth_id))
277
key = __key_get(trusted);
278
279
} else if (asymmetric_key_id_same(signer_ids[1],
280
sig->auth_ids[1]) &&
281
match_either_id(signer_ids,
282
sig->auth_ids[0])) {
283
key = __key_get(trusted);
284
}
285
} else {
286
return -EOPNOTSUPP;
287
}
288
}
289
290
if (check_dest && !key) {
291
/* See if the destination has a key that signed this one. */
292
key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
293
sig->auth_ids[1], sig->auth_ids[2],
294
false);
295
if (IS_ERR(key))
296
key = NULL;
297
}
298
299
if (!key)
300
return -ENOKEY;
301
302
ret = key_validate(key);
303
if (ret == 0)
304
ret = verify_signature(key, sig);
305
306
key_put(key);
307
return ret;
308
}
309
310
/**
311
* restrict_link_by_key_or_keyring - Restrict additions to a ring of public
312
* keys using the restrict_key information stored in the ring.
313
* @dest_keyring: Keyring being linked to.
314
* @type: The type of key being added.
315
* @payload: The payload of the new key.
316
* @trusted: A key or ring of keys that can be used to vouch for the new cert.
317
*
318
* Check the new certificate only against the key or keys passed in the data
319
* parameter. If one of those is the signing key and validates the new
320
* certificate, then mark the new certificate as being ok to link.
321
*
322
* Returns 0 if the new certificate was accepted, -ENOKEY if we
323
* couldn't find a matching parent certificate in the trusted list,
324
* -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
325
* unsupported crypto, or some other error if there is a matching certificate
326
* but the signature check cannot be performed.
327
*/
328
int restrict_link_by_key_or_keyring(struct key *dest_keyring,
329
const struct key_type *type,
330
const union key_payload *payload,
331
struct key *trusted)
332
{
333
return key_or_keyring_common(dest_keyring, type, payload, trusted,
334
false);
335
}
336
337
/**
338
* restrict_link_by_key_or_keyring_chain - Restrict additions to a ring of
339
* public keys using the restrict_key information stored in the ring.
340
* @dest_keyring: Keyring being linked to.
341
* @type: The type of key being added.
342
* @payload: The payload of the new key.
343
* @trusted: A key or ring of keys that can be used to vouch for the new cert.
344
*
345
* Check the new certificate against the key or keys passed in the data
346
* parameter and against the keys already linked to the destination keyring. If
347
* one of those is the signing key and validates the new certificate, then mark
348
* the new certificate as being ok to link.
349
*
350
* Returns 0 if the new certificate was accepted, -ENOKEY if we
351
* couldn't find a matching parent certificate in the trusted list,
352
* -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
353
* unsupported crypto, or some other error if there is a matching certificate
354
* but the signature check cannot be performed.
355
*/
356
int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
357
const struct key_type *type,
358
const union key_payload *payload,
359
struct key *trusted)
360
{
361
return key_or_keyring_common(dest_keyring, type, payload, trusted,
362
true);
363
}
364
365