diff options
author | David Howells <dhowells@redhat.com> | 2014-09-16 20:36:15 +0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-09-16 20:36:15 +0400 |
commit | 41559420003cfe99522257dded7793192c77b4e9 (patch) | |
tree | 478af8309836992b40385a1aff6d8eae537d44c4 /crypto/asymmetric_keys/x509_public_key.c | |
parent | 46963b774d441c833afc1535f6d84b3df2a94204 (diff) | |
download | linux-41559420003cfe99522257dded7793192c77b4e9.tar.xz |
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/x509_public_key.c')
-rw-r--r-- | crypto/asymmetric_keys/x509_public_key.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index c60905c3f4d2..1d9a4c555376 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -115,6 +115,8 @@ int x509_get_sig_params(struct x509_certificate *cert) pr_devel("==>%s()\n", __func__); + if (cert->unsupported_crypto) + return -ENOPKG; if (cert->sig.rsa.s) return 0; @@ -127,8 +129,13 @@ int x509_get_sig_params(struct x509_certificate *cert) * big the hash operational data will be. */ tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0); - if (IS_ERR(tfm)) - return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); + if (IS_ERR(tfm)) { + if (PTR_ERR(tfm) == -ENOENT) { + cert->unsupported_crypto = true; + return -ENOPKG; + } + return PTR_ERR(tfm); + } desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); digest_size = crypto_shash_digestsize(tfm); @@ -175,6 +182,8 @@ int x509_check_signature(const struct public_key *pub, return ret; ret = public_key_verify_signature(pub, &cert->sig); + if (ret == -ENOPKG) + cert->unsupported_crypto = true; pr_debug("Cert Verification: %d\n", ret); return ret; } |