[PATCH v8 06/17] KEYS: CA link restriction
From: Eric Snowberg <eric.snowberg@oracle.com>
Date: 2021-11-24 04:42:55
Also in:
keyrings, linux-efi, linux-integrity, linux-security-module, lkml
Subsystem:
asymmetric keys, crypto api, the rest · Maintainers:
David Howells, Lukas Wunner, Ignat Korchagin, Herbert Xu, "David S. Miller", Linus Torvalds
Add a new link restriction. Restrict the addition of keys in a keyring
based on the key to be added being a CA.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
---
v1: Initial version
v2: Removed secondary keyring references
v3: Removed restrict_link_by_system_trusted_or_ca
Simplify restrict_link_by_ca - only see if the key is a CA
Did not add __init in front of restrict_link_by_ca in case
restriction could be resued in the future
v6: Unmodified from v3
v7: Check for CA restruction in public key
v8: Fix issue found by build bot when asym keys not defined in the config
---
crypto/asymmetric_keys/restrict.c | 43 +++++++++++++++++++++++++++++++
include/crypto/public_key.h | 15 +++++++++++
2 files changed, 58 insertions(+)
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
index 84cefe3b3585..a891c598a2aa 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c@@ -108,6 +108,49 @@ int restrict_link_by_signature(struct key *dest_keyring, return ret; } +/** + * restrict_link_by_ca - Restrict additions to a ring of CA keys + * @dest_keyring: Keyring being linked to. + * @type: The type of key being added. + * @payload: The payload of the new key. + * @trust_keyring: Unused. + * + * Check if the new certificate is a CA. If it is a CA, then mark the new + * certificate as being ok to link. + * + * Returns 0 if the new certificate was accepted, -ENOKEY if the + * certificate is not a CA. -ENOPKG if the signature uses unsupported + * crypto, or some other error if there is a matching certificate but + * the signature check cannot be performed. + */ +int restrict_link_by_ca(struct key *dest_keyring, + const struct key_type *type, + const union key_payload *payload, + struct key *trust_keyring) +{ + const struct public_key_signature *sig; + const struct public_key *pkey; + + if (type != &key_type_asymmetric) + return -EOPNOTSUPP; + + sig = payload->data[asym_auth]; + if (!sig) + return -ENOPKG; + + if (!sig->auth_ids[0] && !sig->auth_ids[1]) + return -ENOKEY; + + pkey = payload->data[asym_crypto]; + if (!pkey) + return -ENOPKG; + + if (!pkey->key_is_ca) + return -ENOKEY; + + return public_key_verify_signature(pkey, sig); +} + static bool match_either_id(const struct asymmetric_key_ids *pair, const struct asymmetric_key_id *single) {
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 72dcbc06ef9c..06e34d3340c4 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h@@ -72,6 +72,21 @@ extern int restrict_link_by_key_or_keyring_chain(struct key *trust_keyring, const union key_payload *payload, struct key *trusted); +#if IS_REACHABLE(CONFIG_ASYMMETRIC_KEY_TYPE) +extern int restrict_link_by_ca(struct key *dest_keyring, + const struct key_type *type, + const union key_payload *payload, + struct key *trust_keyring); +#else +static inline int restrict_link_by_ca(struct key *dest_keyring, + const struct key_type *type, + const union key_payload *payload, + struct key *trust_keyring) +{ + return 0; +} +#endif + extern int query_asymmetric_key(const struct kernel_pkey_params *, struct kernel_pkey_query *);
--
2.18.4