All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] scripts/sign-file.c: Add support for signing with a raw signature
@ 2016-01-30  9:18 Juerg Haefliger
  2016-02-03 20:34 ` David Howells
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Juerg Haefliger @ 2016-01-30  9:18 UTC (permalink / raw)
  To: linux-kernel, keyrings; +Cc: dhowells, dwmw2

This commit adds support for signing a kernel module with a raw
detached PKCS#7 signature/message.

The signature is not converted and is simply appended to the module so
it needs to be in the right format. Using openssl, a valid signature can
be generated like this:
  $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
    <key> -signer <x509> -outform der -out <raw sig>

The resulting raw signature from the above command is (more or less)
identical to the raw signature that sign-file itself can produce like
this:
  $ scripts/sign-file -d <hash algo> <key> <x509> <module>

Signed-off-by: Juerg Haefliger <juerg.haefliger@hpe.com>
---
 scripts/sign-file.c | 213 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 135 insertions(+), 78 deletions(-)

diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 250a7a6..d23fe70 100755
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -2,9 +2,11 @@
  *
  * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
  * Copyright © 2015      Intel Corporation.
+ * Copyright © 2016      Hewlett Packard Enterprise Development Company, L.P.
  *
  * Authors: David Howells <dhowells@redhat.com>
  *          David Woodhouse <dwmw2@infradead.org>
+ *          Juerg Haefliger <juerg.haefliger@hpe.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -67,6 +69,8 @@ void format(void)
 {
 	fprintf(stderr,
 		"Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]\n");
+	fprintf(stderr,
+		"       scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]\n");
 	exit(2);
 }
 
@@ -126,26 +130,84 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
 	return pwlen;
 }
 
+static EVP_PKEY *read_private_key(char *private_key_name)
+{
+	EVP_PKEY *private_key;
+
+	if (!strncmp(private_key_name, "pkcs11:", 7)) {
+		ENGINE *e;
+
+		ENGINE_load_builtin_engines();
+		drain_openssl_errors();
+		e = ENGINE_by_id("pkcs11");
+		ERR(!e, "Load PKCS#11 ENGINE");
+		if (ENGINE_init(e))
+			drain_openssl_errors();
+		else
+			ERR(1, "ENGINE_init");
+		if (key_pass)
+			ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0),
+			    "Set PKCS#11 PIN");
+		private_key = ENGINE_load_private_key(e, private_key_name,
+						      NULL, NULL);
+		ERR(!private_key, "%s", private_key_name);
+	} else {
+		BIO *b;
+
+		b = BIO_new_file(private_key_name, "rb");
+		ERR(!b, "%s", private_key_name);
+		private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb,
+						      NULL);
+		ERR(!private_key, "%s", private_key_name);
+		BIO_free(b);
+	}
+
+	return private_key;
+}
+
+static X509 *read_x509(char *x509_name)
+{
+	X509 *x509;
+	BIO *b;
+
+	b = BIO_new_file(x509_name, "rb");
+	ERR(!b, "%s", x509_name);
+	x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */
+	if (!x509) {
+		ERR(BIO_reset(b) != 1, "%s", x509_name);
+		x509 = PEM_read_bio_X509(b, NULL, NULL,
+					 NULL); /* PEM encoded X.509 */
+		if (x509)
+			drain_openssl_errors();
+	}
+	BIO_free(b);
+	ERR(!x509, "%s", x509_name);
+
+	return x509;
+}
+
 int main(int argc, char **argv)
 {
 	struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 };
 	char *hash_algo = NULL;
-	char *private_key_name, *x509_name, *module_name, *dest_name;
+	char *private_key_name = NULL, *raw_sig_name = NULL;
+	char *x509_name, *module_name, *dest_name;
 	bool save_sig = false, replace_orig;
 	bool sign_only = false;
+	bool raw_sig = false;
 	unsigned char buf[4096];
 	unsigned long module_size, sig_size;
 	unsigned int use_signed_attrs;
 	const EVP_MD *digest_algo;
 	EVP_PKEY *private_key;
 #ifndef USE_PKCS7
-	CMS_ContentInfo *cms;
+	CMS_ContentInfo *cms = NULL;
 	unsigned int use_keyid = 0;
 #else
-	PKCS7 *pkcs7;
+	PKCS7 *pkcs7 = NULL;
 #endif
 	X509 *x509;
-	BIO *b, *bd = NULL, *bm;
+	BIO *bd, *bm;
 	int opt, n;
 	OpenSSL_add_all_algorithms();
 	ERR_load_crypto_strings();
@@ -160,8 +222,9 @@ int main(int argc, char **argv)
 #endif
 
 	do {
-		opt = getopt(argc, argv, "dpk");
+		opt = getopt(argc, argv, "sdpk");
 		switch (opt) {
+		case 's': raw_sig = true; break;
 		case 'p': save_sig = true; break;
 		case 'd': sign_only = true; save_sig = true; break;
 #ifndef USE_PKCS7
@@ -177,8 +240,13 @@ int main(int argc, char **argv)
 	if (argc < 4 || argc > 5)
 		format();
 
-	hash_algo = argv[0];
-	private_key_name = argv[1];
+	if (raw_sig) {
+		raw_sig_name = argv[0];
+		hash_algo = argv[1];
+	} else {
+		hash_algo = argv[0];
+		private_key_name = argv[1];
+	}
 	x509_name = argv[2];
 	module_name = argv[3];
 	if (argc == 5) {
@@ -198,84 +266,50 @@ int main(int argc, char **argv)
 	}
 #endif
 
-	/* Read the private key and the X.509 cert the PKCS#7 message
-	 * will point to.
-	 */
-	if (!strncmp(private_key_name, "pkcs11:", 7)) {
-		ENGINE *e;
-
-		ENGINE_load_builtin_engines();
-		drain_openssl_errors();
-		e = ENGINE_by_id("pkcs11");
-		ERR(!e, "Load PKCS#11 ENGINE");
-		if (ENGINE_init(e))
-			drain_openssl_errors();
-		else
-			ERR(1, "ENGINE_init");
-		if (key_pass)
-			ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
-		private_key = ENGINE_load_private_key(e, private_key_name, NULL,
-						      NULL);
-		ERR(!private_key, "%s", private_key_name);
-	} else {
-		b = BIO_new_file(private_key_name, "rb");
-		ERR(!b, "%s", private_key_name);
-		private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL);
-		ERR(!private_key, "%s", private_key_name);
-		BIO_free(b);
-	}
-
-	b = BIO_new_file(x509_name, "rb");
-	ERR(!b, "%s", x509_name);
-	x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */
-	if (!x509) {
-		ERR(BIO_reset(b) != 1, "%s", x509_name);
-		x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); /* PEM encoded X.509 */
-		if (x509)
-			drain_openssl_errors();
-	}
-	BIO_free(b);
-	ERR(!x509, "%s", x509_name);
+	/* Open the module file */
+	bm = BIO_new_file(module_name, "rb");
+	ERR(!bm, "%s", module_name);
 
-	/* Open the destination file now so that we can shovel the module data
-	 * across as we read it.
-	 */
-	if (!sign_only) {
-		bd = BIO_new_file(dest_name, "wb");
-		ERR(!bd, "%s", dest_name);
-	}
+	if (!raw_sig) {
 
-	/* Digest the module data. */
-	OpenSSL_add_all_digests();
-	display_openssl_errors(__LINE__);
-	digest_algo = EVP_get_digestbyname(hash_algo);
-	ERR(!digest_algo, "EVP_get_digestbyname");
+		/* Read the private key and the X.509 cert the PKCS#7 message
+		 * will point to.
+		 */
+		private_key = read_private_key(private_key_name);
+		x509 = read_x509(x509_name);
 
-	bm = BIO_new_file(module_name, "rb");
-	ERR(!bm, "%s", module_name);
+		/* Digest the module data. */
+		OpenSSL_add_all_digests();
+		display_openssl_errors(__LINE__);
+		digest_algo = EVP_get_digestbyname(hash_algo);
+		ERR(!digest_algo, "EVP_get_digestbyname");
 
 #ifndef USE_PKCS7
-	/* Load the signature message from the digest buffer. */
-	cms = CMS_sign(NULL, NULL, NULL, NULL,
-		       CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_DETACHED | CMS_STREAM);
-	ERR(!cms, "CMS_sign");
-
-	ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
-			     CMS_NOCERTS | CMS_BINARY | CMS_NOSMIMECAP |
-			     use_keyid | use_signed_attrs),
-	    "CMS_add1_signer");
-	ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0,
-	    "CMS_final");
+		/* Load the signature message from the digest buffer. */
+		cms = CMS_sign(NULL, NULL, NULL, NULL,
+			       CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
+			       CMS_DETACHED | CMS_STREAM);
+		ERR(!cms, "CMS_sign");
+
+		ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
+				     CMS_NOCERTS | CMS_BINARY |
+				     CMS_NOSMIMECAP | use_keyid |
+				     use_signed_attrs),
+		    "CMS_add1_signer");
+		ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0,
+		    "CMS_final");
 
 #else
-	pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
-			   PKCS7_NOCERTS | PKCS7_BINARY |
-			   PKCS7_DETACHED | use_signed_attrs);
-	ERR(!pkcs7, "PKCS7_sign");
+		pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
+				   PKCS7_NOCERTS | PKCS7_BINARY |
+				   PKCS7_DETACHED | use_signed_attrs);
+		ERR(!pkcs7, "PKCS7_sign");
 #endif
+	}
 
-	if (save_sig) {
+	if (!raw_sig && save_sig) {
 		char *sig_file_name;
+		BIO *b;
 
 		ERR(asprintf(&sig_file_name, "%s.p7s", module_name) < 0,
 		    "asprintf");
@@ -291,8 +325,16 @@ int main(int argc, char **argv)
 		BIO_free(b);
 	}
 
-	if (sign_only)
+	if (!raw_sig && sign_only) {
+		BIO_free(bm);
 		return 0;
+	}
+
+	/* Open the destination file now so that we can shovel the module data
+	 * across as we read it.
+	 */
+	bd = BIO_new_file(dest_name, "wb");
+	ERR(!bd, "%s", dest_name);
 
 	/* Append the marker and the PKCS#7 message to the destination file */
 	ERR(BIO_reset(bm) < 0, "%s", module_name);
@@ -300,14 +342,29 @@ int main(int argc, char **argv)
 	       n > 0) {
 		ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
 	}
+	BIO_free(bm);
 	ERR(n < 0, "%s", module_name);
 	module_size = BIO_number_written(bd);
 
+	if (!raw_sig) {
 #ifndef USE_PKCS7
-	ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name);
+		ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name);
 #else
-	ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name);
+		ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name);
 #endif
+	} else {
+		BIO *b;
+
+		/* Read the raw signature file and write the data to the
+		 * destination file
+		 */
+		b = BIO_new_file(raw_sig_name, "rb");
+		ERR(!b, "%s", raw_sig_name);
+		while ((n = BIO_read(b, buf, sizeof(buf))), n > 0)
+			ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
+		BIO_free(b);
+	}
+
 	sig_size = BIO_number_written(bd) - module_size;
 	sig_info.sig_len = htonl(sig_size);
 	ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] scripts/sign-file.c: Add support for signing with a raw signature
  2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
@ 2016-02-03 20:34 ` David Howells
  2016-02-04  9:07   ` Juerg Haefliger
  2016-02-04 10:42   ` David Howells
  2016-02-03 20:45 ` David Howells
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: David Howells @ 2016-02-03 20:34 UTC (permalink / raw)
  To: Juerg Haefliger; +Cc: dhowells, linux-kernel, keyrings, dwmw2

Juerg Haefliger <juerg.haefliger@hpe.com> wrote:

> +static EVP_PKEY *read_private_key(char *private_key_name)

const char * please.

> +static X509 *read_x509(char *x509_name)

And here.

David

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] scripts/sign-file.c: Add support for signing with a raw signature
  2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
  2016-02-03 20:34 ` David Howells
@ 2016-02-03 20:45 ` David Howells
  2016-02-04 11:09 ` [PATCH v2] " Juerg Haefliger
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: David Howells @ 2016-02-03 20:45 UTC (permalink / raw)
  To: Juerg Haefliger; +Cc: dhowells, linux-kernel, keyrings, dwmw2

In the patched file, I see:

	if (!raw_sig) {
	...
	}

	if (!raw_sig && save_sig) {
	...
	}

	if (!raw_sig && sign_only) {
	...
	}


Can you just merge the three into one if-statement that is conditional on
!raw_sig with conditional bits inside?  It might be worth moving the contents
out to its own function, but it deals with sufficient of main's context that
it might not actually be worthwhile.

David

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] scripts/sign-file.c: Add support for signing with a raw signature
  2016-02-03 20:34 ` David Howells
@ 2016-02-04  9:07   ` Juerg Haefliger
  2016-02-04 10:42   ` David Howells
  1 sibling, 0 replies; 13+ messages in thread
From: Juerg Haefliger @ 2016-02-04  9:07 UTC (permalink / raw)
  To: David Howells; +Cc: linux-kernel, keyrings, dwmw2

On 02/03/2016 09:34 PM, David Howells wrote:
> Juerg Haefliger <juerg.haefliger@hpe.com> wrote:
> 
>> +static EVP_PKEY *read_private_key(char *private_key_name)
> 
> const char * please.
> 
>> +static X509 *read_x509(char *x509_name)
> 
> And here.

Why? These functions do return pointers to EVP_PKEY and X509 structs.

...Juerg


> David
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] scripts/sign-file.c: Add support for signing with a raw signature
  2016-02-03 20:34 ` David Howells
  2016-02-04  9:07   ` Juerg Haefliger
@ 2016-02-04 10:42   ` David Howells
  1 sibling, 0 replies; 13+ messages in thread
From: David Howells @ 2016-02-04 10:42 UTC (permalink / raw)
  To: Juerg Haefliger; +Cc: dhowells, linux-kernel, keyrings, dwmw2

Juerg Haefliger <juerg.haefliger@hpe.com> wrote:

> >> +static EVP_PKEY *read_private_key(char *private_key_name)
> > 
> > const char * please.
> > 
> >> +static X509 *read_x509(char *x509_name)
> > 
> > And here.
> 
> Why? These functions do return pointers to EVP_PKEY and X509 structs.

I meant the arguments not the return type.

David

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
  2016-02-03 20:34 ` David Howells
  2016-02-03 20:45 ` David Howells
@ 2016-02-04 11:09 ` Juerg Haefliger
  2016-02-09 16:44 ` David Howells
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Juerg Haefliger @ 2016-02-04 11:09 UTC (permalink / raw)
  To: linux-kernel, keyrings; +Cc: dhowells, dwmw2, juerg.haefliger

This patch adds support for signing a kernel module with a raw
detached PKCS#7 signature/message.

The signature is not converted and is simply appended to the module so
it needs to be in the right format. Using openssl, a valid signature can
be generated like this:
  $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
    <key> -signer <x509> -outform der -out <raw sig>

The resulting raw signature from the above command is (more or less)
identical to the raw signature that sign-file itself can produce like
this:
  $ scripts/sign-file -d <hash algo> <key> <x509> <module>

Signed-off-by: Juerg Haefliger <juerg.haefliger@hpe.com>
---
 scripts/sign-file.c | 235 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 146 insertions(+), 89 deletions(-)

diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 250a7a6..c78ddd7 100755
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -2,9 +2,11 @@
  *
  * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
  * Copyright © 2015      Intel Corporation.
+ * Copyright © 2016      Hewlett Packard Enterprise Development LP
  *
  * Authors: David Howells <dhowells@redhat.com>
  *          David Woodhouse <dwmw2@infradead.org>
+ *          Juerg Haefliger <juerg.haefliger@hpe.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -67,6 +69,8 @@ void format(void)
 {
 	fprintf(stderr,
 		"Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]\n");
+	fprintf(stderr,
+		"       scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]\n");
 	exit(2);
 }
 
@@ -126,26 +130,84 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
 	return pwlen;
 }
 
+static EVP_PKEY *read_private_key(const char *private_key_name)
+{
+	EVP_PKEY *private_key;
+
+	if (!strncmp(private_key_name, "pkcs11:", 7)) {
+		ENGINE *e;
+
+		ENGINE_load_builtin_engines();
+		drain_openssl_errors();
+		e = ENGINE_by_id("pkcs11");
+		ERR(!e, "Load PKCS#11 ENGINE");
+		if (ENGINE_init(e))
+			drain_openssl_errors();
+		else
+			ERR(1, "ENGINE_init");
+		if (key_pass)
+			ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0),
+			    "Set PKCS#11 PIN");
+		private_key = ENGINE_load_private_key(e, private_key_name,
+						      NULL, NULL);
+		ERR(!private_key, "%s", private_key_name);
+	} else {
+		BIO *b;
+
+		b = BIO_new_file(private_key_name, "rb");
+		ERR(!b, "%s", private_key_name);
+		private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb,
+						      NULL);
+		ERR(!private_key, "%s", private_key_name);
+		BIO_free(b);
+	}
+
+	return private_key;
+}
+
+static X509 *read_x509(const char *x509_name)
+{
+	X509 *x509;
+	BIO *b;
+
+	b = BIO_new_file(x509_name, "rb");
+	ERR(!b, "%s", x509_name);
+	x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */
+	if (!x509) {
+		ERR(BIO_reset(b) != 1, "%s", x509_name);
+		x509 = PEM_read_bio_X509(b, NULL, NULL,
+					 NULL); /* PEM encoded X.509 */
+		if (x509)
+			drain_openssl_errors();
+	}
+	BIO_free(b);
+	ERR(!x509, "%s", x509_name);
+
+	return x509;
+}
+
 int main(int argc, char **argv)
 {
 	struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 };
 	char *hash_algo = NULL;
-	char *private_key_name, *x509_name, *module_name, *dest_name;
+	char *private_key_name = NULL, *raw_sig_name = NULL;
+	char *x509_name, *module_name, *dest_name;
 	bool save_sig = false, replace_orig;
 	bool sign_only = false;
+	bool raw_sig = false;
 	unsigned char buf[4096];
 	unsigned long module_size, sig_size;
 	unsigned int use_signed_attrs;
 	const EVP_MD *digest_algo;
 	EVP_PKEY *private_key;
 #ifndef USE_PKCS7
-	CMS_ContentInfo *cms;
+	CMS_ContentInfo *cms = NULL;
 	unsigned int use_keyid = 0;
 #else
-	PKCS7 *pkcs7;
+	PKCS7 *pkcs7 = NULL;
 #endif
 	X509 *x509;
-	BIO *b, *bd = NULL, *bm;
+	BIO *bd, *bm;
 	int opt, n;
 	OpenSSL_add_all_algorithms();
 	ERR_load_crypto_strings();
@@ -160,8 +222,9 @@ int main(int argc, char **argv)
 #endif
 
 	do {
-		opt = getopt(argc, argv, "dpk");
+		opt = getopt(argc, argv, "sdpk");
 		switch (opt) {
+		case 's': raw_sig = true; break;
 		case 'p': save_sig = true; break;
 		case 'd': sign_only = true; save_sig = true; break;
 #ifndef USE_PKCS7
@@ -177,8 +240,13 @@ int main(int argc, char **argv)
 	if (argc < 4 || argc > 5)
 		format();
 
-	hash_algo = argv[0];
-	private_key_name = argv[1];
+	if (raw_sig) {
+		raw_sig_name = argv[0];
+		hash_algo = argv[1];
+	} else {
+		hash_algo = argv[0];
+		private_key_name = argv[1];
+	}
 	x509_name = argv[2];
 	module_name = argv[3];
 	if (argc == 5) {
@@ -198,101 +266,75 @@ int main(int argc, char **argv)
 	}
 #endif
 
-	/* Read the private key and the X.509 cert the PKCS#7 message
-	 * will point to.
-	 */
-	if (!strncmp(private_key_name, "pkcs11:", 7)) {
-		ENGINE *e;
-
-		ENGINE_load_builtin_engines();
-		drain_openssl_errors();
-		e = ENGINE_by_id("pkcs11");
-		ERR(!e, "Load PKCS#11 ENGINE");
-		if (ENGINE_init(e))
-			drain_openssl_errors();
-		else
-			ERR(1, "ENGINE_init");
-		if (key_pass)
-			ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
-		private_key = ENGINE_load_private_key(e, private_key_name, NULL,
-						      NULL);
-		ERR(!private_key, "%s", private_key_name);
-	} else {
-		b = BIO_new_file(private_key_name, "rb");
-		ERR(!b, "%s", private_key_name);
-		private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL);
-		ERR(!private_key, "%s", private_key_name);
-		BIO_free(b);
-	}
-
-	b = BIO_new_file(x509_name, "rb");
-	ERR(!b, "%s", x509_name);
-	x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */
-	if (!x509) {
-		ERR(BIO_reset(b) != 1, "%s", x509_name);
-		x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); /* PEM encoded X.509 */
-		if (x509)
-			drain_openssl_errors();
-	}
-	BIO_free(b);
-	ERR(!x509, "%s", x509_name);
+	/* Open the module file */
+	bm = BIO_new_file(module_name, "rb");
+	ERR(!bm, "%s", module_name);
 
-	/* Open the destination file now so that we can shovel the module data
-	 * across as we read it.
-	 */
-	if (!sign_only) {
-		bd = BIO_new_file(dest_name, "wb");
-		ERR(!bd, "%s", dest_name);
-	}
+	if (!raw_sig) {
 
-	/* Digest the module data. */
-	OpenSSL_add_all_digests();
-	display_openssl_errors(__LINE__);
-	digest_algo = EVP_get_digestbyname(hash_algo);
-	ERR(!digest_algo, "EVP_get_digestbyname");
+		/* Read the private key and the X.509 cert the PKCS#7 message
+		 * will point to.
+		 */
+		private_key = read_private_key(private_key_name);
+		x509 = read_x509(x509_name);
 
-	bm = BIO_new_file(module_name, "rb");
-	ERR(!bm, "%s", module_name);
+		/* Digest the module data. */
+		OpenSSL_add_all_digests();
+		display_openssl_errors(__LINE__);
+		digest_algo = EVP_get_digestbyname(hash_algo);
+		ERR(!digest_algo, "EVP_get_digestbyname");
 
 #ifndef USE_PKCS7
-	/* Load the signature message from the digest buffer. */
-	cms = CMS_sign(NULL, NULL, NULL, NULL,
-		       CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_DETACHED | CMS_STREAM);
-	ERR(!cms, "CMS_sign");
-
-	ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
-			     CMS_NOCERTS | CMS_BINARY | CMS_NOSMIMECAP |
-			     use_keyid | use_signed_attrs),
-	    "CMS_add1_signer");
-	ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0,
-	    "CMS_final");
+		/* Load the signature message from the digest buffer. */
+		cms = CMS_sign(NULL, NULL, NULL, NULL,
+			       CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
+			       CMS_DETACHED | CMS_STREAM);
+		ERR(!cms, "CMS_sign");
+
+		ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
+				     CMS_NOCERTS | CMS_BINARY |
+				     CMS_NOSMIMECAP | use_keyid |
+				     use_signed_attrs),
+		    "CMS_add1_signer");
+		ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0,
+		    "CMS_final");
 
 #else
-	pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
-			   PKCS7_NOCERTS | PKCS7_BINARY |
-			   PKCS7_DETACHED | use_signed_attrs);
-	ERR(!pkcs7, "PKCS7_sign");
+		pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
+				   PKCS7_NOCERTS | PKCS7_BINARY |
+				   PKCS7_DETACHED | use_signed_attrs);
+		ERR(!pkcs7, "PKCS7_sign");
 #endif
 
-	if (save_sig) {
-		char *sig_file_name;
+		if (save_sig) {
+			char *sig_file_name;
+			BIO *b;
 
-		ERR(asprintf(&sig_file_name, "%s.p7s", module_name) < 0,
-		    "asprintf");
-		b = BIO_new_file(sig_file_name, "wb");
-		ERR(!b, "%s", sig_file_name);
+			ERR(asprintf(&sig_file_name, "%s.p7s", module_name) < 0,
+			    "asprintf");
+			b = BIO_new_file(sig_file_name, "wb");
+			ERR(!b, "%s", sig_file_name);
 #ifndef USE_PKCS7
-		ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0,
-		    "%s", sig_file_name);
+			ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0,
+			    "%s", sig_file_name);
 #else
-		ERR(i2d_PKCS7_bio(b, pkcs7) < 0,
-			"%s", sig_file_name);
+			ERR(i2d_PKCS7_bio(b, pkcs7) < 0,
+			    "%s", sig_file_name);
 #endif
-		BIO_free(b);
+			BIO_free(b);
+		}
+
+		if (sign_only) {
+			BIO_free(bm);
+			return 0;
+		}
 	}
 
-	if (sign_only)
-		return 0;
+	/* Open the destination file now so that we can shovel the module data
+	 * across as we read it.
+	 */
+	bd = BIO_new_file(dest_name, "wb");
+	ERR(!bd, "%s", dest_name);
 
 	/* Append the marker and the PKCS#7 message to the destination file */
 	ERR(BIO_reset(bm) < 0, "%s", module_name);
@@ -300,14 +342,29 @@ int main(int argc, char **argv)
 	       n > 0) {
 		ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
 	}
+	BIO_free(bm);
 	ERR(n < 0, "%s", module_name);
 	module_size = BIO_number_written(bd);
 
+	if (!raw_sig) {
 #ifndef USE_PKCS7
-	ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name);
+		ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name);
 #else
-	ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name);
+		ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name);
 #endif
+	} else {
+		BIO *b;
+
+		/* Read the raw signature file and write the data to the
+		 * destination file
+		 */
+		b = BIO_new_file(raw_sig_name, "rb");
+		ERR(!b, "%s", raw_sig_name);
+		while ((n = BIO_read(b, buf, sizeof(buf))), n > 0)
+			ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
+		BIO_free(b);
+	}
+
 	sig_size = BIO_number_written(bd) - module_size;
 	sig_info.sig_len = htonl(sig_size);
 	ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
                   ` (2 preceding siblings ...)
  2016-02-04 11:09 ` [PATCH v2] " Juerg Haefliger
@ 2016-02-09 16:44 ` David Howells
  2016-02-10 10:12 ` David Howells
  2016-02-18 17:23 ` David Howells
  5 siblings, 0 replies; 13+ messages in thread
From: David Howells @ 2016-02-09 16:44 UTC (permalink / raw)
  To: Juerg Haefliger; +Cc: dhowells, linux-kernel, keyrings, dwmw2

Juerg Haefliger <juerg.haefliger@hpe.com> wrote:

> This patch adds support for signing a kernel module with a raw
> detached PKCS#7 signature/message.
> 
> The signature is not converted and is simply appended to the module so
> it needs to be in the right format. Using openssl, a valid signature can
> be generated like this:
>   $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
>     <key> -signer <x509> -outform der -out <raw sig>
> 
> The resulting raw signature from the above command is (more or less)
> identical to the raw signature that sign-file itself can produce like
> this:
>   $ scripts/sign-file -d <hash algo> <key> <x509> <module>
> 
> Signed-off-by: Juerg Haefliger <juerg.haefliger@hpe.com>

Looks okay.  I'll apply it unless David Woodhouse has an objection.

David

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
                   ` (3 preceding siblings ...)
  2016-02-09 16:44 ` David Howells
@ 2016-02-10 10:12 ` David Howells
  2016-02-10 10:25   ` David Woodhouse
                     ` (2 more replies)
  2016-02-18 17:23 ` David Howells
  5 siblings, 3 replies; 13+ messages in thread
From: David Howells @ 2016-02-10 10:12 UTC (permalink / raw)
  To: Juerg Haefliger; +Cc: dhowells, linux-kernel, keyrings, dwmw2

Juerg Haefliger <juerg.haefliger@hpe.com> wrote:

> This patch adds support for signing a kernel module with a raw
> detached PKCS#7 signature/message.
> 
> The signature is not converted and is simply appended to the module so
> it needs to be in the right format. Using openssl, a valid signature can
> be generated like this:
>   $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
>     <key> -signer <x509> -outform der -out <raw sig>
> 
> The resulting raw signature from the above command is (more or less)
> identical to the raw signature that sign-file itself can produce like
> this:
>   $ scripts/sign-file -d <hash algo> <key> <x509> <module>

What's the usage case for this?  Can it be done instead with openssl PKCS#11?

David

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-02-10 10:12 ` David Howells
@ 2016-02-10 10:25   ` David Woodhouse
  2016-02-10 13:07   ` Juerg Haefliger
  2016-02-10 13:24   ` Juerg Haefliger
  2 siblings, 0 replies; 13+ messages in thread
From: David Woodhouse @ 2016-02-10 10:25 UTC (permalink / raw)
  To: David Howells, Juerg Haefliger; +Cc: linux-kernel, keyrings

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: Type: text/plain, Size: 1882 bytes --]

On Wed, 2016-02-10 at 10:12 +0000, David Howells wrote:
> Juerg Haefliger <juerg.haefliger@hpe.com> wrote:
> 
> > This patch adds support for signing a kernel module with a raw
> > detached PKCS#7 signature/message.
> > 
> > The signature is not converted and is simply appended to the module so
> > it needs to be in the right format. Using openssl, a valid signature can
> > be generated like this:
> >   $ openssl smime -sign -nocerts -noattr -binary -in  -inkey \
> >      -signer  -outform der -out 
> > 
> > The resulting raw signature from the above command is (more or less)
> > identical to the raw signature that sign-file itself can produce like
> > this:
> >   $ scripts/sign-file -d    
> 
> What's the usage case for this?  Can it be done instead with openssl PKCS#11?

Ah, right. That's what it was doing. Yeah, I have a vague recollection
of looking at this as we were doing the conversion to C, and concluding
that it was indeed a hackish workaround for the fact that the existing
setup didn't allow using external crypto devices via PKCS#11.

If you want to generate your signatures using external hardware, then
using sign-file with a PKCS#11 key definitely seems like the way to do
it. I believe I even tested it with the p11-kit remote mechanism, doing
the signing on a remote system over SSH.

There doesn't seem to be much of an excuse for doing otherwise on
security grounds — if this is the build system and you're going to
trust the modules which were built here, then copying them to separate
system and producing the signatures there is not really any different
to just allowing this system to invoke the signature-creation for
itself via PKCS#11, is it?

-- 
-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation


[-- Attachment #3: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5691 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-02-10 10:12 ` David Howells
  2016-02-10 10:25   ` David Woodhouse
@ 2016-02-10 13:07   ` Juerg Haefliger
  2016-02-10 13:24   ` Juerg Haefliger
  2 siblings, 0 replies; 13+ messages in thread
From: Juerg Haefliger @ 2016-02-10 13:07 UTC (permalink / raw)
  To: David Howells; +Cc: linux-kernel, keyrings, dwmw2

On 02/10/2016 11:12 AM, David Howells wrote:
> Juerg Haefliger <juerg.haefliger@hpe.com> wrote:
> 
>> This patch adds support for signing a kernel module with a raw
>> detached PKCS#7 signature/message.
>>
>> The signature is not converted and is simply appended to the module so
>> it needs to be in the right format. Using openssl, a valid signature can
>> be generated like this:
>>   $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
>>     <key> -signer <x509> -outform der -out <raw sig>
>>
>> The resulting raw signature from the above command is (more or less)
>> identical to the raw signature that sign-file itself can produce like
>> this:
>>   $ scripts/sign-file -d <hash algo> <key> <x509> <module>
> 
> What's the usage case for this?  Can it be done instead with openssl PKCS#11?

Our internal signing service doesn't support PKCS#11. I have to submit the blobs
and get detached PKCS#7 messages back. I don't claim I fully understand all the
different signing mechanisms but everything worked just fine until support for
signing with a detached signature was removed. IMO that's a regression, which
I'm trying to fix with this patch.

...Juerg



> David
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-02-10 10:12 ` David Howells
  2016-02-10 10:25   ` David Woodhouse
  2016-02-10 13:07   ` Juerg Haefliger
@ 2016-02-10 13:24   ` Juerg Haefliger
  2016-02-18  9:26     ` Juerg Haefliger
  2 siblings, 1 reply; 13+ messages in thread
From: Juerg Haefliger @ 2016-02-10 13:24 UTC (permalink / raw)
  To: David Howells; +Cc: linux-kernel, keyrings, dwmw2

On 02/10/2016 11:12 AM, David Howells wrote:
> Juerg Haefliger <juerg.haefliger@hpe.com> wrote:
> 
>> This patch adds support for signing a kernel module with a raw
>> detached PKCS#7 signature/message.
>>
>> The signature is not converted and is simply appended to the module so
>> it needs to be in the right format. Using openssl, a valid signature can
>> be generated like this:
>>   $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
>>     <key> -signer <x509> -outform der -out <raw sig>
>>
>> The resulting raw signature from the above command is (more or less)
>> identical to the raw signature that sign-file itself can produce like
>> this:
>>   $ scripts/sign-file -d <hash algo> <key> <x509> <module>
> 
> What's the usage case for this?  Can it be done instead with openssl PKCS#11?

Our internal signing service doesn't support PKCS#11. I have to submit the blobs
and get detached PKCS#7 messages back. I don't claim I fully understand all the
different signing mechanisms but everything worked just fine until support for
signing with a detached signature was removed. IMO that's a regression, which
I'm trying to fix with this patch.

...Juerg



> David
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-02-10 13:24   ` Juerg Haefliger
@ 2016-02-18  9:26     ` Juerg Haefliger
  0 siblings, 0 replies; 13+ messages in thread
From: Juerg Haefliger @ 2016-02-18  9:26 UTC (permalink / raw)
  To: David Howells; +Cc: linux-kernel, keyrings, dwmw2

On 02/10/2016 02:24 PM, Juerg Haefliger wrote:
> On 02/10/2016 11:12 AM, David Howells wrote:
>> Juerg Haefliger <juerg.haefliger@hpe.com> wrote:
>>
>>> This patch adds support for signing a kernel module with a raw
>>> detached PKCS#7 signature/message.
>>>
>>> The signature is not converted and is simply appended to the module so
>>> it needs to be in the right format. Using openssl, a valid signature can
>>> be generated like this:
>>>   $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
>>>     <key> -signer <x509> -outform der -out <raw sig>
>>>
>>> The resulting raw signature from the above command is (more or less)
>>> identical to the raw signature that sign-file itself can produce like
>>> this:
>>>   $ scripts/sign-file -d <hash algo> <key> <x509> <module>
>>
>> What's the usage case for this?  Can it be done instead with openssl PKCS#11?
> 
> Our internal signing service doesn't support PKCS#11. I have to submit the blobs
> and get detached PKCS#7 messages back. I don't claim I fully understand all the
> different signing mechanisms but everything worked just fine until support for
> signing with a detached signature was removed. IMO that's a regression, which
> I'm trying to fix with this patch.

Any comments?

Thanks
...Juerg

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] scripts/sign-file.c: Add support for signing with a raw signature
  2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
                   ` (4 preceding siblings ...)
  2016-02-10 10:12 ` David Howells
@ 2016-02-18 17:23 ` David Howells
  5 siblings, 0 replies; 13+ messages in thread
From: David Howells @ 2016-02-18 17:23 UTC (permalink / raw)
  To: Juerg Haefliger; +Cc: dhowells, linux-kernel, keyrings, dwmw2

Juerg Haefliger <juerg.haefliger@hpe.com> wrote:

> This patch adds support for signing a kernel module with a raw
> detached PKCS#7 signature/message.
> 
> The signature is not converted and is simply appended to the module so
> it needs to be in the right format. Using openssl, a valid signature can
> be generated like this:
>   $ openssl smime -sign -nocerts -noattr -binary -in <module> -inkey \
>     <key> -signer <x509> -outform der -out <raw sig>
> 
> The resulting raw signature from the above command is (more or less)
> identical to the raw signature that sign-file itself can produce like
> this:
>   $ scripts/sign-file -d <hash algo> <key> <x509> <module>
> 
> Signed-off-by: Juerg Haefliger <juerg.haefliger@hpe.com>

Applied.

David

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-02-18 17:23 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-30  9:18 [PATCH] scripts/sign-file.c: Add support for signing with a raw signature Juerg Haefliger
2016-02-03 20:34 ` David Howells
2016-02-04  9:07   ` Juerg Haefliger
2016-02-04 10:42   ` David Howells
2016-02-03 20:45 ` David Howells
2016-02-04 11:09 ` [PATCH v2] " Juerg Haefliger
2016-02-09 16:44 ` David Howells
2016-02-10 10:12 ` David Howells
2016-02-10 10:25   ` David Woodhouse
2016-02-10 13:07   ` Juerg Haefliger
2016-02-10 13:24   ` Juerg Haefliger
2016-02-18  9:26     ` Juerg Haefliger
2016-02-18 17:23 ` David Howells

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.