summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-04-06 11:14:24 -0400
committerDavid Howells <dhowells@redhat.com>2016-04-06 11:14:24 -0400
commitbda850cd214e90b1be0cc25bc48c4f6ac53eb543 (patch)
treeacb936239ac766592c557295aec265ec9a2d04fb
parente68503bd6836ba765dc8e0ee77ea675fedc07e41 (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.c13
-rw-r--r--crypto/asymmetric_keys/pkcs7_key_type.c2
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.h1
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c18
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c2
-rw-r--r--crypto/asymmetric_keys/x509_parser.h1
-rw-r--r--include/crypto/pkcs7.h3
-rw-r--r--include/linux/verification.h1
-rw-r--r--kernel/module_signing.c2
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);
121int verify_pkcs7_signature(const void *data, size_t len, 121int 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
123matched: 120matched:
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:
134verified: 130verified:
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 */
172int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 164int 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 */
35extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 35extern 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;
33extern int verify_pkcs7_signature(const void *data, size_t len, 33extern 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}