diff options
author | David Howells <dhowells@redhat.com> | 2016-04-06 11:14:24 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-04-06 11:14:24 -0400 |
commit | bda850cd214e90b1be0cc25bc48c4f6ac53eb543 (patch) | |
tree | acb936239ac766592c557295aec265ec9a2d04fb | |
parent | e68503bd6836ba765dc8e0ee77ea675fedc07e41 (diff) |
PKCS#7: Make trust determination dependent on contents of trust keyring
Make the determination of the trustworthiness of a key dependent on whether
a key that can verify it is present in the supplied ring of trusted keys
rather than whether or not the verifying key has KEY_FLAG_TRUSTED set.
verify_pkcs7_signature() will return -ENOKEY if the PKCS#7 message trust
chain cannot be verified.
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | certs/system_keyring.c | 13 | ||||
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_key_type.c | 2 | ||||
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_parser.h | 1 | ||||
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_trust.c | 18 | ||||
-rw-r--r-- | crypto/asymmetric_keys/verify_pefile.c | 2 | ||||
-rw-r--r-- | crypto/asymmetric_keys/x509_parser.h | 1 | ||||
-rw-r--r-- | include/crypto/pkcs7.h | 3 | ||||
-rw-r--r-- | include/linux/verification.h | 1 | ||||
-rw-r--r-- | kernel/module_signing.c | 2 |
9 files changed, 11 insertions, 32 deletions
diff --git a/certs/system_keyring.c b/certs/system_keyring.c index a83bffedc0aa..dc18869ff680 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c | |||
@@ -121,7 +121,6 @@ late_initcall(load_system_certificate_list); | |||
121 | int verify_pkcs7_signature(const void *data, size_t len, | 121 | int verify_pkcs7_signature(const void *data, size_t len, |
122 | const void *raw_pkcs7, size_t pkcs7_len, | 122 | const void *raw_pkcs7, size_t pkcs7_len, |
123 | struct key *trusted_keys, | 123 | struct key *trusted_keys, |
124 | int untrusted_error, | ||
125 | enum key_being_used_for usage, | 124 | enum key_being_used_for usage, |
126 | int (*view_content)(void *ctx, | 125 | int (*view_content)(void *ctx, |
127 | const void *data, size_t len, | 126 | const void *data, size_t len, |
@@ -129,7 +128,6 @@ int verify_pkcs7_signature(const void *data, size_t len, | |||
129 | void *ctx) | 128 | void *ctx) |
130 | { | 129 | { |
131 | struct pkcs7_message *pkcs7; | 130 | struct pkcs7_message *pkcs7; |
132 | bool trusted; | ||
133 | int ret; | 131 | int ret; |
134 | 132 | ||
135 | pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len); | 133 | pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len); |
@@ -149,13 +147,10 @@ int verify_pkcs7_signature(const void *data, size_t len, | |||
149 | 147 | ||
150 | if (!trusted_keys) | 148 | if (!trusted_keys) |
151 | trusted_keys = system_trusted_keyring; | 149 | trusted_keys = system_trusted_keyring; |
152 | ret = pkcs7_validate_trust(pkcs7, trusted_keys, &trusted); | 150 | ret = pkcs7_validate_trust(pkcs7, trusted_keys); |
153 | if (ret < 0) | 151 | if (ret < 0) { |
154 | goto error; | 152 | if (ret == -ENOKEY) |
155 | 153 | pr_err("PKCS#7 signature not signed with a trusted key\n"); | |
156 | if (!trusted && untrusted_error) { | ||
157 | pr_err("PKCS#7 signature not signed with a trusted key\n"); | ||
158 | ret = untrusted_error; | ||
159 | goto error; | 154 | goto error; |
160 | } | 155 | } |
161 | 156 | ||
diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c index ab9bf5363ecd..3b92523882e5 100644 --- a/crypto/asymmetric_keys/pkcs7_key_type.c +++ b/crypto/asymmetric_keys/pkcs7_key_type.c | |||
@@ -62,7 +62,7 @@ static int pkcs7_preparse(struct key_preparsed_payload *prep) | |||
62 | 62 | ||
63 | return verify_pkcs7_signature(NULL, 0, | 63 | return verify_pkcs7_signature(NULL, 0, |
64 | prep->data, prep->datalen, | 64 | prep->data, prep->datalen, |
65 | NULL, -ENOKEY, usage, | 65 | NULL, usage, |
66 | pkcs7_view_content, prep); | 66 | pkcs7_view_content, prep); |
67 | } | 67 | } |
68 | 68 | ||
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h index d5eec31e95b6..f4e81074f5e0 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.h +++ b/crypto/asymmetric_keys/pkcs7_parser.h | |||
@@ -22,7 +22,6 @@ struct pkcs7_signed_info { | |||
22 | struct pkcs7_signed_info *next; | 22 | struct pkcs7_signed_info *next; |
23 | struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ | 23 | struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ |
24 | unsigned index; | 24 | unsigned index; |
25 | bool trusted; | ||
26 | bool unsupported_crypto; /* T if not usable due to missing crypto */ | 25 | bool unsupported_crypto; /* T if not usable due to missing crypto */ |
27 | 26 | ||
28 | /* Message digest - the digest of the Content Data (or NULL) */ | 27 | /* Message digest - the digest of the Content Data (or NULL) */ |
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index b9a5487cd82d..36e77cb07bd0 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c | |||
@@ -30,7 +30,6 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, | |||
30 | struct public_key_signature *sig = sinfo->sig; | 30 | struct public_key_signature *sig = sinfo->sig; |
31 | struct x509_certificate *x509, *last = NULL, *p; | 31 | struct x509_certificate *x509, *last = NULL, *p; |
32 | struct key *key; | 32 | struct key *key; |
33 | bool trusted; | ||
34 | int ret; | 33 | int ret; |
35 | 34 | ||
36 | kenter(",%u,", sinfo->index); | 35 | kenter(",%u,", sinfo->index); |
@@ -42,10 +41,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, | |||
42 | 41 | ||
43 | for (x509 = sinfo->signer; x509; x509 = x509->signer) { | 42 | for (x509 = sinfo->signer; x509; x509 = x509->signer) { |
44 | if (x509->seen) { | 43 | if (x509->seen) { |
45 | if (x509->verified) { | 44 | if (x509->verified) |
46 | trusted = x509->trusted; | ||
47 | goto verified; | 45 | goto verified; |
48 | } | ||
49 | kleave(" = -ENOKEY [cached]"); | 46 | kleave(" = -ENOKEY [cached]"); |
50 | return -ENOKEY; | 47 | return -ENOKEY; |
51 | } | 48 | } |
@@ -122,7 +119,6 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, | |||
122 | 119 | ||
123 | matched: | 120 | matched: |
124 | ret = verify_signature(key, sig); | 121 | ret = verify_signature(key, sig); |
125 | trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags); | ||
126 | key_put(key); | 122 | key_put(key); |
127 | if (ret < 0) { | 123 | if (ret < 0) { |
128 | if (ret == -ENOMEM) | 124 | if (ret == -ENOMEM) |
@@ -134,12 +130,9 @@ matched: | |||
134 | verified: | 130 | verified: |
135 | if (x509) { | 131 | if (x509) { |
136 | x509->verified = true; | 132 | x509->verified = true; |
137 | for (p = sinfo->signer; p != x509; p = p->signer) { | 133 | for (p = sinfo->signer; p != x509; p = p->signer) |
138 | p->verified = true; | 134 | p->verified = true; |
139 | p->trusted = trusted; | ||
140 | } | ||
141 | } | 135 | } |
142 | sinfo->trusted = trusted; | ||
143 | kleave(" = 0"); | 136 | kleave(" = 0"); |
144 | return 0; | 137 | return 0; |
145 | } | 138 | } |
@@ -148,7 +141,6 @@ verified: | |||
148 | * pkcs7_validate_trust - Validate PKCS#7 trust chain | 141 | * pkcs7_validate_trust - Validate PKCS#7 trust chain |
149 | * @pkcs7: The PKCS#7 certificate to validate | 142 | * @pkcs7: The PKCS#7 certificate to validate |
150 | * @trust_keyring: Signing certificates to use as starting points | 143 | * @trust_keyring: Signing certificates to use as starting points |
151 | * @_trusted: Set to true if trustworth, false otherwise | ||
152 | * | 144 | * |
153 | * Validate that the certificate chain inside the PKCS#7 message intersects | 145 | * Validate that the certificate chain inside the PKCS#7 message intersects |
154 | * keys we already know and trust. | 146 | * keys we already know and trust. |
@@ -170,16 +162,13 @@ verified: | |||
170 | * May also return -ENOMEM. | 162 | * May also return -ENOMEM. |
171 | */ | 163 | */ |
172 | int pkcs7_validate_trust(struct pkcs7_message *pkcs7, | 164 | int pkcs7_validate_trust(struct pkcs7_message *pkcs7, |
173 | struct key *trust_keyring, | 165 | struct key *trust_keyring) |
174 | bool *_trusted) | ||
175 | { | 166 | { |
176 | struct pkcs7_signed_info *sinfo; | 167 | struct pkcs7_signed_info *sinfo; |
177 | struct x509_certificate *p; | 168 | struct x509_certificate *p; |
178 | int cached_ret = -ENOKEY; | 169 | int cached_ret = -ENOKEY; |
179 | int ret; | 170 | int ret; |
180 | 171 | ||
181 | *_trusted = false; | ||
182 | |||
183 | for (p = pkcs7->certs; p; p = p->next) | 172 | for (p = pkcs7->certs; p; p = p->next) |
184 | p->seen = false; | 173 | p->seen = false; |
185 | 174 | ||
@@ -193,7 +182,6 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7, | |||
193 | cached_ret = -ENOPKG; | 182 | cached_ret = -ENOPKG; |
194 | continue; | 183 | continue; |
195 | case 0: | 184 | case 0: |
196 | *_trusted |= sinfo->trusted; | ||
197 | cached_ret = 0; | 185 | cached_ret = 0; |
198 | continue; | 186 | continue; |
199 | default: | 187 | default: |
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 265351075b0e..672a94c2c3ff 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c | |||
@@ -436,7 +436,7 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen, | |||
436 | 436 | ||
437 | ret = verify_pkcs7_signature(NULL, 0, | 437 | ret = verify_pkcs7_signature(NULL, 0, |
438 | pebuf + ctx.sig_offset, ctx.sig_len, | 438 | pebuf + ctx.sig_offset, ctx.sig_len, |
439 | trusted_keys, -EKEYREJECTED, usage, | 439 | trusted_keys, usage, |
440 | mscode_parse, &ctx); | 440 | mscode_parse, &ctx); |
441 | if (ret < 0) | 441 | if (ret < 0) |
442 | goto error; | 442 | goto error; |
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h index f24f4d808e7f..05eef1c68881 100644 --- a/crypto/asymmetric_keys/x509_parser.h +++ b/crypto/asymmetric_keys/x509_parser.h | |||
@@ -39,7 +39,6 @@ struct x509_certificate { | |||
39 | unsigned index; | 39 | unsigned index; |
40 | bool seen; /* Infinite recursion prevention */ | 40 | bool seen; /* Infinite recursion prevention */ |
41 | bool verified; | 41 | bool verified; |
42 | bool trusted; | ||
43 | bool self_signed; /* T if self-signed (check unsupported_sig too) */ | 42 | bool self_signed; /* T if self-signed (check unsupported_sig too) */ |
44 | bool unsupported_key; /* T if key uses unsupported crypto */ | 43 | bool unsupported_key; /* T if key uses unsupported crypto */ |
45 | bool unsupported_sig; /* T if signature uses unsupported crypto */ | 44 | bool unsupported_sig; /* T if signature uses unsupported crypto */ |
diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h index 8323e3e57131..583f199400a3 100644 --- a/include/crypto/pkcs7.h +++ b/include/crypto/pkcs7.h | |||
@@ -33,8 +33,7 @@ extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, | |||
33 | * pkcs7_trust.c | 33 | * pkcs7_trust.c |
34 | */ | 34 | */ |
35 | extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, | 35 | extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, |
36 | struct key *trust_keyring, | 36 | struct key *trust_keyring); |
37 | bool *_trusted); | ||
38 | 37 | ||
39 | /* | 38 | /* |
40 | * pkcs7_verify.c | 39 | * pkcs7_verify.c |
diff --git a/include/linux/verification.h b/include/linux/verification.h index bb0fcf941cb7..a10549a6c7cd 100644 --- a/include/linux/verification.h +++ b/include/linux/verification.h | |||
@@ -33,7 +33,6 @@ struct key; | |||
33 | extern int verify_pkcs7_signature(const void *data, size_t len, | 33 | extern int verify_pkcs7_signature(const void *data, size_t len, |
34 | const void *raw_pkcs7, size_t pkcs7_len, | 34 | const void *raw_pkcs7, size_t pkcs7_len, |
35 | struct key *trusted_keys, | 35 | struct key *trusted_keys, |
36 | int untrusted_error, | ||
37 | enum key_being_used_for usage, | 36 | enum key_being_used_for usage, |
38 | int (*view_content)(void *ctx, | 37 | int (*view_content)(void *ctx, |
39 | const void *data, size_t len, | 38 | const void *data, size_t len, |
diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 593aace88a02..6a64e03b9f44 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c | |||
@@ -81,6 +81,6 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, | 83 | return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, |
84 | NULL, -ENOKEY, VERIFYING_MODULE_SIGNATURE, | 84 | NULL, VERIFYING_MODULE_SIGNATURE, |
85 | NULL, NULL); | 85 | NULL, NULL); |
86 | } | 86 | } |