* [PATCH 1/9] PKCS#7: fix certificate chain verification
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 2/9] PKCS#7: fix certificate blacklisting Eric Biggers
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings
Cc: linux-crypto, Michael Halcrow, Eric Biggers, stable
From: Eric Biggers <ebiggers@google.com>
When pkcs7_verify_sig_chain() is building the certificate chain for a
SignerInfo using the certificates in the PKCS#7 message, it is passing
the wrong arguments to public_key_verify_signature(). Consequently,
when the next certificate is supposed to be used to verify the previous
certificate, the next certificate is actually used to verify itself.
An attacker can use this bug to create a bogus certificate chain that
has no cryptographic relationship between the beginning and end.
Fortunately I couldn't quite find a way to use this to bypass the
overall signature verification, though it comes very close. Here's the
reasoning: due to the bug, every certificate in the chain beyond the
first actually has to be self-signed (where "self-signed" here refers to
the actual key and signature; an attacker might still manipulate the
certificate fields such that the self_signed flag doesn't actually get
set, and thus the chain doesn't end immediately). But to pass trust
validation (pkcs7_validate_trust()), either the SignerInfo or one of the
certificates has to actually be signed by a trusted key. Since only
self-signed certificates can be added to the chain, the only way for an
attacker to introduce a trusted signature is to include a self-signed
trusted certificate.
But, when pkcs7_validate_trust_one() reaches that certificate, instead
of trying to verify the signature on that certificate, it will actually
look up the corresponding trusted key, which will succeed, and then try
to verify the *previous* certificate, which will fail. Thus, disaster
is narrowly averted (as far as I could tell).
Fixes: 6c2dc5ae4ab7 ("X.509: Extract signature digest and make self-signed cert checks earlier")
Cc: <stable@vger.kernel.org> # v4.7+
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/pkcs7_verify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 39e6de0c2761..2f6a768b91d7 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -270,7 +270,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
sinfo->index);
return 0;
}
- ret = public_key_verify_signature(p->pub, p->sig);
+ ret = public_key_verify_signature(p->pub, x509->sig);
if (ret < 0)
return ret;
x509->signer = p;
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 2/9] PKCS#7: fix certificate blacklisting
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
2018-02-07 1:10 ` [PATCH 1/9] PKCS#7: fix certificate chain verification Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 3/9] PKCS#7: fix direct verification of SignerInfo signature Eric Biggers
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings
Cc: linux-crypto, Michael Halcrow, Eric Biggers, stable
From: Eric Biggers <ebiggers@google.com>
If there is a blacklisted certificate in a SignerInfo's certificate
chain, then pkcs7_verify_sig_chain() sets sinfo->blacklisted and returns
0. But, pkcs7_verify() fails to handle this case appropriately, as it
actually continues on to the line 'actual_ret = 0;', indicating that the
SignerInfo has passed verification. Consequently, PKCS#7 signature
verification ignores the certificate blacklist.
Fix this by not considering blacklisted SignerInfos to have passed
verification.
Also fix the function comment with regards to when 0 is returned.
Fixes: 03bb79315ddc ("PKCS#7: Handle blacklisted certificates")
Cc: <stable@vger.kernel.org> # v4.12+
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/pkcs7_verify.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 2f6a768b91d7..97c77f66b20d 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -366,8 +366,7 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
*
* (*) -EBADMSG if some part of the message was invalid, or:
*
- * (*) 0 if no signature chains were found to be blacklisted or to contain
- * unsupported crypto, or:
+ * (*) 0 if a signature chain passed verification, or:
*
* (*) -EKEYREJECTED if a blacklisted key was encountered, or:
*
@@ -423,8 +422,11 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
ret = pkcs7_verify_one(pkcs7, sinfo);
- if (sinfo->blacklisted && actual_ret == -ENOPKG)
- actual_ret = -EKEYREJECTED;
+ if (sinfo->blacklisted) {
+ if (actual_ret == -ENOPKG)
+ actual_ret = -EKEYREJECTED;
+ continue;
+ }
if (ret < 0) {
if (ret == -ENOPKG) {
sinfo->unsupported_crypto = true;
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 3/9] PKCS#7: fix direct verification of SignerInfo signature
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
2018-02-07 1:10 ` [PATCH 1/9] PKCS#7: fix certificate chain verification Eric Biggers
2018-02-07 1:10 ` [PATCH 2/9] PKCS#7: fix certificate blacklisting Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported Eric Biggers
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings; +Cc: linux-crypto, Michael Halcrow, Eric Biggers
From: Eric Biggers <ebiggers@google.com>
If none of the certificates in a SignerInfo's certificate chain match a
trusted key, nor is the last certificate signed by a trusted key, then
pkcs7_validate_trust_one() tries to check whether the SignerInfo's
signature was made directly by a trusted key. But, it actually fails to
set the 'sig' variable correctly, so it actually verifies the last
signature seen. That will only be the SignerInfo's signature if the
certificate chain is empty; otherwise it will actually be the last
certificate's signature.
This is not by itself a security problem, since verifying any of the
certificates in the chain should be sufficient to verify the SignerInfo.
Still, it's not working as intended so it should be fixed.
Fix it by setting 'sig' correctly for the direct verification case.
Fixes: 757932e6da6d ("PKCS#7: Handle PKCS#7 messages that contain no X.509 certs")
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/pkcs7_trust.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 1f4e25f10049..598906b1e28d 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -106,6 +106,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
pr_devel("sinfo %u: Direct signer is key %x\n",
sinfo->index, key_serial(key));
x509 = NULL;
+ sig = sinfo->sig;
goto matched;
}
if (PTR_ERR(key) != -ENOKEY)
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (2 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 3/9] PKCS#7: fix direct verification of SignerInfo signature Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 5/9] X.509: fix NULL dereference when restricting key with unsupported_sig Eric Biggers
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings
Cc: linux-crypto, Michael Halcrow, Eric Biggers, Paolo Valente,
stable
From: Eric Biggers <ebiggers@google.com>
The X.509 parser mishandles the case where the certificate's signature's
hash algorithm is not available in the crypto API. In this case,
x509_get_sig_params() doesn't allocate the cert->sig->digest buffer;
this part seems to be intentional. However,
public_key_verify_signature() is still called via
x509_check_for_self_signed(), which triggers the 'BUG_ON(!sig->digest)'.
Fix this by making public_key_verify_signature() return -ENOPKG if the
hash buffer has not been allocated.
Reproducer when all the CONFIG_CRYPTO_SHA512* options are disabled:
openssl req -new -sha512 -x509 -batch -nodes -outform der \
| keyctl padd asymmetric desc @s
Fixes: 6c2dc5ae4ab7 ("X.509: Extract signature digest and make self-signed cert checks earlier")
Reported-by: Paolo Valente <paolo.valente@linaro.org>
Cc: Paolo Valente <paolo.valente@linaro.org>
Cc: <stable@vger.kernel.org> # v4.7+
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/public_key.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index de996586762a..e929fe1e4106 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -79,9 +79,11 @@ int public_key_verify_signature(const struct public_key *pkey,
BUG_ON(!pkey);
BUG_ON(!sig);
- BUG_ON(!sig->digest);
BUG_ON(!sig->s);
+ if (!sig->digest)
+ return -ENOPKG;
+
alg_name = sig->pkey_algo;
if (strcmp(sig->pkey_algo, "rsa") == 0) {
/* The data wangled by the RSA algorithm is typically padded
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 5/9] X.509: fix NULL dereference when restricting key with unsupported_sig
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (3 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo Eric Biggers
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings
Cc: linux-crypto, Michael Halcrow, Eric Biggers, stable
From: Eric Biggers <ebiggers@google.com>
The asymmetric key type allows an X.509 certificate to be added even if
its signature's hash algorithm is not available in the crypto API. In
that case 'payload.data[asym_auth]' will be NULL. But the key
restriction code failed to check for this case before trying to use the
signature, resulting in a NULL pointer dereference in
key_or_keyring_common() or in restrict_link_by_signature().
Fix this by returning -ENOPKG when the signature is unsupported.
Reproducer when all the CONFIG_CRYPTO_SHA512* options are disabled and
keyctl has support for the 'restrict_keyring' command:
keyctl new_session
keyctl restrict_keyring @s asymmetric builtin_trusted
openssl req -new -sha512 -x509 -batch -nodes -outform der \
| keyctl padd asymmetric desc @s
Fixes: a511e1af8b12 ("KEYS: Move the point of trust determination to __key_link()")
Cc: <stable@vger.kernel.org> # v4.7+
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/restrict.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
index 86fb68508952..7c93c7728454 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c
@@ -67,8 +67,9 @@ __setup("ca_keys=", ca_keys_setup);
*
* Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
* matching parent certificate in the trusted list, -EKEYREJECTED if the
- * signature check fails or the key is blacklisted and some other error if
- * there is a matching certificate but the signature check cannot be performed.
+ * signature check fails or the key is blacklisted, -ENOPKG if the signature
+ * uses unsupported crypto, or some other error if there is a matching
+ * certificate but the signature check cannot be performed.
*/
int restrict_link_by_signature(struct key *dest_keyring,
const struct key_type *type,
@@ -88,6 +89,8 @@ int restrict_link_by_signature(struct key *dest_keyring,
return -EOPNOTSUPP;
sig = payload->data[asym_auth];
+ if (!sig)
+ return -ENOPKG;
if (!sig->auth_ids[0] && !sig->auth_ids[1])
return -ENOKEY;
@@ -139,6 +142,8 @@ static int key_or_keyring_common(struct key *dest_keyring,
return -EOPNOTSUPP;
sig = payload->data[asym_auth];
+ if (!sig)
+ return -ENOPKG;
if (!sig->auth_ids[0] && !sig->auth_ids[1])
return -ENOKEY;
@@ -222,9 +227,9 @@ static int key_or_keyring_common(struct key *dest_keyring,
*
* Returns 0 if the new certificate was accepted, -ENOKEY if we
* couldn't find a matching parent certificate in the trusted list,
- * -EKEYREJECTED if the signature check fails, and some other error if
- * there is a matching certificate but the signature check cannot be
- * performed.
+ * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
+ * unsupported crypto, or some other error if there is a matching certificate
+ * but the signature check cannot be performed.
*/
int restrict_link_by_key_or_keyring(struct key *dest_keyring,
const struct key_type *type,
@@ -249,9 +254,9 @@ int restrict_link_by_key_or_keyring(struct key *dest_keyring,
*
* Returns 0 if the new certificate was accepted, -ENOKEY if we
* couldn't find a matching parent certificate in the trusted list,
- * -EKEYREJECTED if the signature check fails, and some other error if
- * there is a matching certificate but the signature check cannot be
- * performed.
+ * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
+ * unsupported crypto, or some other error if there is a matching certificate
+ * but the signature check cannot be performed.
*/
int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
const struct key_type *type,
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (4 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 5/9] X.509: fix NULL dereference when restricting key with unsupported_sig Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 7/9] X.509: remove never-set ->unsupported_key flag Eric Biggers
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings; +Cc: linux-crypto, Michael Halcrow, Eric Biggers
From: Eric Biggers <ebiggers@google.com>
The PKCS#7 parser is guaranteed to set ->sig->hash_algo for every
SignerInfo, since pkcs7_sig_note_digest_algo() is a mandatory action in
the PKCS#7 ASN.1 grammar, and it returns an error code if an
unrecognized DigestAlgorithmIdentifier is given rather than leaving the
algorithm as NULL. Therefore, remove the unnecessary NULL check.
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/pkcs7_verify.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 97c77f66b20d..a9e03f5c52e7 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -33,9 +33,6 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
- if (!sinfo->sig->hash_algo)
- return -ENOPKG;
-
/* Allocate the hashing algorithm we're going to need and find out how
* big the hash operational data will be.
*/
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 7/9] X.509: remove never-set ->unsupported_key flag
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (5 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig Eric Biggers
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings; +Cc: linux-crypto, Michael Halcrow, Eric Biggers
From: Eric Biggers <ebiggers@google.com>
The X.509 parser is guaranteed to set cert->pub->pkey_algo, since
x509_extract_key_data() is a mandatory action in the X.509 ASN.1
grammar, and it returns an error code if an unrecognized
AlgorithmIdentifier is given rather than leaving the algorithm as NULL.
Therefore, remove the dead code which handled this algorithm being NULL.
This results in the ->unsupported_key flag never being set at all, so
remove that too.
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/pkcs7_verify.c | 3 ---
crypto/asymmetric_keys/x509_parser.h | 1 -
crypto/asymmetric_keys/x509_public_key.c | 9 ---------
3 files changed, 13 deletions(-)
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index a9e03f5c52e7..beb47fd2fca5 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -196,9 +196,6 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
return 0;
}
- if (x509->unsupported_key)
- goto unsupported_crypto_in_x509;
-
pr_debug("- issuer %s\n", x509->issuer);
sig = x509->sig;
if (sig->auth_ids[0])
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index e373e7483812..217341276ae0 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -40,7 +40,6 @@ struct x509_certificate {
bool seen; /* Infinite recursion prevention */
bool verified;
bool self_signed; /* T if self-signed (check unsupported_sig too) */
- bool unsupported_key; /* T if key uses unsupported crypto */
bool unsupported_sig; /* T if signature uses unsupported crypto */
bool blacklisted;
};
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 9338b4558cdc..514007932ec9 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -34,9 +34,6 @@ int x509_get_sig_params(struct x509_certificate *cert)
pr_devel("==>%s()\n", __func__);
- if (!cert->pub->pkey_algo)
- cert->unsupported_key = true;
-
if (!sig->pkey_algo)
cert->unsupported_sig = true;
@@ -173,12 +170,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
pr_devel("Cert Issuer: %s\n", cert->issuer);
pr_devel("Cert Subject: %s\n", cert->subject);
-
- if (cert->unsupported_key) {
- ret = -ENOPKG;
- goto error_free_cert;
- }
-
pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (6 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 7/9] X.509: remove never-set ->unsupported_key flag Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-07 1:10 ` [PATCH 9/9] X.509: self_signed implies !unsupported_sig Eric Biggers
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings; +Cc: linux-crypto, Michael Halcrow, Eric Biggers
From: Eric Biggers <ebiggers@google.com>
The X.509 parser is guaranteed to set cert->sig->pkey_algo and
cert->sig->hash_algo, since x509_note_pkey_algo() is a mandatory action
in the X.509 ASN.1 grammar, and it returns an error code if an
unrecognized AlgorithmIdentifier is given rather than leaving the
algorithms as NULL.
Therefore, remove the dead code which handled these algorithm strings
being NULL.
Note that cert->unsupported_sig can still be set if the hash algorithm
cannot be allocated from the crypto API.
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/x509_public_key.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 514007932ec9..1a7c63003bc6 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -34,15 +34,6 @@ int x509_get_sig_params(struct x509_certificate *cert)
pr_devel("==>%s()\n", __func__);
- if (!sig->pkey_algo)
- cert->unsupported_sig = true;
-
- /* We check the hash if we can - even if we can't then verify it */
- if (!sig->hash_algo) {
- cert->unsupported_sig = true;
- return 0;
- }
-
sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
if (!sig->s)
return -ENOMEM;
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 9/9] X.509: self_signed implies !unsupported_sig
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (7 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig Eric Biggers
@ 2018-02-07 1:10 ` Eric Biggers
2018-02-08 14:28 ` [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups David Howells
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Eric Biggers @ 2018-02-07 1:10 UTC (permalink / raw)
To: David Howells, keyrings; +Cc: linux-crypto, Michael Halcrow, Eric Biggers
From: Eric Biggers <ebiggers@google.com>
The self_signed flag on a certificate implies we verified its signature.
Hence, the signature cannot have been unsupported.
Remove the dead code that resulted from this oversight.
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/asymmetric_keys/pkcs7_verify.c | 18 +++---------------
crypto/asymmetric_keys/x509_parser.h | 2 +-
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index beb47fd2fca5..c23255240b93 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -206,13 +206,10 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
sig->auth_ids[1]->len, sig->auth_ids[1]->data);
if (x509->self_signed) {
- /* If there's no authority certificate specified, then
- * the certificate must be self-signed and is the root
- * of the chain. Likewise if the cert is its own
- * authority.
+ /*
+ * If the certificate is self-signed, then it is the
+ * root of the chain.
*/
- if (x509->unsupported_sig)
- goto unsupported_crypto_in_x509;
x509->signer = x509;
pr_debug("- self-signed\n");
return 0;
@@ -275,15 +272,6 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
x509 = p;
might_sleep();
}
-
-unsupported_crypto_in_x509:
- /* Just prune the certificate chain at this point if we lack some
- * crypto module to go further. Note, however, we don't want to set
- * sinfo->unsupported_crypto as the signed info block may still be
- * validatable against an X.509 cert lower in the chain that we have a
- * trusted copy of.
- */
- return 0;
}
/*
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 217341276ae0..1294cc2c855d 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -39,7 +39,7 @@ struct x509_certificate {
unsigned index;
bool seen; /* Infinite recursion prevention */
bool verified;
- bool self_signed; /* T if self-signed (check unsupported_sig too) */
+ bool self_signed; /* T if self-signed */
bool unsupported_sig; /* T if signature uses unsupported crypto */
bool blacklisted;
};
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (8 preceding siblings ...)
2018-02-07 1:10 ` [PATCH 9/9] X.509: self_signed implies !unsupported_sig Eric Biggers
@ 2018-02-08 14:28 ` David Howells
2018-02-08 15:07 ` [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported David Howells
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: David Howells @ 2018-02-08 14:28 UTC (permalink / raw)
To: Eric Biggers
Cc: dhowells, keyrings, linux-crypto, Michael Halcrow, Eric Biggers
I presume you don't have this in a git tree somewhere that I can pull?
David
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (9 preceding siblings ...)
2018-02-08 14:28 ` [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups David Howells
@ 2018-02-08 15:07 ` David Howells
2018-02-08 15:13 ` [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo David Howells
2018-02-08 15:27 ` [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig David Howells
12 siblings, 0 replies; 14+ messages in thread
From: David Howells @ 2018-02-08 15:07 UTC (permalink / raw)
To: Eric Biggers
Cc: dhowells, keyrings, linux-crypto, Michael Halcrow, Eric Biggers,
Paolo Valente, stable
Eric Biggers <ebiggers3@gmail.com> wrote:
> The X.509 parser mishandles the case where the certificate's signature's
> hash algorithm is not available in the crypto API. In this case,
> x509_get_sig_params() doesn't allocate the cert->sig->digest buffer; this
> part seems to be intentional.
Well, yes, that would be intentional: we can't digest the digestibles without
access to a hash algorithm to do so and we can't allocate a digest buffer
without knowing how big it should be.
> Fix this by making public_key_verify_signature() return -ENOPKG if the
> hash buffer has not been allocated.
Hmmm... I'm not sure that this is the right place to do this, since it
obscures a potential invalid argument within the kernel.
I'm more inclined that the users of X.509 certs should check
x509->unsupported_sig (pkcs7_verify_sig_chain() does this already partially).
David
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (10 preceding siblings ...)
2018-02-08 15:07 ` [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported David Howells
@ 2018-02-08 15:13 ` David Howells
2018-02-08 15:27 ` [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig David Howells
12 siblings, 0 replies; 14+ messages in thread
From: David Howells @ 2018-02-08 15:13 UTC (permalink / raw)
To: Eric Biggers
Cc: dhowells, keyrings, linux-crypto, Michael Halcrow, Eric Biggers
Eric Biggers <ebiggers3@gmail.com> wrote:
> The PKCS#7 parser is guaranteed to set ->sig->hash_algo for every
> SignerInfo, since pkcs7_sig_note_digest_algo() is a mandatory action in
> the PKCS#7 ASN.1 grammar, and it returns an error code if an
> unrecognized DigestAlgorithmIdentifier is given rather than leaving the
> algorithm as NULL. Therefore, remove the unnecessary NULL check.
Actually, we might be better off deferring ENOPKG generation as we might have
multiple signatures, at least one of which does have a digest algorithm that
we can handle.
David
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig
2018-02-07 1:10 [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups Eric Biggers
` (11 preceding siblings ...)
2018-02-08 15:13 ` [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo David Howells
@ 2018-02-08 15:27 ` David Howells
12 siblings, 0 replies; 14+ messages in thread
From: David Howells @ 2018-02-08 15:27 UTC (permalink / raw)
To: Eric Biggers
Cc: dhowells, keyrings, linux-crypto, Michael Halcrow, Eric Biggers
Eric Biggers <ebiggers3@gmail.com> wrote:
> The X.509 parser is guaranteed to set cert->sig->pkey_algo and
> cert->sig->hash_algo, since x509_note_pkey_algo() is a mandatory action
> in the X.509 ASN.1 grammar, and it returns an error code if an
> unrecognized AlgorithmIdentifier is given rather than leaving the
> algorithms as NULL.
I'm leaning towards ENOPKG production here being deferred so that X.509 certs
that we can't verify can still be built into the kernel or loaded from
'trusted' sources.
Let me think about this a bit more.
David
^ permalink raw reply [flat|nested] 14+ messages in thread