Re: [RFC PATCH 00/20] KEYS: Restrict additions to 'trusted' keyrings [ver #2]

From: Mimi Zohar
Date: Wed Jan 20 2016 - 13:59:26 EST


On Tue, 2016-01-19 at 11:30 +0000, David Howells wrote:
> Here's a set of patches that changes how certificates/keys are determined
> to be trusted. That's currently a two-step process:
>
> (1) Up until recently, when an X.509 certificate was parsed - no matter
> the source - it was judged against the keys in .system_keyring,
> assuming those keys to be trusted if they have KEY_FLAG_TRUSTED set
> upon them.
>
> This has just been changed such that any key in the .ima_mok keyring

, if configured,

> may also be used to judge the trustwortiness of a new certificate,
> whether or not the .ima_mok keyring is meant to be consulted for
> whatever process is being undertaken.
>
> If a certificate is determined to be trustworthy, KEY_FLAG_TRUSTED
> will be set upon a key it is loaded into (if it is loaded into one),
> no matter what the key is going to be loaded for.
>
> (2) If an X.509 certificate is loaded into a key, then that key - if
> KEY_FLAG_TRUSTED gets set upon it - can be linked into any keyring
> with KEY_FLAG_TRUSTED_ONLY set upon it. This was meant to be the
> system keyring only, but has been extended to various IMA keyrings.
>
> A user can at will link any key marked KEY_FLAG_TRUSTED into any
> keyring marked KEY_FLAG_TRUSTED_ONLY if the relevant permissions masks
> permit it.
>
> These patches change that:
>
> (1) Trust becomes a matter of consulting the ring of trusted keys supplied
> when the trust is evaluated only.
>
> (2) Asymmetric keys retain the source certificate signature information
> for future evaluation rather than discarding it.
>
> (3) Every keyring can be supplied with its own manager function to
> restrict what may be added to that keyring. This is called whenever a
> key is to be linked into the keyring to guard against a key being
> created in one keyring and then linked across.
>
> This function is supplied with the keyring and the key type and
> payload[*] of the key being linked in for use in its evaluation. It
> is permitted to use other data also, such as the contents of other
> keyrings such as the system keyrings.
>
> [*] The type and payload are supplied instead of a key because as an
> optimisation this function may be called whilst creating a key and
> so may reject the proposed key between preparse and allocation.
>
> (4) A default manager function is provided that permits keys to be
> restricted to only asymmetric keys that are vouched for by the
> contents of the system keyring.
>
> (5) A key allocation flag, KEY_ALLOC_BYPASS_RESTRICTION, is made available
> so that the kernel can initialise keyrings with keys that form the
> root of the trust relationship.
>
> (6) KEY_FLAG_TRUSTED and KEY_FLAG_TRUSTED_ONLY are removed, along with
> key_preparsed_payload::trusted.
>
> This change also makes it possible for userspace to create a private set of
> trusted keys and then to seal it by setting a manager function where the
> private set is wholly independent of the kernel's trust relationships.
>
> Further changes in the set involve extracting certain IMA special keyrings
> and making them generally global:
>
> (*) .system_keyring is renamed to .builtin_trusted_keys and remains read
> only. It carries only keys built in to the kernel. It may be where
> UEFI keys should be loaded - though that could better be the new
> secondary keyring (see below).

or even better a UEFI specific keyring.

> (*) An optional system blacklist keyring is created to replace the IMA
> keyring.

to replace the IMA blacklist keyring.

> (*) A 'blacklist' key type is created that may contain a hex string in
> its description (it carries no payload). When an X.509
> certificate is parsed, the system blacklist is searched for a
> blacklist key that matches the TBS hash of the X.509 certificate
> and if one is found, the certificate is considered blacklisted.
>
> (*) A list of blacklisted hashes can be added to the system blacklist
> keyring at compile time. In the future it should also be possible
> to load this up from such as the UEFI blacklist.
>
> (*) Keys can be added to the blacklist keyring by root if the keys are
> signed by a key in the builtin system keyring. These can then be
> searched for by asymmetric key ID. This allows the functionality
> of the IMA blacklist keyring to be replicated.
>
> It might be worth making an asymmetric key subtype that carries no
> data to be used here as the cryptographic material is then just
> dead weight since the IDs are what matter.

I would go one step farther and say that only this new asymmetric key
subtype, that carries no data, be permitted. Otherwise the same
certificate, that was used for loading the key in the first place, could
be inadvertently added to the blacklist.

Mimi

> (*) An optional secondary system keyring (called .secondary_trusted_keys)
> is added to replace the IMA MOK keyring.
>
> (*) Keys can be added to the secondary keyring by root if the keys can
> be vouched for by either ring of system keys.
>
> (*) Module signing and kexec only use .builtin_trusted_keys and do not use
> the new secondary keyring, but they do consult the system blacklist.
>
> (*) If the kernel sees a PKCS#7 message with more than one signature, at
> least one of which is blacklisted, it will permit the message if at
> least one of the non-blacklisted signature chains is vouched for. If
> none are, then EKEYREJECTED will be given. This error takes priority
> over giving ENOPKG for unsupported encryption.
>
> The patches can be found here also:
>
> http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-trust
>
> David
> ---
> David Howells (20):
> KEYS: Add an alloc flag to convey the builtinness of a key
> KEYS: Add a system blacklist keyring
> X.509: Allow X.509 certs to be blacklisted
> X.509: Don't treat self-signed keys specially
> KEYS: Generalise system_verify_data() to provide access to internal content
> PKCS#7: Make trust determination dependent on contents of trust keyring
> KEYS: Add a facility to restrict new links into a keyring
> KEYS: Allow authentication data to be stored in an asymmetric key
> KEYS: Add identifier pointers to public_key_signature struct
> X.509: Retain the key verification data
> X.509: Extract signature digest and make self-signed cert checks earlier
> PKCS#7: Make the signature a pointer rather than embedding it
> X.509: Move the trust validation code out to its own file
> KEYS: Generalise x509_request_asymmetric_key()
> KEYS: Move the point of trust determination to __key_link()
> KEYS: Remove KEY_FLAG_TRUSTED and KEY_ALLOC_TRUSTED
> PKCS#7: Handle blacklisted certificates
> IMA: Use the system blacklist keyring
> certs: Add a secondary system keyring that can be added to dynamically
> IMA: Replace the .ima_mok keyring with the secondary system keyring
>
>
> Documentation/security/keys.txt | 14 +
> arch/x86/kernel/kexec-bzimage64.c | 18 --
> certs/Kconfig | 26 ++
> certs/Makefile | 6 +
> certs/blacklist.c | 184 +++++++++++++++++
> certs/blacklist.h | 3
> certs/blacklist_hashes.c | 6 +
> certs/blacklist_nohashes.c | 5
> certs/system_keyring.c | 141 ++++++++++---
> crypto/asymmetric_keys/Kconfig | 1
> crypto/asymmetric_keys/Makefile | 2
> crypto/asymmetric_keys/asymmetric_keys.h | 2
> crypto/asymmetric_keys/asymmetric_type.c | 7 -
> crypto/asymmetric_keys/mscode_parser.c | 21 +-
> crypto/asymmetric_keys/pkcs7_key_type.c | 66 +++---
> crypto/asymmetric_keys/pkcs7_parser.c | 59 +++--
> crypto/asymmetric_keys/pkcs7_parser.h | 12 -
> crypto/asymmetric_keys/pkcs7_trust.c | 44 ++--
> crypto/asymmetric_keys/pkcs7_verify.c | 141 ++++++-------
> crypto/asymmetric_keys/public_key.c | 24 ++
> crypto/asymmetric_keys/public_key.h | 6 +
> crypto/asymmetric_keys/public_key_trust.c | 209 +++++++++++++++++++
> crypto/asymmetric_keys/verify_pefile.c | 40 +---
> crypto/asymmetric_keys/verify_pefile.h | 5
> crypto/asymmetric_keys/x509_cert_parser.c | 51 +++--
> crypto/asymmetric_keys/x509_parser.h | 13 +
> crypto/asymmetric_keys/x509_public_key.c | 318 +++++++++--------------------
> fs/cifs/cifsacl.c | 2
> fs/nfs/nfs4idmap.c | 2
> include/crypto/pkcs7.h | 6 -
> include/crypto/public_key.h | 35 +--
> include/keys/asymmetric-subtype.h | 2
> include/keys/asymmetric-type.h | 8 -
> include/keys/system_keyring.h | 52 ++---
> include/linux/key-type.h | 1
> include/linux/key.h | 39 +++-
> include/linux/verification.h | 49 ++++
> include/linux/verify_pefile.h | 22 --
> kernel/module_signing.c | 7 -
> net/dns_resolver/dns_key.c | 2
> net/rxrpc/ar-key.c | 4
> security/integrity/digsig.c | 10 +
> security/integrity/digsig_asymmetric.c | 18 +-
> security/integrity/ima/Kconfig | 18 --
> security/integrity/ima/Makefile | 1
> security/integrity/ima/ima_mok.c | 55 -----
> security/keys/key.c | 44 +++-
> security/keys/keyring.c | 26 ++
> security/keys/persistent.c | 4
> security/keys/process_keys.c | 16 +
> security/keys/request_key.c | 4
> security/keys/request_key_auth.c | 2
> 52 files changed, 1131 insertions(+), 722 deletions(-)
> create mode 100644 certs/blacklist.c
> create mode 100644 certs/blacklist.h
> create mode 100644 certs/blacklist_hashes.c
> create mode 100644 certs/blacklist_nohashes.c
> create mode 100644 crypto/asymmetric_keys/public_key_trust.c
> create mode 100644 include/linux/verification.h
> delete mode 100644 include/linux/verify_pefile.h
> delete mode 100644 security/integrity/ima/ima_mok.c
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>