From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752513AbcASLda (ORCPT ); Tue, 19 Jan 2016 06:33:30 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42774 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753605AbcASLcu (ORCPT ); Tue, 19 Jan 2016 06:32:50 -0500 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH 19/20] certs: Add a secondary system keyring that can be added to dynamically [ver #2] From: David Howells To: zohar@linux.vnet.ibm.com Cc: dhowells@redhat.com, linux-security-module@vger.kernel.org, keyrings@vger.kernel.org, petkan@mip-labs.com, linux-kernel@vger.kernel.org Date: Tue, 19 Jan 2016 11:32:47 +0000 Message-ID: <20160119113247.23238.30302.stgit@warthog.procyon.org.uk> In-Reply-To: <20160119113026.23238.4498.stgit@warthog.procyon.org.uk> References: <20160119113026.23238.4498.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- certs/Kconfig | 8 ++++ certs/system_keyring.c | 82 +++++++++++++++++++++++++++++++++++------ include/keys/system_keyring.h | 4 ++ 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/certs/Kconfig b/certs/Kconfig index 7ce41d4b541d..d78354bb5dfc 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -57,4 +57,12 @@ config SYSTEM_BLACKLIST_HASH_LIST wrapper to incorporate the list into the kernel. Each should be a string of hex digits. +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 5e76121d4cc2..4d930895f9ac 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -18,7 +18,10 @@ #include #include -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,25 +36,72 @@ int restrict_link_by_system_trusted(struct key *keyring, const struct key_type *type, const union key_payload *payload) { - return public_key_restrict_link(system_trusted_keyring, type, payload); + int ret; + + /* 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) + return 0; + + ret = public_key_restrict_link(secondary_trusted_keys, type, payload); +#else + ret = public_key_restrict_link(builtin_trusted_keys, type, payload); +#endif + if (ret == 0 || ret == -EKEYREJECTED) + return ret; + return ret; +} + +/** + * 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 public_key_restrict_link(secondary_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"); +#endif + + if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0) + panic("Can't link trusted keyrings\n"); + return 0; } @@ -87,7 +137,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, @@ -124,7 +174,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. @@ -156,8 +207,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 15107dcc2ec4..b261362c8b2d 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -19,6 +19,10 @@ 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); #endif #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING