Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+11 -32
+4 -9
certs/system_keyring.c
··· 121 121 int verify_pkcs7_signature(const void *data, size_t len, 122 122 const void *raw_pkcs7, size_t pkcs7_len, 123 123 struct key *trusted_keys, 124 - int untrusted_error, 125 124 enum key_being_used_for usage, 126 125 int (*view_content)(void *ctx, 127 126 const void *data, size_t len, ··· 128 129 void *ctx) 129 130 { 130 131 struct pkcs7_message *pkcs7; 131 - bool trusted; 132 132 int ret; 133 133 134 134 pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len); ··· 147 149 148 150 if (!trusted_keys) 149 151 trusted_keys = system_trusted_keyring; 150 - ret = pkcs7_validate_trust(pkcs7, trusted_keys, &trusted); 151 - if (ret < 0) 152 - goto error; 153 - 154 - if (!trusted && untrusted_error) { 155 - pr_err("PKCS#7 signature not signed with a trusted key\n"); 156 - ret = untrusted_error; 152 + ret = pkcs7_validate_trust(pkcs7, trusted_keys); 153 + if (ret < 0) { 154 + if (ret == -ENOKEY) 155 + pr_err("PKCS#7 signature not signed with a trusted key\n"); 157 156 goto error; 158 157 } 159 158
+1 -1
crypto/asymmetric_keys/pkcs7_key_type.c
··· 62 62 63 63 return verify_pkcs7_signature(NULL, 0, 64 64 prep->data, prep->datalen, 65 - NULL, -ENOKEY, usage, 65 + NULL, usage, 66 66 pkcs7_view_content, prep); 67 67 } 68 68
-1
crypto/asymmetric_keys/pkcs7_parser.h
··· 22 22 struct pkcs7_signed_info *next; 23 23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ 24 24 unsigned index; 25 - bool trusted; 26 25 bool unsupported_crypto; /* T if not usable due to missing crypto */ 27 26 28 27 /* Message digest - the digest of the Content Data (or NULL) */
+3 -15
crypto/asymmetric_keys/pkcs7_trust.c
··· 30 30 struct public_key_signature *sig = sinfo->sig; 31 31 struct x509_certificate *x509, *last = NULL, *p; 32 32 struct key *key; 33 - bool trusted; 34 33 int ret; 35 34 36 35 kenter(",%u,", sinfo->index); ··· 41 42 42 43 for (x509 = sinfo->signer; x509; x509 = x509->signer) { 43 44 if (x509->seen) { 44 - if (x509->verified) { 45 - trusted = x509->trusted; 45 + if (x509->verified) 46 46 goto verified; 47 - } 48 47 kleave(" = -ENOKEY [cached]"); 49 48 return -ENOKEY; 50 49 } ··· 119 122 120 123 matched: 121 124 ret = verify_signature(key, sig); 122 - trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags); 123 125 key_put(key); 124 126 if (ret < 0) { 125 127 if (ret == -ENOMEM) ··· 130 134 verified: 131 135 if (x509) { 132 136 x509->verified = true; 133 - for (p = sinfo->signer; p != x509; p = p->signer) { 137 + for (p = sinfo->signer; p != x509; p = p->signer) 134 138 p->verified = true; 135 - p->trusted = trusted; 136 - } 137 139 } 138 - sinfo->trusted = trusted; 139 140 kleave(" = 0"); 140 141 return 0; 141 142 } ··· 141 148 * pkcs7_validate_trust - Validate PKCS#7 trust chain 142 149 * @pkcs7: The PKCS#7 certificate to validate 143 150 * @trust_keyring: Signing certificates to use as starting points 144 - * @_trusted: Set to true if trustworth, false otherwise 145 151 * 146 152 * Validate that the certificate chain inside the PKCS#7 message intersects 147 153 * keys we already know and trust. ··· 162 170 * May also return -ENOMEM. 163 171 */ 164 172 int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 165 - struct key *trust_keyring, 166 - bool *_trusted) 173 + struct key *trust_keyring) 167 174 { 168 175 struct pkcs7_signed_info *sinfo; 169 176 struct x509_certificate *p; 170 177 int cached_ret = -ENOKEY; 171 178 int ret; 172 - 173 - *_trusted = false; 174 179 175 180 for (p = pkcs7->certs; p; p = p->next) 176 181 p->seen = false; ··· 182 193 cached_ret = -ENOPKG; 183 194 continue; 184 195 case 0: 185 - *_trusted |= sinfo->trusted; 186 196 cached_ret = 0; 187 197 continue; 188 198 default:
+1 -1
crypto/asymmetric_keys/verify_pefile.c
··· 436 436 437 437 ret = verify_pkcs7_signature(NULL, 0, 438 438 pebuf + ctx.sig_offset, ctx.sig_len, 439 - trusted_keys, -EKEYREJECTED, usage, 439 + trusted_keys, usage, 440 440 mscode_parse, &ctx); 441 441 if (ret < 0) 442 442 goto error;
-1
crypto/asymmetric_keys/x509_parser.h
··· 39 39 unsigned index; 40 40 bool seen; /* Infinite recursion prevention */ 41 41 bool verified; 42 - bool trusted; 43 42 bool self_signed; /* T if self-signed (check unsupported_sig too) */ 44 43 bool unsupported_key; /* T if key uses unsupported crypto */ 45 44 bool unsupported_sig; /* T if signature uses unsupported crypto */
+1 -2
include/crypto/pkcs7.h
··· 33 33 * pkcs7_trust.c 34 34 */ 35 35 extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 36 - struct key *trust_keyring, 37 - bool *_trusted); 36 + struct key *trust_keyring); 38 37 39 38 /* 40 39 * pkcs7_verify.c
-1
include/linux/verification.h
··· 33 33 extern int verify_pkcs7_signature(const void *data, size_t len, 34 34 const void *raw_pkcs7, size_t pkcs7_len, 35 35 struct key *trusted_keys, 36 - int untrusted_error, 37 36 enum key_being_used_for usage, 38 37 int (*view_content)(void *ctx, 39 38 const void *data, size_t len,
+1 -1
kernel/module_signing.c
··· 81 81 } 82 82 83 83 return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, 84 - NULL, -ENOKEY, VERIFYING_MODULE_SIGNATURE, 84 + NULL, VERIFYING_MODULE_SIGNATURE, 85 85 NULL, NULL); 86 86 }