diff options
author | David Howells <dhowells@redhat.com> | 2014-07-08 19:07:52 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-07-08 19:07:52 +0100 |
commit | 170dec90e9c3a4a1cc38a9684a1c7748f77476e8 (patch) | |
tree | 3c18795858149fe4450fbe930a40f31c05e81dbf | |
parent | 490b28ed5e09e42a3f069b8d84c0b23025cd2003 (diff) | |
download | linux-modsign-devel-pekey.tar.gz |
pefile: Load the contained key if we consider the container to be validly signeddevel-pekey
Load the key contained in the PE binary if the signature on the container can
be verified by following the chain of X.509 certificates in the PKCS#7 message
to a key that we already trust. Typically, the trusted key will be acquired
from a source outside of the kernel, such as the UEFI database.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
-rw-r--r-- | crypto/asymmetric_keys/pefile_parser.c | 14 | ||||
-rw-r--r-- | crypto/asymmetric_keys/x509_parser.h | 3 | ||||
-rw-r--r-- | crypto/asymmetric_keys/x509_public_key.c | 3 |
3 files changed, 16 insertions, 4 deletions
diff --git a/crypto/asymmetric_keys/pefile_parser.c b/crypto/asymmetric_keys/pefile_parser.c index 0a00ccfc84bfb..f17ca6b51dbd5 100644 --- a/crypto/asymmetric_keys/pefile_parser.c +++ b/crypto/asymmetric_keys/pefile_parser.c @@ -21,6 +21,7 @@ #include <keys/system_keyring.h> #include <crypto/hash.h> #include "asymmetric_keys.h" +#include "x509_parser.h" #include "pefile_parser.h" /* @@ -404,8 +405,8 @@ static int pefile_key_preparse(struct key_preparsed_payload *prep) { struct pkcs7_message *pkcs7; struct pefile_context ctx; - const void *data; - size_t datalen; + const void *saved_data, *data; + size_t saved_datalen, datalen; int ret; kenter(""); @@ -453,7 +454,14 @@ static int pefile_key_preparse(struct key_preparsed_payload *prep) if (ret < 0) goto error; - ret = -ENOANO; // Not yet complete + /* We can now try to load the key */ + saved_data = prep->data; + saved_datalen = prep->datalen; + prep->data += ctx.keylist_offset; + prep->datalen = ctx.keylist_len; + ret = x509_key_preparse(prep); + prep->data = saved_data; + prep->datalen = saved_datalen; error: pkcs7_free_message(ctx.pkcs7); diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h index 1b76f207c1f3a..812ae650b9ca3 100644 --- a/crypto/asymmetric_keys/x509_parser.h +++ b/crypto/asymmetric_keys/x509_parser.h @@ -12,6 +12,8 @@ #include <linux/time.h> #include <crypto/public_key.h> +struct key_preparsed_payload; + struct x509_certificate { struct x509_certificate *next; struct x509_certificate *signer; /* Certificate that signed this one */ @@ -51,3 +53,4 @@ extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen extern int x509_get_sig_params(struct x509_certificate *cert); extern int x509_check_signature(const struct public_key *pub, struct x509_certificate *cert); +extern int x509_key_preparse(struct key_preparsed_payload *prep); diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 382ef0d2ff2e5..26c64ec35528e 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -105,7 +105,7 @@ EXPORT_SYMBOL_GPL(x509_check_signature); /* * Attempt to parse a data blob for a key as an X509 certificate. */ -static int x509_key_preparse(struct key_preparsed_payload *prep) +int x509_key_preparse(struct key_preparsed_payload *prep) { struct x509_certificate *cert; size_t srlen, sulen; @@ -191,6 +191,7 @@ error_free_cert: x509_free_certificate(cert); return ret; } +EXPORT_SYMBOL_GPL(x509_key_preparse); static struct asymmetric_key_parser x509_key_parser = { .owner = THIS_MODULE, |