On Tue May 9, 2023 at 1:07 AM EEST, Eric Snowberg wrote: > Add a new link restriction. Restrict the addition of keys in a keyring > based on the key having digitalSignature usage set. Additionally, verify > the new certificate against the ones in the system keyrings. Add two > additional functions to use the new restriction within either the builtin > or secondary keyrings. > > Signed-off-by: Eric Snowberg <eric.snowberg@xxxxxxxxxx> > --- > certs/system_keyring.c | 52 +++++++++++++++++++++++++++++++ > crypto/asymmetric_keys/restrict.c | 44 ++++++++++++++++++++++++++ > include/crypto/public_key.h | 11 +++++++ > include/keys/system_keyring.h | 11 +++++++ > 4 files changed, 118 insertions(+) > > diff --git a/certs/system_keyring.c b/certs/system_keyring.c > index a7a49b17ceb1..4249c49bd43b 100644 > --- a/certs/system_keyring.c > +++ b/certs/system_keyring.c > @@ -51,6 +51,27 @@ int restrict_link_by_builtin_trusted(struct key *dest_keyring, > builtin_trusted_keys); > } > > +/** > + * restrict_link_by_digsig_builtin - Restrict digitalSignature key additions > + * by the built-in keyring. BTW, does checkpatch complain if you put that to a single line (I don't know this)? If not, I would just put "Restrict by digitalSignature" > + * @dest_keyring: Keyring being linked to. > + * @type: The type of key being added. > + * @payload: The payload of the new key. > + * @restriction_key: A ring of keys that can be used to vouch for the new cert. > + * > + * Restrict the addition of keys into a keyring based on the key-to-be-added > + * being vouched for by a key in the built in system keyring. The new key > + * must have the digitalSignature usage field set. > + */ > +int restrict_link_by_digsig_builtin(struct key *dest_keyring, > + const struct key_type *type, > + const union key_payload *payload, > + struct key *restriction_key) > +{ > + return restrict_link_by_digsig(dest_keyring, type, payload, > + builtin_trusted_keys); > +} > + > #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING > /** > * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring > @@ -83,6 +104,37 @@ int restrict_link_by_builtin_and_secondary_trusted( > secondary_trusted_keys); > } > > +/** > + * restrict_link_by_digsig_builtin_and_secondary - Restrict digitalSignature > + * key additions by both built-in and secondary keyrings. > + * @dest_keyring: Keyring being linked to. > + * @type: The type of key being added. > + * @payload: The payload of the new key. > + * @restrict_key: A ring of keys that can be used to vouch for the new cert. > + * > + * Restrict the addition of keys into a keyring based on the key-to-be-added > + * being vouched for by a key in either the built-in or the secondary system > + * keyrings. The new key must have the digitalSignature usage field set. > + */ > +int restrict_link_by_digsig_builtin_and_secondary( > + struct key *dest_keyring, > + const struct key_type *type, > + const union key_payload *payload, > + struct key *restrict_key) > +{ > + /* If we have a secondary trusted keyring, then that contains a link > + * through to the builtin keyring and the search will follow that link. > + */ > + if (type == &key_type_keyring && > + dest_keyring == secondary_trusted_keys && > + payload == &builtin_trusted_keys->payload) > + /* Allow the builtin keyring to be added to the secondary */ > + return 0; > + > + return restrict_link_by_digsig(dest_keyring, type, payload, > + secondary_trusted_keys); > +} > + > /* > * Allocate a struct key_restriction for the "builtin and secondary trust" > * keyring. Only for use in system_trusted_keyring_init(). > diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c > index 276bdb627498..6b69ea40da23 100644 > --- a/crypto/asymmetric_keys/restrict.c > +++ b/crypto/asymmetric_keys/restrict.c > @@ -148,6 +148,50 @@ int restrict_link_by_ca(struct key *dest_keyring, > return 0; > } > > +/** > + * restrict_link_by_digsig - Restrict additions to a ring of digsig keys > + * @dest_keyring: Keyring being linked to. > + * @type: The type of key being added. > + * @payload: The payload of the new key. > + * @trust_keyring: A ring of keys that can be used to vouch for the new cert. > + * > + * Check if the new certificate has digitalSignature usage set. If it is, > + * then mark the new certificate as being ok to link. Afterwards verify > + * the new certificate against the ones in the trust_keyring. > + * > + * Returns 0 if the new certificate was accepted, -ENOKEY if the > + * certificate is not a digsig. -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_digsig(struct key *dest_keyring, > + const struct key_type *type, > + const union key_payload *payload, > + struct key *trust_keyring) > +{ > + const struct public_key *pkey; > + > + if (type != &key_type_asymmetric) > + return -EOPNOTSUPP; > + > + pkey = payload->data[asym_crypto]; > + > + if (!pkey) > + return -ENOPKG; > + > + if (!test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags)) > + return -ENOKEY; > + > + if (test_bit(KEY_EFLAG_CA, &pkey->key_eflags)) > + return -ENOKEY; > + > + if (test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags)) > + return -ENOKEY; > + > + return restrict_link_by_signature(dest_keyring, type, payload, > + trust_keyring); > +} > + > static bool match_either_id(const struct asymmetric_key_id **pair, > const struct asymmetric_key_id *single) > { > diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h > index 653992a6e941..8eb5eff059f3 100644 > --- a/include/crypto/public_key.h > +++ b/include/crypto/public_key.h > @@ -80,6 +80,10 @@ extern int restrict_link_by_ca(struct key *dest_keyring, > const struct key_type *type, > const union key_payload *payload, > struct key *trust_keyring); > +int restrict_link_by_digsig(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, > @@ -88,6 +92,13 @@ static inline int restrict_link_by_ca(struct key *dest_keyring, > { > return 0; > } > +static inline int restrict_link_by_digsig(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 *, > diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h > index 91e080efb918..38f63f1c2cbe 100644 > --- a/include/keys/system_keyring.h > +++ b/include/keys/system_keyring.h > @@ -23,10 +23,15 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring, > const struct key_type *type, > const union key_payload *payload, > struct key *restriction_key); > +int restrict_link_by_digsig_builtin(struct key *dest_keyring, > + const struct key_type *type, > + const union key_payload *payload, > + struct key *restriction_key); > extern __init int load_module_cert(struct key *keyring); > > #else > #define restrict_link_by_builtin_trusted restrict_link_reject > +#define restrict_link_by_digsig_builtin restrict_link_reject > > static inline __init int load_module_cert(struct key *keyring) > { > @@ -41,8 +46,14 @@ extern int restrict_link_by_builtin_and_secondary_trusted( > const struct key_type *type, > const union key_payload *payload, > struct key *restriction_key); > +extern int restrict_link_by_digsig_builtin_and_secondary( > + struct key *keyring, > + const struct key_type *type, > + const union key_payload *payload, > + struct key *restriction_key); > #else > #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted > +#define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin > #endif > > #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING > -- > 2.27.0 BR, Jarkko