File Index
Files and directories
Sign in
FILE

restrict.c

File preview with syntax highlighting.

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