summaryrefslogtreecommitdiffstats
path: root/crypto/asymmetric_keys/pkcs7_trust.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-09-16 18:36:15 +0200
committerDavid Howells <dhowells@redhat.com>2014-09-16 18:36:15 +0200
commit41559420003cfe99522257dded7793192c77b4e9 (patch)
tree478af8309836992b40385a1aff6d8eae537d44c4 /crypto/asymmetric_keys/pkcs7_trust.c
parentKEYS: Overhaul key identification when searching for asymmetric keys (diff)
downloadlinux-41559420003cfe99522257dded7793192c77b4e9.tar.xz
linux-41559420003cfe99522257dded7793192c77b4e9.zip
PKCS#7: Better handling of unsupported crypto
Provide better handling of unsupported crypto when verifying a PKCS#7 message. If we can't bridge the gap between a pair of X.509 certs or between a signed info block and an X.509 cert because it involves some crypto we don't support, that's not necessarily the end of the world as there may be other ways points at which we can intersect with a ring of trusted keys. Instead, only produce ENOPKG immediately if all the signed info blocks in a PKCS#7 message require unsupported crypto to bridge to the first X.509 cert. Otherwise, we defer the generation of ENOPKG until we get ENOKEY during trust validation. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Vivek Goyal <vgoyal@redhat.com>
Diffstat (limited to 'crypto/asymmetric_keys/pkcs7_trust.c')
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 09197e50fa82..8bd474e5e706 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -35,6 +35,11 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
kenter(",%u,", sinfo->index);
+ if (sinfo->unsupported_crypto) {
+ kleave(" = -ENOPKG [cached]");
+ return -ENOPKG;
+ }
+
for (x509 = sinfo->signer; x509; x509 = x509->signer) {
if (x509->seen) {
if (x509->verified) {
@@ -139,24 +144,28 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
{
struct pkcs7_signed_info *sinfo;
struct x509_certificate *p;
- int cached_ret = 0, ret;
+ int cached_ret = -ENOKEY;
+ int ret;
for (p = pkcs7->certs; p; p = p->next)
p->seen = false;
for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring);
- if (ret < 0) {
- if (ret == -ENOPKG) {
+ switch (ret) {
+ case -ENOKEY:
+ continue;
+ case -ENOPKG:
+ if (cached_ret == -ENOKEY)
cached_ret = -ENOPKG;
- } else if (ret == -ENOKEY) {
- if (cached_ret == 0)
- cached_ret = -ENOKEY;
- } else {
- return ret;
- }
+ continue;
+ case 0:
+ *_trusted |= sinfo->trusted;
+ cached_ret = 0;
+ continue;
+ default:
+ return ret;
}
- *_trusted |= sinfo->trusted;
}
return cached_ret;