summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-04-03 16:07:25 +0100
committerDavid Howells <dhowells@redhat.com>2017-04-03 16:07:25 +0100
commitb16a0209c34610f374d0714c8eeb6772e830f397 (patch)
tree753814b25438af7a1358c0f5a17ea0ebc5bcecb2
parentf27596611714bbcd2e2459974f9713106cf0f351 (diff)
downloadlinux-crypto-b16a0209c34610f374d0714c8eeb6772e830f397.tar.gz
linux-crypto-b16a0209c34610f374d0714c8eeb6772e830f397.zip
X.509: Allow X.509 certs to be blacklisted
Allow X.509 certs to be blacklisted based on their TBSCertificate hash. This is convenient since we have to determine this anyway to be able to check the signature on an X.509 certificate. This is also what UEFI uses in its blacklist. If a certificate built into the kernel is blacklisted, something like the following might then be seen during boot: X.509: Cert 123412341234c55c1dcc601ab8e172917706aa32fb5eaf826813547fdf02dd46 is blacklisted Problem loading in-kernel X.509 certificate (-129) where the hex string shown is the blacklisted hash. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--crypto/asymmetric_keys/x509_parser.h1
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c15
2 files changed, 16 insertions, 0 deletions
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 05eef1c6..e373e748 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -42,6 +42,7 @@ struct x509_certificate {
bool self_signed; /* T if self-signed (check unsupported_sig too) */
bool unsupported_key; /* T if key uses unsupported crypto */
bool unsupported_sig; /* T if signature uses unsupported crypto */
+ bool blacklisted;
};
/*
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index fb732296..eea71dc9 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -84,6 +84,16 @@ int x509_get_sig_params(struct x509_certificate *cert)
goto error_2;
might_sleep();
ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
+ if (ret < 0)
+ goto error_2;
+
+ ret = is_hash_blacklisted(sig->digest, sig->digest_size, "tbs");
+ if (ret == -EKEYREJECTED) {
+ pr_err("Cert %*phN is blacklisted\n",
+ sig->digest_size, sig->digest);
+ cert->blacklisted = true;
+ ret = 0;
+ }
error_2:
kfree(desc);
@@ -186,6 +196,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
cert->sig->pkey_algo, cert->sig->hash_algo);
}
+ /* Don't permit addition of blacklisted keys */
+ ret = -EKEYREJECTED;
+ if (cert->blacklisted)
+ goto error_free_cert;
+
/* Propose a description */
sulen = strlen(cert->subject);
if (cert->raw_skid) {