aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-07-08 19:07:52 +0100
committerDavid Howells <dhowells@redhat.com>2014-07-08 19:07:52 +0100
commit170dec90e9c3a4a1cc38a9684a1c7748f77476e8 (patch)
tree3c18795858149fe4450fbe930a40f31c05e81dbf
parent490b28ed5e09e42a3f069b8d84c0b23025cd2003 (diff)
downloadlinux-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.c14
-rw-r--r--crypto/asymmetric_keys/x509_parser.h3
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c3
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,