aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/asymmetric_keys/pkcs7_verify.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-09-16 12:36:13 -0400
committerDavid Howells <dhowells@redhat.com>2014-09-16 12:36:13 -0400
commit46963b774d441c833afc1535f6d84b3df2a94204 (patch)
tree335cbd163ef2581b72d462f49984a6809609a58b /crypto/asymmetric_keys/pkcs7_verify.c
parent7901c1a8effbe5f89673bfc09d6e37b8f334f1a7 (diff)
KEYS: Overhaul key identification when searching for asymmetric keys
Make use of the new match string preparsing to overhaul key identification when searching for asymmetric keys. The following changes are made: (1) Use the previously created asymmetric_key_id struct to hold the following key IDs derived from the X.509 certificate or PKCS#7 message: id: serial number + issuer skid: subjKeyId + subject authority: authKeyId + issuer (2) Replace the hex fingerprint attached to key->type_data[1] with an asymmetric_key_ids struct containing the id and the skid (if present). (3) Make the asymmetric_type match data preparse select one of two searches: (a) An iterative search for the key ID given if prefixed with "id:". The prefix is expected to be followed by a hex string giving the ID to search for. The criterion key ID is checked against all key IDs recorded on the key. (b) A direct search if the key ID is not prefixed with "id:". This will look for an exact match on the key description. (4) Make x509_request_asymmetric_key() take a key ID. This is then converted into "id:<hex>" and passed into keyring_search() where match preparsing will turn it back into a binary ID. (5) X.509 certificate verification then takes the authority key ID and looks up a key that matches it to find the public key for the certificate signature. (6) PKCS#7 certificate verification then takes the id key ID and looks up a key that matches it to find the public key for the signed information block signature. Additional changes: (1) Multiple subjKeyId and authKeyId values on an X.509 certificate cause the cert to be rejected with -EBADMSG. (2) The 'fingerprint' ID is gone. This was primarily intended to convey PGP public key fingerprints. If PGP is supported in future, this should generate a key ID that carries the fingerprint. (3) Th ca_keyid= kernel command line option is now converted to a key ID and used to match the authority key ID. Possibly this should only match the actual authKeyId part and not the issuer as well. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Vivek Goyal <vgoyal@redhat.com>
Diffstat (limited to 'crypto/asymmetric_keys/pkcs7_verify.c')
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index c62cf8006e1f..57e90fa17f2b 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -131,8 +131,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
131 struct x509_certificate *x509; 131 struct x509_certificate *x509;
132 unsigned certix = 1; 132 unsigned certix = 1;
133 133
134 kenter("%u,%u,%u", 134 kenter("%u", sinfo->index);
135 sinfo->index, sinfo->raw_serial_size, sinfo->raw_issuer_size);
136 135
137 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) { 136 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) {
138 /* I'm _assuming_ that the generator of the PKCS#7 message will 137 /* I'm _assuming_ that the generator of the PKCS#7 message will
@@ -140,21 +139,11 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
140 * PKCS#7 message - but I can't be 100% sure of that. It's 139 * PKCS#7 message - but I can't be 100% sure of that. It's
141 * possible this will need element-by-element comparison. 140 * possible this will need element-by-element comparison.
142 */ 141 */
143 if (x509->raw_serial_size != sinfo->raw_serial_size || 142 if (!asymmetric_key_id_same(x509->id, sinfo->signing_cert_id))
144 memcmp(x509->raw_serial, sinfo->raw_serial,
145 sinfo->raw_serial_size) != 0)
146 continue; 143 continue;
147 pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 144 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
148 sinfo->index, certix); 145 sinfo->index, certix);
149 146
150 if (x509->raw_issuer_size != sinfo->raw_issuer_size ||
151 memcmp(x509->raw_issuer, sinfo->raw_issuer,
152 sinfo->raw_issuer_size) != 0) {
153 pr_warn("Sig %u: X.509 subject and PKCS#7 issuer don't match\n",
154 sinfo->index);
155 continue;
156 }
157
158 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { 147 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) {
159 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 148 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
160 sinfo->index); 149 sinfo->index);
@@ -164,8 +153,10 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
164 sinfo->signer = x509; 153 sinfo->signer = x509;
165 return 0; 154 return 0;
166 } 155 }
156
167 pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n", 157 pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n",
168 sinfo->index, sinfo->raw_serial_size, sinfo->raw_serial); 158 sinfo->index,
159 sinfo->signing_cert_id->len, sinfo->signing_cert_id->data);
169 return -ENOKEY; 160 return -ENOKEY;
170} 161}
171 162
@@ -184,7 +175,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
184 p->seen = false; 175 p->seen = false;
185 176
186 for (;;) { 177 for (;;) {
187 pr_debug("verify %s: %s\n", x509->subject, x509->fingerprint); 178 pr_debug("verify %s: %*phN\n",
179 x509->subject,
180 x509->raw_serial_size, x509->raw_serial);
188 x509->seen = true; 181 x509->seen = true;
189 ret = x509_get_sig_params(x509); 182 ret = x509_get_sig_params(x509);
190 if (ret < 0) 183 if (ret < 0)
@@ -192,7 +185,8 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
192 185
193 pr_debug("- issuer %s\n", x509->issuer); 186 pr_debug("- issuer %s\n", x509->issuer);
194 if (x509->authority) 187 if (x509->authority)
195 pr_debug("- authkeyid %s\n", x509->authority); 188 pr_debug("- authkeyid %*phN\n",
189 x509->authority->len, x509->authority->data);
196 190
197 if (!x509->authority || 191 if (!x509->authority ||
198 strcmp(x509->subject, x509->issuer) == 0) { 192 strcmp(x509->subject, x509->issuer) == 0) {
@@ -218,13 +212,14 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
218 /* Look through the X.509 certificates in the PKCS#7 message's 212 /* Look through the X.509 certificates in the PKCS#7 message's
219 * list to see if the next one is there. 213 * list to see if the next one is there.
220 */ 214 */
221 pr_debug("- want %s\n", x509->authority); 215 pr_debug("- want %*phN\n",
216 x509->authority->len, x509->authority->data);
222 for (p = pkcs7->certs; p; p = p->next) { 217 for (p = pkcs7->certs; p; p = p->next) {
223 pr_debug("- cmp [%u] %s\n", p->index, p->fingerprint); 218 if (!p->skid)
224 if (p->raw_subject_size == x509->raw_issuer_size && 219 continue;
225 strcmp(p->fingerprint, x509->authority) == 0 && 220 pr_debug("- cmp [%u] %*phN\n",
226 memcmp(p->raw_subject, x509->raw_issuer, 221 p->index, p->skid->len, p->skid->data);
227 x509->raw_issuer_size) == 0) 222 if (asymmetric_key_id_same(p->skid, x509->authority))
228 goto found_issuer; 223 goto found_issuer;
229 } 224 }
230 225
@@ -233,7 +228,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
233 return 0; 228 return 0;
234 229
235 found_issuer: 230 found_issuer:
236 pr_debug("- issuer %s\n", p->subject); 231 pr_debug("- subject %s\n", p->subject);
237 if (p->seen) { 232 if (p->seen) {
238 pr_warn("Sig %u: X.509 chain contains loop\n", 233 pr_warn("Sig %u: X.509 chain contains loop\n",
239 sinfo->index); 234 sinfo->index);
@@ -304,7 +299,8 @@ int pkcs7_verify(struct pkcs7_message *pkcs7)
304 ret = x509_get_sig_params(x509); 299 ret = x509_get_sig_params(x509);
305 if (ret < 0) 300 if (ret < 0)
306 return ret; 301 return ret;
307 pr_debug("X.509[%u] %s\n", n, x509->authority); 302 pr_debug("X.509[%u] %*phN\n",
303 n, x509->authority->len, x509->authority->data);
308 } 304 }
309 305
310 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 306 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {