diff options
Diffstat (limited to 'crypto/asymmetric_keys/pkcs7_trust.c')
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_trust.c | 48 |
1 files changed, 36 insertions, 12 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"); |