summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c48
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c16
2 files changed, 47 insertions, 17 deletions
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 8bd474e5e706..ae47be6128c4 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -55,13 +55,16 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* keys.
*/
key = x509_request_asymmetric_key(trust_keyring, x509->id);
- if (!IS_ERR(key))
+ if (!IS_ERR(key)) {
/* One of the X.509 certificates in the PKCS#7 message
* is apparently the same as one we already trust.
* Verify that the trusted variant can also validate
* the signature on the descendant.
*/
+ pr_devel("sinfo %u: Cert %u as key %x\n",
+ sinfo->index, x509->index, key_serial(key));
goto matched;
+ }
if (key == ERR_PTR(-ENOMEM))
return -ENOMEM;
@@ -81,15 +84,34 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
/* No match - see if the root certificate has a signer amongst the
* trusted keys.
*/
- if (!last || !last->issuer || !last->authority) {
- kleave(" = -ENOKEY [no backref]");
- return -ENOKEY;
+ if (last && last->authority) {
+ key = x509_request_asymmetric_key(trust_keyring, last->authority);
+ if (!IS_ERR(key)) {
+ x509 = last;
+ pr_devel("sinfo %u: Root cert %u signer is key %x\n",
+ sinfo->index, x509->index, key_serial(key));
+ goto matched;
+ }
+ if (PTR_ERR(key) != -ENOKEY)
+ return PTR_ERR(key);
}
- key = x509_request_asymmetric_key(trust_keyring, last->authority);
- if (IS_ERR(key))
- return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY;
- x509 = last;
+ /* As a last resort, see if we have a trusted public key that matches
+ * the signed info directly.
+ */
+ key = x509_request_asymmetric_key(trust_keyring,
+ sinfo->signing_cert_id);
+ if (!IS_ERR(key)) {
+ pr_devel("sinfo %u: Direct signer is key %x\n",
+ sinfo->index, key_serial(key));
+ x509 = NULL;
+ goto matched;
+ }
+ if (PTR_ERR(key) != -ENOKEY)
+ return PTR_ERR(key);
+
+ kleave(" = -ENOKEY [no backref]");
+ return -ENOKEY;
matched:
ret = verify_signature(key, sig);
@@ -103,10 +125,12 @@ matched:
}
verified:
- x509->verified = true;
- for (p = sinfo->signer; p != x509; p = p->signer) {
- p->verified = true;
- p->trusted = trusted;
+ if (x509) {
+ x509->verified = true;
+ for (p = sinfo->signer; p != x509; p = p->signer) {
+ p->verified = true;
+ p->trusted = trusted;
+ }
}
sinfo->trusted = trusted;
kleave(" = 0");
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index bd264052f751..cd455450b069 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -154,10 +154,13 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
return 0;
}
- pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n",
- sinfo->index,
- sinfo->signing_cert_id->len, sinfo->signing_cert_id->data);
- return -ENOKEY;
+ /* The relevant X.509 cert isn't found here, but it might be found in
+ * the trust keyring.
+ */
+ pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
+ sinfo->index,
+ sinfo->signing_cert_id->len, sinfo->signing_cert_id->data);
+ return 0;
}
/*
@@ -275,11 +278,14 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
if (ret < 0)
return ret;
- /* Find the key for the signature */
+ /* Find the key for the signature if there is one */
ret = pkcs7_find_key(pkcs7, sinfo);
if (ret < 0)
return ret;
+ if (!sinfo->signer)
+ return 0;
+
pr_devel("Using X.509[%u] for sig %u\n",
sinfo->signer->index, sinfo->index);