diff options
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_trust.c | 48 | ||||
-rw-r--r-- | crypto/asymmetric_keys/pkcs7_verify.c | 16 |
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, | |||
55 | * keys. | 55 | * keys. |
56 | */ | 56 | */ |
57 | key = x509_request_asymmetric_key(trust_keyring, x509->id); | 57 | key = x509_request_asymmetric_key(trust_keyring, x509->id); |
58 | if (!IS_ERR(key)) | 58 | if (!IS_ERR(key)) { |
59 | /* One of the X.509 certificates in the PKCS#7 message | 59 | /* One of the X.509 certificates in the PKCS#7 message |
60 | * is apparently the same as one we already trust. | 60 | * is apparently the same as one we already trust. |
61 | * Verify that the trusted variant can also validate | 61 | * Verify that the trusted variant can also validate |
62 | * the signature on the descendant. | 62 | * the signature on the descendant. |
63 | */ | 63 | */ |
64 | pr_devel("sinfo %u: Cert %u as key %x\n", | ||
65 | sinfo->index, x509->index, key_serial(key)); | ||
64 | goto matched; | 66 | goto matched; |
67 | } | ||
65 | if (key == ERR_PTR(-ENOMEM)) | 68 | if (key == ERR_PTR(-ENOMEM)) |
66 | return -ENOMEM; | 69 | return -ENOMEM; |
67 | 70 | ||
@@ -81,15 +84,34 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, | |||
81 | /* No match - see if the root certificate has a signer amongst the | 84 | /* No match - see if the root certificate has a signer amongst the |
82 | * trusted keys. | 85 | * trusted keys. |
83 | */ | 86 | */ |
84 | if (!last || !last->issuer || !last->authority) { | 87 | if (last && last->authority) { |
85 | kleave(" = -ENOKEY [no backref]"); | 88 | key = x509_request_asymmetric_key(trust_keyring, last->authority); |
86 | return -ENOKEY; | 89 | if (!IS_ERR(key)) { |
90 | x509 = last; | ||
91 | pr_devel("sinfo %u: Root cert %u signer is key %x\n", | ||
92 | sinfo->index, x509->index, key_serial(key)); | ||
93 | goto matched; | ||
94 | } | ||
95 | if (PTR_ERR(key) != -ENOKEY) | ||
96 | return PTR_ERR(key); | ||
87 | } | 97 | } |
88 | 98 | ||
89 | key = x509_request_asymmetric_key(trust_keyring, last->authority); | 99 | /* As a last resort, see if we have a trusted public key that matches |
90 | if (IS_ERR(key)) | 100 | * the signed info directly. |
91 | return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY; | 101 | */ |
92 | x509 = last; | 102 | key = x509_request_asymmetric_key(trust_keyring, |
103 | sinfo->signing_cert_id); | ||
104 | if (!IS_ERR(key)) { | ||
105 | pr_devel("sinfo %u: Direct signer is key %x\n", | ||
106 | sinfo->index, key_serial(key)); | ||
107 | x509 = NULL; | ||
108 | goto matched; | ||
109 | } | ||
110 | if (PTR_ERR(key) != -ENOKEY) | ||
111 | return PTR_ERR(key); | ||
112 | |||
113 | kleave(" = -ENOKEY [no backref]"); | ||
114 | return -ENOKEY; | ||
93 | 115 | ||
94 | matched: | 116 | matched: |
95 | ret = verify_signature(key, sig); | 117 | ret = verify_signature(key, sig); |
@@ -103,10 +125,12 @@ matched: | |||
103 | } | 125 | } |
104 | 126 | ||
105 | verified: | 127 | verified: |
106 | x509->verified = true; | 128 | if (x509) { |
107 | for (p = sinfo->signer; p != x509; p = p->signer) { | 129 | x509->verified = true; |
108 | p->verified = true; | 130 | for (p = sinfo->signer; p != x509; p = p->signer) { |
109 | p->trusted = trusted; | 131 | p->verified = true; |
132 | p->trusted = trusted; | ||
133 | } | ||
110 | } | 134 | } |
111 | sinfo->trusted = trusted; | 135 | sinfo->trusted = trusted; |
112 | kleave(" = 0"); | 136 | 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, | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n", | 157 | /* The relevant X.509 cert isn't found here, but it might be found in |
158 | sinfo->index, | 158 | * the trust keyring. |
159 | sinfo->signing_cert_id->len, sinfo->signing_cert_id->data); | 159 | */ |
160 | return -ENOKEY; | 160 | pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n", |
161 | sinfo->index, | ||
162 | sinfo->signing_cert_id->len, sinfo->signing_cert_id->data); | ||
163 | return 0; | ||
161 | } | 164 | } |
162 | 165 | ||
163 | /* | 166 | /* |
@@ -275,11 +278,14 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7, | |||
275 | if (ret < 0) | 278 | if (ret < 0) |
276 | return ret; | 279 | return ret; |
277 | 280 | ||
278 | /* Find the key for the signature */ | 281 | /* Find the key for the signature if there is one */ |
279 | ret = pkcs7_find_key(pkcs7, sinfo); | 282 | ret = pkcs7_find_key(pkcs7, sinfo); |
280 | if (ret < 0) | 283 | if (ret < 0) |
281 | return ret; | 284 | return ret; |
282 | 285 | ||
286 | if (!sinfo->signer) | ||
287 | return 0; | ||
288 | |||
283 | pr_devel("Using X.509[%u] for sig %u\n", | 289 | pr_devel("Using X.509[%u] for sig %u\n", |
284 | sinfo->signer->index, sinfo->index); | 290 | sinfo->signer->index, sinfo->index); |
285 | 291 | ||