diff options
author | David Howells <dhowells@redhat.com> | 2016-04-06 11:14:27 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-04-11 17:48:09 -0400 |
commit | d3bfe84129f65e0af2450743ebdab33d161d01c9 (patch) | |
tree | 37d567ed647f869e6a01cddcb40ec67b716204e0 | |
parent | 77f68bac9481ad440f4f34dda3d28c2dce6eb87b (diff) |
certs: Add a secondary system keyring that can be added to dynamically
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>
-rw-r--r-- | certs/Kconfig | 8 | ||||
-rw-r--r-- | certs/system_keyring.c | 87 | ||||
-rw-r--r-- | include/keys/system_keyring.h | 9 |
3 files changed, 88 insertions, 16 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 | |||
56 | This is the number of bytes reserved in the kernel image for a | 56 | This is the number of bytes reserved in the kernel image for a |
57 | certificate to be inserted. | 57 | certificate to be inserted. |
58 | 58 | ||
59 | config SECONDARY_TRUSTED_KEYRING | ||
60 | bool "Provide a keyring to which extra trustable keys may be added" | ||
61 | depends on SYSTEM_TRUSTED_KEYRING | ||
62 | help | ||
63 | If set, provide a keyring to which extra keys may be added, provided | ||
64 | those keys are not blacklisted and are vouched for by a key built | ||
65 | into the kernel or already in the secondary trusted keyring. | ||
66 | |||
59 | endmenu | 67 | endmenu |
diff --git a/certs/system_keyring.c b/certs/system_keyring.c index e460d00a7781..50979d6dcecd 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c | |||
@@ -18,41 +18,88 @@ | |||
18 | #include <keys/system_keyring.h> | 18 | #include <keys/system_keyring.h> |
19 | #include <crypto/pkcs7.h> | 19 | #include <crypto/pkcs7.h> |
20 | 20 | ||
21 | static struct key *system_trusted_keyring; | 21 | static struct key *builtin_trusted_keys; |
22 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING | ||
23 | static struct key *secondary_trusted_keys; | ||
24 | #endif | ||
22 | 25 | ||
23 | extern __initconst const u8 system_certificate_list[]; | 26 | extern __initconst const u8 system_certificate_list[]; |
24 | extern __initconst const unsigned long system_certificate_list_size; | 27 | extern __initconst const unsigned long system_certificate_list_size; |
25 | 28 | ||
26 | /** | 29 | /** |
27 | * restrict_link_by_builtin_trusted - Restrict keyring addition by system CA | 30 | * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA |
28 | * | 31 | * |
29 | * Restrict the addition of keys into a keyring based on the key-to-be-added | 32 | * Restrict the addition of keys into a keyring based on the key-to-be-added |
30 | * being vouched for by a key in the system keyring. | 33 | * being vouched for by a key in the built in system keyring. |
31 | */ | 34 | */ |
32 | int restrict_link_by_builtin_trusted(struct key *keyring, | 35 | int restrict_link_by_builtin_trusted(struct key *keyring, |
33 | const struct key_type *type, | 36 | const struct key_type *type, |
34 | const union key_payload *payload) | 37 | const union key_payload *payload) |
35 | { | 38 | { |
36 | return restrict_link_by_signature(system_trusted_keyring, | 39 | return restrict_link_by_signature(builtin_trusted_keys, type, payload); |
37 | type, payload); | ||
38 | } | 40 | } |
39 | 41 | ||
42 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING | ||
43 | /** | ||
44 | * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring | ||
45 | * addition by both builtin and secondary keyrings | ||
46 | * | ||
47 | * Restrict the addition of keys into a keyring based on the key-to-be-added | ||
48 | * being vouched for by a key in either the built-in or the secondary system | ||
49 | * keyrings. | ||
50 | */ | ||
51 | int restrict_link_by_builtin_and_secondary_trusted( | ||
52 | struct key *keyring, | ||
53 | const struct key_type *type, | ||
54 | const union key_payload *payload) | ||
55 | { | ||
56 | /* If we have a secondary trusted keyring, then that contains a link | ||
57 | * through to the builtin keyring and the search will follow that link. | ||
58 | */ | ||
59 | if (type == &key_type_keyring && | ||
60 | keyring == secondary_trusted_keys && | ||
61 | payload == &builtin_trusted_keys->payload) | ||
62 | /* Allow the builtin keyring to be added to the secondary */ | ||
63 | return 0; | ||
64 | |||
65 | return restrict_link_by_signature(secondary_trusted_keys, type, payload); | ||
66 | } | ||
67 | #endif | ||
68 | |||
40 | /* | 69 | /* |
41 | * Load the compiled-in keys | 70 | * Create the trusted keyrings |
42 | */ | 71 | */ |
43 | static __init int system_trusted_keyring_init(void) | 72 | static __init int system_trusted_keyring_init(void) |
44 | { | 73 | { |
45 | pr_notice("Initialise system trusted keyring\n"); | 74 | pr_notice("Initialise system trusted keyrings\n"); |
46 | 75 | ||
47 | system_trusted_keyring = | 76 | builtin_trusted_keys = |
48 | keyring_alloc(".system_keyring", | 77 | keyring_alloc(".builtin_trusted_keys", |
49 | KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), | 78 | KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), |
50 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | | 79 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | |
51 | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), | 80 | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), |
52 | KEY_ALLOC_NOT_IN_QUOTA, | 81 | KEY_ALLOC_NOT_IN_QUOTA, |
53 | restrict_link_by_builtin_trusted, NULL); | 82 | NULL, NULL); |
54 | if (IS_ERR(system_trusted_keyring)) | 83 | if (IS_ERR(builtin_trusted_keys)) |
55 | panic("Can't allocate system trusted keyring\n"); | 84 | panic("Can't allocate builtin trusted keyring\n"); |
85 | |||
86 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING | ||
87 | secondary_trusted_keys = | ||
88 | keyring_alloc(".secondary_trusted_keys", | ||
89 | KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), | ||
90 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | | ||
91 | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH | | ||
92 | KEY_USR_WRITE), | ||
93 | KEY_ALLOC_NOT_IN_QUOTA, | ||
94 | restrict_link_by_builtin_and_secondary_trusted, | ||
95 | NULL); | ||
96 | if (IS_ERR(secondary_trusted_keys)) | ||
97 | panic("Can't allocate secondary trusted keyring\n"); | ||
98 | |||
99 | if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0) | ||
100 | panic("Can't link trusted keyrings\n"); | ||
101 | #endif | ||
102 | |||
56 | return 0; | 103 | return 0; |
57 | } | 104 | } |
58 | 105 | ||
@@ -88,7 +135,7 @@ static __init int load_system_certificate_list(void) | |||
88 | if (plen > end - p) | 135 | if (plen > end - p) |
89 | goto dodgy_cert; | 136 | goto dodgy_cert; |
90 | 137 | ||
91 | key = key_create_or_update(make_key_ref(system_trusted_keyring, 1), | 138 | key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1), |
92 | "asymmetric", | 139 | "asymmetric", |
93 | NULL, | 140 | NULL, |
94 | p, | 141 | p, |
@@ -125,7 +172,8 @@ late_initcall(load_system_certificate_list); | |||
125 | * @len: Size of @data. | 172 | * @len: Size of @data. |
126 | * @raw_pkcs7: The PKCS#7 message that is the signature. | 173 | * @raw_pkcs7: The PKCS#7 message that is the signature. |
127 | * @pkcs7_len: The size of @raw_pkcs7. | 174 | * @pkcs7_len: The size of @raw_pkcs7. |
128 | * @trusted_keys: Trusted keys to use (NULL for system_trusted_keyring). | 175 | * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only, |
176 | * (void *)1UL for all trusted keys). | ||
129 | * @usage: The use to which the key is being put. | 177 | * @usage: The use to which the key is being put. |
130 | * @view_content: Callback to gain access to content. | 178 | * @view_content: Callback to gain access to content. |
131 | * @ctx: Context for callback. | 179 | * @ctx: Context for callback. |
@@ -157,8 +205,15 @@ int verify_pkcs7_signature(const void *data, size_t len, | |||
157 | if (ret < 0) | 205 | if (ret < 0) |
158 | goto error; | 206 | goto error; |
159 | 207 | ||
160 | if (!trusted_keys) | 208 | if (!trusted_keys) { |
161 | trusted_keys = system_trusted_keyring; | 209 | trusted_keys = builtin_trusted_keys; |
210 | } else if (trusted_keys == (void *)1UL) { | ||
211 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING | ||
212 | trusted_keys = secondary_trusted_keys; | ||
213 | #else | ||
214 | trusted_keys = builtin_trusted_keys; | ||
215 | #endif | ||
216 | } | ||
162 | ret = pkcs7_validate_trust(pkcs7, trusted_keys); | 217 | ret = pkcs7_validate_trust(pkcs7, trusted_keys); |
163 | if (ret < 0) { | 218 | if (ret < 0) { |
164 | if (ret == -ENOKEY) | 219 | if (ret == -ENOKEY) |
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index c72330ae76df..614424029de7 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h | |||
@@ -24,6 +24,15 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring, | |||
24 | #define restrict_link_by_builtin_trusted restrict_link_reject | 24 | #define restrict_link_by_builtin_trusted restrict_link_reject |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING | ||
28 | extern int restrict_link_by_builtin_and_secondary_trusted( | ||
29 | struct key *keyring, | ||
30 | const struct key_type *type, | ||
31 | const union key_payload *payload); | ||
32 | #else | ||
33 | #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted | ||
34 | #endif | ||
35 | |||
27 | #ifdef CONFIG_IMA_MOK_KEYRING | 36 | #ifdef CONFIG_IMA_MOK_KEYRING |
28 | extern struct key *ima_mok_keyring; | 37 | extern struct key *ima_mok_keyring; |
29 | extern struct key *ima_blacklist_keyring; | 38 | extern struct key *ima_blacklist_keyring; |