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>
This commit is contained in:
@@ -131,8 +131,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
|
||||
struct x509_certificate *x509;
|
||||
unsigned certix = 1;
|
||||
|
||||
kenter("%u,%u,%u",
|
||||
sinfo->index, sinfo->raw_serial_size, sinfo->raw_issuer_size);
|
||||
kenter("%u", sinfo->index);
|
||||
|
||||
for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) {
|
||||
/* 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,
|
||||
* PKCS#7 message - but I can't be 100% sure of that. It's
|
||||
* possible this will need element-by-element comparison.
|
||||
*/
|
||||
if (x509->raw_serial_size != sinfo->raw_serial_size ||
|
||||
memcmp(x509->raw_serial, sinfo->raw_serial,
|
||||
sinfo->raw_serial_size) != 0)
|
||||
if (!asymmetric_key_id_same(x509->id, sinfo->signing_cert_id))
|
||||
continue;
|
||||
pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
|
||||
sinfo->index, certix);
|
||||
|
||||
if (x509->raw_issuer_size != sinfo->raw_issuer_size ||
|
||||
memcmp(x509->raw_issuer, sinfo->raw_issuer,
|
||||
sinfo->raw_issuer_size) != 0) {
|
||||
pr_warn("Sig %u: X.509 subject and PKCS#7 issuer don't match\n",
|
||||
sinfo->index);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) {
|
||||
pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
|
||||
sinfo->index);
|
||||
@@ -164,8 +153,10 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
|
||||
sinfo->signer = x509;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n",
|
||||
sinfo->index, sinfo->raw_serial_size, sinfo->raw_serial);
|
||||
sinfo->index,
|
||||
sinfo->signing_cert_id->len, sinfo->signing_cert_id->data);
|
||||
return -ENOKEY;
|
||||
}
|
||||
|
||||
@@ -184,7 +175,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
|
||||
p->seen = false;
|
||||
|
||||
for (;;) {
|
||||
pr_debug("verify %s: %s\n", x509->subject, x509->fingerprint);
|
||||
pr_debug("verify %s: %*phN\n",
|
||||
x509->subject,
|
||||
x509->raw_serial_size, x509->raw_serial);
|
||||
x509->seen = true;
|
||||
ret = x509_get_sig_params(x509);
|
||||
if (ret < 0)
|
||||
@@ -192,7 +185,8 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
|
||||
|
||||
pr_debug("- issuer %s\n", x509->issuer);
|
||||
if (x509->authority)
|
||||
pr_debug("- authkeyid %s\n", x509->authority);
|
||||
pr_debug("- authkeyid %*phN\n",
|
||||
x509->authority->len, x509->authority->data);
|
||||
|
||||
if (!x509->authority ||
|
||||
strcmp(x509->subject, x509->issuer) == 0) {
|
||||
@@ -218,13 +212,14 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
|
||||
/* Look through the X.509 certificates in the PKCS#7 message's
|
||||
* list to see if the next one is there.
|
||||
*/
|
||||
pr_debug("- want %s\n", x509->authority);
|
||||
pr_debug("- want %*phN\n",
|
||||
x509->authority->len, x509->authority->data);
|
||||
for (p = pkcs7->certs; p; p = p->next) {
|
||||
pr_debug("- cmp [%u] %s\n", p->index, p->fingerprint);
|
||||
if (p->raw_subject_size == x509->raw_issuer_size &&
|
||||
strcmp(p->fingerprint, x509->authority) == 0 &&
|
||||
memcmp(p->raw_subject, x509->raw_issuer,
|
||||
x509->raw_issuer_size) == 0)
|
||||
if (!p->skid)
|
||||
continue;
|
||||
pr_debug("- cmp [%u] %*phN\n",
|
||||
p->index, p->skid->len, p->skid->data);
|
||||
if (asymmetric_key_id_same(p->skid, x509->authority))
|
||||
goto found_issuer;
|
||||
}
|
||||
|
||||
@@ -233,7 +228,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
|
||||
return 0;
|
||||
|
||||
found_issuer:
|
||||
pr_debug("- issuer %s\n", p->subject);
|
||||
pr_debug("- subject %s\n", p->subject);
|
||||
if (p->seen) {
|
||||
pr_warn("Sig %u: X.509 chain contains loop\n",
|
||||
sinfo->index);
|
||||
@@ -304,7 +299,8 @@ int pkcs7_verify(struct pkcs7_message *pkcs7)
|
||||
ret = x509_get_sig_params(x509);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pr_debug("X.509[%u] %s\n", n, x509->authority);
|
||||
pr_debug("X.509[%u] %*phN\n",
|
||||
n, x509->authority->len, x509->authority->data);
|
||||
}
|
||||
|
||||
for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
|
||||
|
Reference in New Issue
Block a user