Messages in this thread Patch in this message | | | Subject | [RFC PATCH 11/12] certs: Add a secondary system keyring that can be added to dynamically [ver #2] | From | David Howells <> | Date | Fri, 04 Mar 2016 15:01:42 +0000 |
| |
Add a secondary system keyring that can be added to by root whilst the system is running - provided the key being added is vouched for by a key built into the kernel or already added to the secondary keyring.
Rename .system_keyring to .builtin_trusted_keys to distinguish it more obviously from the new keyring (called .secondary_trusted_keys).
The new keyring needs to be enabled with CONFIG_SECONDARY_TRUSTED_KEYRING.
If the secondary keyring is enabled, a link is created from that to .builtin_trusted_keys so that the the latter will automatically be searched too if the secondary keyring is searched.
Signed-off-by: David Howells <dhowells@redhat.com> ---
certs/Kconfig | 8 ++++ certs/system_keyring.c | 79 ++++++++++++++++++++++++++++++++++------- include/keys/system_keyring.h | 4 ++ 3 files changed, 78 insertions(+), 13 deletions(-)
diff --git a/certs/Kconfig b/certs/Kconfig index 743d480f5f6f..fc5955f5fc8a 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -56,4 +56,12 @@ config SYSTEM_EXTRA_CERTIFICATE_SIZE This is the number of bytes reserved in the kernel image for a certificate to be inserted. +config SECONDARY_TRUSTED_KEYRING + bool "Provide a keyring to which extra trustable keys may be added" + depends on SYSTEM_TRUSTED_KEYRING + help + If set, provide a keyring to which extra keys may be added, provided + those keys are not blacklisted and are vouched for by a key built + into the kernel or already in the secondary trusted keyring. + endmenu diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 3cfc88c76aee..9700f37350ff 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -18,7 +18,10 @@ #include <keys/system_keyring.h> #include <crypto/pkcs7.h> -static struct key *system_trusted_keyring; +static struct key *builtin_trusted_keys; +#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING +static struct key *secondary_trusted_keys; +#endif extern __initconst const u8 system_certificate_list[]; extern __initconst const unsigned long system_certificate_list_size; @@ -33,26 +36,68 @@ int restrict_link_by_system_trusted(struct key *keyring, const struct key_type *type, const union key_payload *payload) { - return restrict_link_by_signature(system_trusted_keyring, - type, payload); + /* If we have a secondary trusted keyring, then that contains a link + * through to the builtin keyring and the search will follow that link. + */ +#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING + if (type == &key_type_keyring && + 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_signature(secondary_trusted_keys, type, payload); +#else + return restrict_link_by_signature(builtin_trusted_keys, type, payload); +#endif +} + +/** + * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA + * + * 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. + */ +int restrict_link_by_builtin_trusted(struct key *keyring, + const struct key_type *type, + const union key_payload *payload) +{ + return restrict_link_by_signature(builtin_trusted_keys, type, payload); } /* - * Load the compiled-in keys + * Create the trusted keyrings */ static __init int system_trusted_keyring_init(void) { - pr_notice("Initialise system trusted keyring\n"); + pr_notice("Initialise system trusted keyrings\n"); - system_trusted_keyring = - keyring_alloc(".system_keyring", + builtin_trusted_keys = + keyring_alloc(".builtin_trusted_keys", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), KEY_ALLOC_NOT_IN_QUOTA, + NULL, NULL); + if (IS_ERR(builtin_trusted_keys)) + panic("Can't allocate builtin trusted keyring\n"); + +#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING + secondary_trusted_keys = + keyring_alloc(".secondary_trusted_keys", + KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH | + KEY_USR_WRITE), + KEY_ALLOC_NOT_IN_QUOTA, restrict_link_by_system_trusted, NULL); - if (IS_ERR(system_trusted_keyring)) - panic("Can't allocate system trusted keyring\n"); + if (IS_ERR(secondary_trusted_keys)) + panic("Can't allocate secondary trusted keyring\n"); + + if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0) + panic("Can't link trusted keyrings\n"); +#endif + return 0; } @@ -88,7 +133,7 @@ static __init int load_system_certificate_list(void) if (plen > end - p) goto dodgy_cert; - key = key_create_or_update(make_key_ref(system_trusted_keyring, 1), + key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1), "asymmetric", NULL, p, @@ -125,7 +170,8 @@ late_initcall(load_system_certificate_list); * @len: Size of @data. * @raw_pkcs7: The PKCS#7 message that is the signature. * @pkcs7_len: The size of @raw_pkcs7. - * @trusted_keys: Trusted keys to use (NULL for system_trusted_keyring). + * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only, + * (void *)1UL for all trusted keys). * @usage: The use to which the key is being put. * @view_content: Callback to gain access to content. * @ctx: Context for callback. @@ -157,8 +203,15 @@ int verify_pkcs7_signature(const void *data, size_t len, if (ret < 0) goto error; - if (!trusted_keys) - trusted_keys = system_trusted_keyring; + if (!trusted_keys) { + trusted_keys = builtin_trusted_keys; + } else if (trusted_keys == (void *)1UL) { +#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING + trusted_keys = secondary_trusted_keys; +#else + trusted_keys = builtin_trusted_keys; +#endif + } ret = pkcs7_validate_trust(pkcs7, trusted_keys); if (ret < 0) { if (ret == -ENOKEY) diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 71f3e2523767..c6c05f1513f5 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -19,9 +19,13 @@ extern int restrict_link_by_system_trusted(struct key *keyring, const struct key_type *type, const union key_payload *payload); +extern int restrict_link_by_builtin_trusted(struct key *keyring, + const struct key_type *type, + const union key_payload *payload); #else #define restrict_link_by_system_trusted restrict_link_reject +#define restrict_link_by_builtin_trusted restrict_link_reject #endif #ifdef CONFIG_IMA_MOK_KEYRING
| |