aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--certs/system_keyring.c20
-rw-r--r--crypto/asymmetric_keys/restrict.c62
-rw-r--r--crypto/asymmetric_keys/x509_parser.h6
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c21
-rw-r--r--include/crypto/public_key.h7
-rw-r--r--include/keys/system_keyring.h19
-rw-r--r--kernel/module_signing.c2
-rw-r--r--security/integrity/digsig.c33
-rw-r--r--security/integrity/ima/ima_mok.c6
9 files changed, 100 insertions, 76 deletions
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 417d65882870..4e2fa8ab01d6 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -18,12 +18,26 @@
18#include <keys/system_keyring.h> 18#include <keys/system_keyring.h>
19#include <crypto/pkcs7.h> 19#include <crypto/pkcs7.h>
20 20
21struct key *system_trusted_keyring; 21static struct key *system_trusted_keyring;
22EXPORT_SYMBOL_GPL(system_trusted_keyring);
23 22
24extern __initconst const u8 system_certificate_list[]; 23extern __initconst const u8 system_certificate_list[];
25extern __initconst const unsigned long system_certificate_list_size; 24extern __initconst const unsigned long system_certificate_list_size;
26 25
26/**
27 * restrict_link_by_builtin_trusted - Restrict keyring addition by system CA
28 *
29 * 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.
31 */
32int restrict_link_by_builtin_trusted(struct key *keyring,
33 const struct key_type *type,
34 unsigned long flags,
35 const union key_payload *payload)
36{
37 return restrict_link_by_signature(system_trusted_keyring,
38 type, payload);
39}
40
27/* 41/*
28 * Load the compiled-in keys 42 * Load the compiled-in keys
29 */ 43 */
@@ -37,7 +51,7 @@ static __init int system_trusted_keyring_init(void)
37 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 51 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
38 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), 52 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
39 KEY_ALLOC_NOT_IN_QUOTA, 53 KEY_ALLOC_NOT_IN_QUOTA,
40 keyring_restrict_trusted_only, NULL); 54 restrict_link_by_builtin_trusted, NULL);
41 if (IS_ERR(system_trusted_keyring)) 55 if (IS_ERR(system_trusted_keyring))
42 panic("Can't allocate system trusted keyring\n"); 56 panic("Can't allocate system trusted keyring\n");
43 return 0; 57 return 0;
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
index b4c10f2f5034..ac4bddf669de 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c
@@ -1,6 +1,6 @@
1/* Instantiate a public key crypto key from an X.509 Certificate 1/* Instantiate a public key crypto key from an X.509 Certificate
2 * 2 *
3 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -9,20 +9,12 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12#define pr_fmt(fmt) "X.509: "fmt 12#define pr_fmt(fmt) "ASYM: "fmt
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/err.h> 15#include <linux/err.h>
17#include <linux/mpi.h>
18#include <linux/asn1_decoder.h>
19#include <keys/asymmetric-subtype.h>
20#include <keys/asymmetric-parser.h>
21#include <keys/system_keyring.h>
22#include <crypto/hash.h>
23#include <crypto/public_key.h> 16#include <crypto/public_key.h>
24#include "asymmetric_keys.h" 17#include "asymmetric_keys.h"
25#include "x509_parser.h"
26 18
27static bool use_builtin_keys; 19static bool use_builtin_keys;
28static struct asymmetric_key_id *ca_keyid; 20static struct asymmetric_key_id *ca_keyid;
@@ -62,45 +54,55 @@ static int __init ca_keys_setup(char *str)
62__setup("ca_keys=", ca_keys_setup); 54__setup("ca_keys=", ca_keys_setup);
63#endif 55#endif
64 56
65/* 57/**
58 * restrict_link_by_signature - Restrict additions to a ring of public keys
59 * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
60 * @type: The type of key being added.
61 * @payload: The payload of the new key.
62 *
66 * Check the new certificate against the ones in the trust keyring. If one of 63 * Check the new certificate against the ones in the trust keyring. If one of
67 * those is the signing key and validates the new certificate, then mark the 64 * those is the signing key and validates the new certificate, then mark the
68 * new certificate as being trusted. 65 * new certificate as being trusted.
69 * 66 *
70 * Return 0 if the new certificate was successfully validated, 1 if we couldn't 67 * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
71 * find a matching parent certificate in the trusted list and an error if there 68 * matching parent certificate in the trusted list, -EKEYREJECTED if the
72 * is a matching certificate but the signature check fails. 69 * signature check fails or the key is blacklisted and some other error if
70 * there is a matching certificate but the signature check cannot be performed.
73 */ 71 */
74int x509_validate_trust(struct x509_certificate *cert, 72int restrict_link_by_signature(struct key *trust_keyring,
75 struct key *trust_keyring) 73 const struct key_type *type,
74 const union key_payload *payload)
76{ 75{
77 struct public_key_signature *sig = cert->sig; 76 const struct public_key_signature *sig;
78 struct key *key; 77 struct key *key;
79 int ret = 1; 78 int ret;
80 79
81 if (!sig->auth_ids[0] && !sig->auth_ids[1]) 80 pr_devel("==>%s()\n", __func__);
82 return 1;
83 81
84 if (!trust_keyring) 82 if (!trust_keyring)
83 return -ENOKEY;
84
85 if (type != &key_type_asymmetric)
85 return -EOPNOTSUPP; 86 return -EOPNOTSUPP;
87
88 sig = payload->data[asym_auth];
89 if (!sig->auth_ids[0] && !sig->auth_ids[1])
90 return 0;
91
86 if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid)) 92 if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
87 return -EPERM; 93 return -EPERM;
88 if (cert->unsupported_sig)
89 return -ENOPKG;
90 94
95 /* See if we have a key that signed this one. */
91 key = find_asymmetric_key(trust_keyring, 96 key = find_asymmetric_key(trust_keyring,
92 sig->auth_ids[0], sig->auth_ids[1], 97 sig->auth_ids[0], sig->auth_ids[1],
93 false); 98 false);
94 if (IS_ERR(key)) 99 if (IS_ERR(key))
95 return PTR_ERR(key); 100 return -ENOKEY;
96 101
97 if (!use_builtin_keys || 102 if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
98 test_bit(KEY_FLAG_BUILTIN, &key->flags)) { 103 ret = -ENOKEY;
99 ret = verify_signature(key, cert->sig); 104 else
100 if (ret == -ENOPKG) 105 ret = verify_signature(key, sig);
101 cert->unsupported_sig = true;
102 }
103 key_put(key); 106 key_put(key);
104 return ret; 107 return ret;
105} 108}
106EXPORT_SYMBOL_GPL(x509_validate_trust);
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 7a802b09a509..05eef1c68881 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -58,9 +58,3 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen,
58 */ 58 */
59extern int x509_get_sig_params(struct x509_certificate *cert); 59extern int x509_get_sig_params(struct x509_certificate *cert);
60extern int x509_check_for_self_signed(struct x509_certificate *cert); 60extern int x509_check_for_self_signed(struct x509_certificate *cert);
61
62/*
63 * public_key_trust.c
64 */
65extern int x509_validate_trust(struct x509_certificate *cert,
66 struct key *trust_keyring);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 6d7f42f0de9a..fb732296cd36 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -178,31 +178,12 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
178 178
179 cert->pub->id_type = "X509"; 179 cert->pub->id_type = "X509";
180 180
181 /* See if we can derive the trustability of this certificate. 181 if (cert->unsupported_sig) {
182 *
183 * When it comes to self-signed certificates, we cannot evaluate
184 * trustedness except by the fact that we obtained it from a trusted
185 * location. So we just rely on x509_validate_trust() failing in this
186 * case.
187 *
188 * Note that there's a possibility of a self-signed cert matching a
189 * cert that we have (most likely a duplicate that we already trust) -
190 * in which case it will be marked trusted.
191 */
192 if (cert->unsupported_sig || cert->self_signed) {
193 public_key_signature_free(cert->sig); 182 public_key_signature_free(cert->sig);
194 cert->sig = NULL; 183 cert->sig = NULL;
195 } else { 184 } else {
196 pr_devel("Cert Signature: %s + %s\n", 185 pr_devel("Cert Signature: %s + %s\n",
197 cert->sig->pkey_algo, cert->sig->hash_algo); 186 cert->sig->pkey_algo, cert->sig->hash_algo);
198
199 ret = x509_validate_trust(cert, get_system_trusted_keyring());
200 if (ret)
201 ret = x509_validate_trust(cert, get_ima_mok_keyring());
202 if (ret == -EKEYREJECTED)
203 goto error_free_cert;
204 if (!ret)
205 prep->trusted = true;
206 } 187 }
207 188
208 /* Propose a description */ 189 /* Propose a description */
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 96ef27b8dd41..882ca0e1e7a5 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -47,6 +47,13 @@ extern void public_key_signature_free(struct public_key_signature *sig);
47extern struct asymmetric_key_subtype public_key_subtype; 47extern struct asymmetric_key_subtype public_key_subtype;
48 48
49struct key; 49struct key;
50struct key_type;
51union key_payload;
52
53extern int restrict_link_by_signature(struct key *trust_keyring,
54 const struct key_type *type,
55 const union key_payload *payload);
56
50extern int verify_signature(const struct key *key, 57extern int verify_signature(const struct key *key,
51 const struct public_key_signature *sig); 58 const struct public_key_signature *sig);
52 59
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index b2d645ac35a0..93715913a0b1 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -12,22 +12,17 @@
12#ifndef _KEYS_SYSTEM_KEYRING_H 12#ifndef _KEYS_SYSTEM_KEYRING_H
13#define _KEYS_SYSTEM_KEYRING_H 13#define _KEYS_SYSTEM_KEYRING_H
14 14
15#include <linux/key.h>
16
15#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING 17#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
16 18
17#include <linux/key.h> 19extern int restrict_link_by_builtin_trusted(struct key *keyring,
18#include <linux/verification.h> 20 const struct key_type *type,
19#include <crypto/public_key.h> 21 unsigned long flags,
22 const union key_payload *payload);
20 23
21extern struct key *system_trusted_keyring;
22static inline struct key *get_system_trusted_keyring(void)
23{
24 return system_trusted_keyring;
25}
26#else 24#else
27static inline struct key *get_system_trusted_keyring(void) 25#define restrict_link_by_builtin_trusted restrict_link_reject
28{
29 return NULL;
30}
31#endif 26#endif
32 27
33#ifdef CONFIG_IMA_MOK_KEYRING 28#ifdef CONFIG_IMA_MOK_KEYRING
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index 6a64e03b9f44..937c844bee4a 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -12,7 +12,7 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <keys/system_keyring.h> 15#include <linux/verification.h>
16#include <crypto/public_key.h> 16#include <crypto/public_key.h>
17#include "module-internal.h" 17#include "module-internal.h"
18 18
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 659566c2200b..d647178c6bbd 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -18,6 +18,8 @@
18#include <linux/cred.h> 18#include <linux/cred.h>
19#include <linux/key-type.h> 19#include <linux/key-type.h>
20#include <linux/digsig.h> 20#include <linux/digsig.h>
21#include <crypto/public_key.h>
22#include <keys/system_keyring.h>
21 23
22#include "integrity.h" 24#include "integrity.h"
23 25
@@ -40,6 +42,35 @@ static bool init_keyring __initdata = true;
40static bool init_keyring __initdata; 42static bool init_keyring __initdata;
41#endif 43#endif
42 44
45#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
46/*
47 * Restrict the addition of keys into the IMA keyring.
48 *
49 * Any key that needs to go in .ima keyring must be signed by CA in
50 * either .system or .ima_mok keyrings.
51 */
52static int restrict_link_by_ima_mok(struct key *keyring,
53 const struct key_type *type,
54 unsigned long flags,
55 const union key_payload *payload)
56{
57 int ret;
58
59 ret = restrict_link_by_builtin_trusted(keyring, type, flags, payload);
60 if (ret != -ENOKEY)
61 return ret;
62
63 return restrict_link_by_signature(get_ima_mok_keyring(),
64 type, payload);
65}
66#else
67/*
68 * If there's no system trusted keyring, then keys cannot be loaded into
69 * .ima_mok and added keys cannot be marked trusted.
70 */
71#define restrict_link_by_ima_mok restrict_link_reject
72#endif
73
43int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 74int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
44 const char *digest, int digestlen) 75 const char *digest, int digestlen)
45{ 76{
@@ -84,7 +115,7 @@ int __init integrity_init_keyring(const unsigned int id)
84 KEY_USR_VIEW | KEY_USR_READ | 115 KEY_USR_VIEW | KEY_USR_READ |
85 KEY_USR_WRITE | KEY_USR_SEARCH), 116 KEY_USR_WRITE | KEY_USR_SEARCH),
86 KEY_ALLOC_NOT_IN_QUOTA, 117 KEY_ALLOC_NOT_IN_QUOTA,
87 NULL, NULL); 118 restrict_link_by_ima_mok, NULL);
88 if (IS_ERR(keyring[id])) { 119 if (IS_ERR(keyring[id])) {
89 err = PTR_ERR(keyring[id]); 120 err = PTR_ERR(keyring[id]);
90 pr_info("Can't allocate %s keyring (%d)\n", 121 pr_info("Can't allocate %s keyring (%d)\n",
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
index ef91248cb934..2988726d30d6 100644
--- a/security/integrity/ima/ima_mok.c
+++ b/security/integrity/ima/ima_mok.c
@@ -17,7 +17,7 @@
17#include <linux/cred.h> 17#include <linux/cred.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <keys/asymmetric-type.h> 20#include <keys/system_keyring.h>
21 21
22 22
23struct key *ima_mok_keyring; 23struct key *ima_mok_keyring;
@@ -36,7 +36,7 @@ __init int ima_mok_init(void)
36 KEY_USR_VIEW | KEY_USR_READ | 36 KEY_USR_VIEW | KEY_USR_READ |
37 KEY_USR_WRITE | KEY_USR_SEARCH, 37 KEY_USR_WRITE | KEY_USR_SEARCH,
38 KEY_ALLOC_NOT_IN_QUOTA, 38 KEY_ALLOC_NOT_IN_QUOTA,
39 keyring_restrict_trusted_only, NULL); 39 restrict_link_by_builtin_trusted, NULL);
40 40
41 ima_blacklist_keyring = keyring_alloc(".ima_blacklist", 41 ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
42 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 42 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
@@ -44,7 +44,7 @@ __init int ima_mok_init(void)
44 KEY_USR_VIEW | KEY_USR_READ | 44 KEY_USR_VIEW | KEY_USR_READ |
45 KEY_USR_WRITE | KEY_USR_SEARCH, 45 KEY_USR_WRITE | KEY_USR_SEARCH,
46 KEY_ALLOC_NOT_IN_QUOTA, 46 KEY_ALLOC_NOT_IN_QUOTA,
47 keyring_restrict_trusted_only, NULL); 47 restrict_link_by_builtin_trusted, NULL);
48 48
49 if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) 49 if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring))
50 panic("Can't allocate IMA MOK or blacklist keyrings."); 50 panic("Can't allocate IMA MOK or blacklist keyrings.");