[PATCH 22/23] PEFILE: Load the contained key if we consider thecontainer to be validly signed

From: David Howells
Date: Tue Oct 30 2012 - 15:22:39 EST


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@xxxxxxxxxx>
---

crypto/asymmetric_keys/pefile_parser.c | 11 ++++++++++-
crypto/asymmetric_keys/x509_parser.h | 3 +++
crypto/asymmetric_keys/x509_public_key.c | 2 +-
3 files changed, 14 insertions(+), 2 deletions(-)


diff --git a/crypto/asymmetric_keys/pefile_parser.c b/crypto/asymmetric_keys/pefile_parser.c
index 1ab1890..28be7d3 100644
--- a/crypto/asymmetric_keys/pefile_parser.c
+++ b/crypto/asymmetric_keys/pefile_parser.c
@@ -389,6 +389,8 @@ static int pefile_key_preparse(struct key_preparsed_payload *prep)
{
struct pkcs7_message *pkcs7;
struct pefile_context ctx;
+ const void *saved_data;
+ size_t saved_datalen;
int ret;

kenter("");
@@ -434,7 +436,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 5e35fba..65452c4 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;
const struct x509_certificate *signer; /* Certificate that signed this one */
@@ -47,3 +49,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 3a87512..b37f2a6 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;
struct tm now;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/