linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] sign-file: refactor argument parsing logic
@ 2023-02-09 16:05 Shreenidhi Shedi
  2023-02-09 16:05 ` [PATCH 2/4] sign-file: add license identifier Shreenidhi Shedi
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Shreenidhi Shedi @ 2023-02-09 16:05 UTC (permalink / raw)
  To: dhowells, dwmw2; +Cc: linux-kernel, Shreenidhi Shedi

Add support for bulk signing of modules.

Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
---
 sign-file.c | 349 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 228 insertions(+), 121 deletions(-)

diff --git a/sign-file.c b/sign-file.c
index 598ef54..76fee75 100644
--- a/sign-file.c
+++ b/sign-file.c
@@ -213,15 +213,117 @@ static X509 *read_x509(const char *x509_name)
 	return x509;
 }

+struct cmd_opts {
+	char *hash_algo;
+	char *dest_name;
+	char *private_key_name;
+	char *raw_sig_name;
+	char *x509_name;
+	char *module_name;
+	bool save_sig;
+	bool replace_orig;
+	bool raw_sig;
+	bool sign_only;
+	bool bulk_sign;
+
+#ifndef USE_PKCS7
+	unsigned int use_keyid;
+#endif
+};
+
+void parse_args(int *argc, char **argv, struct cmd_opts *opts)
+{
+	struct option cmd_options[] = {
+		/* These options set a flag. */
+		{"help", no_argument, 0, 'h'},
+		{"savesig", no_argument, 0, 's'},
+		{"signonly", no_argument, 0, 'o'},
+		{"bulksign", no_argument, 0, 'b'},
+#ifndef USE_PKCS7
+		{"usekeyid", no_argument, 0, 'k'},
+#endif
+		{"rawsig", required_argument, 0, 'r'},
+		{"privkey", required_argument, 0, 'p'},
+		{"hashalgo", required_argument, 0, 'a'},
+		{"x509", required_argument, 0, 'x'},
+		{"dest", required_argument, 0, 'd'},
+		{"replaceorig", required_argument, 0, 'l'},
+		{0, 0, 0, 0}
+	};
+
+	int opt;
+	int opt_index;
+
+	do {
+#ifndef USE_PKCS7
+		opt = getopt_long_only(*argc, argv, "hsobr:p:a:x:d:l:",
+					cmd_options, &opt_index);
+#else
+		opt = getopt_long_only(*argc, argv, "hsobkr:p:a:x:d:l:",
+					cmd_options, &opt_index);
+#endif
+		switch (opt) {
+		case 'h':
+			format();
+			break;
+
+		case 'r':
+			opts->raw_sig = true;
+			opts->raw_sig_name = optarg;
+			break;
+
+		case 's':
+			opts->save_sig = true;
+			break;
+
+		case 'o':
+			opts->sign_only = true;
+			opts->save_sig = true;
+			break;
+
+#ifndef USE_PKCS7
+		case 'k':
+			opts->use_keyid = CMS_USE_KEYID;
+			break;
+#endif
+
+		case 'p':
+			opts->private_key_name = optarg;
+			break;
+
+		case 'a':
+			opts->hash_algo = optarg;
+			break;
+
+		case 'x':
+			opts->x509_name = optarg;
+			break;
+
+		case 'd':
+			opts->dest_name = optarg;
+			break;
+
+		case 'l':
+			opts->replace_orig = true;
+			break;
+
+		case 'b':
+			opts->bulk_sign = true;
+			break;
+
+		case -1:
+			break;
+
+		default:
+			format();
+			break;
+		}
+	} while (opt != -1);
+}
+
 int main(int argc, char **argv)
 {
 	struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 };
-	char *hash_algo = NULL;
-	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;
@@ -229,13 +331,14 @@ int main(int argc, char **argv)
 	EVP_PKEY *private_key;
 #ifndef USE_PKCS7
 	CMS_ContentInfo *cms = NULL;
-	unsigned int use_keyid = 0;
 #else
 	PKCS7 *pkcs7 = NULL;
 #endif
 	X509 *x509;
 	BIO *bd, *bm;
-	int opt, n;
+	int i, n;
+	struct cmd_opts opts = {0};
+
 	OpenSSL_add_all_algorithms();
 	ERR_load_crypto_strings();
 	ERR_clear_error();
@@ -248,159 +351,163 @@ int main(int argc, char **argv)
 	use_signed_attrs = PKCS7_NOATTR;
 #endif

-	do {
-		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;
+	parse_args(&argc, argv, &opts);
+	argc -= optind;
+	argv += optind;
+
+	char *hash_algo = opts.hash_algo;
+	char *dest_name = opts.dest_name;
+	char *private_key_name = opts.private_key_name;
+	char *raw_sig_name = opts.raw_sig_name;
+	char *x509_name = opts.x509_name;
+	char *module_name = opts.module_name;
+	bool save_sig = opts.save_sig;
+	bool replace_orig = opts.replace_orig;
+	bool raw_sig = opts.raw_sig;
+	bool sign_only = opts.sign_only;
+	bool bulk_sign = opts.bulk_sign;
+
 #ifndef USE_PKCS7
-		case 'k': use_keyid = CMS_USE_KEYID; break;
+	unsigned int use_keyid = opts.bulk_sign;
 #endif
-		case -1: break;
-		default: format();
-		}
-	} while (opt != -1);

-	argc -= optind;
-	argv += optind;
-	if (argc < 4 || argc > 5)
+	if ((bulk_sign && dest_name) || (!bulk_sign && argc != 1))
 		format();

-	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 && strcmp(argv[3], argv[4]) != 0) {
-		dest_name = argv[4];
+	if (dest_name && strcmp(argv[0], dest_name)) {
 		replace_orig = false;
 	} else {
 		ERR(asprintf(&dest_name, "%s.~signed~", module_name) < 0,
-		    "asprintf");
+				"asprintf");
 		replace_orig = true;
 	}

 #ifdef USE_PKCS7
 	if (strcmp(hash_algo, "sha1") != 0) {
 		fprintf(stderr, "sign-file: %s only supports SHA1 signing\n",
-			OPENSSL_VERSION_TEXT);
+				OPENSSL_VERSION_TEXT);
 		exit(3);
 	}
 #endif

-	/* Open the module file */
-	bm = BIO_new_file(module_name, "rb");
-	ERR(!bm, "%s", module_name);
-
-	if (!raw_sig) {
-		/* 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);
+	for (i = 0; i < argc; i++) {
+		module_name = argv[i];

-		/* 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");
+		if (bulk_sign) {
+			ERR(asprintf(&dest_name, "%s.~signed~", module_name) < 0,
+					"asprintf");
+			if (!replace_orig)
+				replace_orig = true;
+		}
+		/* Open the module file */
+		bm = BIO_new_file(module_name, "rb");
+		ERR(!bm, "%s", module_name);
+
+		if (!raw_sig) {
+			/* 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);
+
+			/* 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;
-			BIO *b;
+			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) {
+				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);
-	while ((n = BIO_read(bm, buf, sizeof(buf))),
-	       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);
+		/* 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);
+		while ((n = BIO_read(bm, buf, sizeof(buf))),
+				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) {
+		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;
+		} 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);
-	}
+			/* 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);
-	ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name);
+		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);
+		ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name);

-	ERR(BIO_free(bd) < 0, "%s", dest_name);
+		ERR(BIO_free(bd) < 0, "%s", dest_name);

-	/* Finally, if we're signing in place, replace the original. */
-	if (replace_orig)
-		ERR(rename(dest_name, module_name) < 0, "%s", dest_name);
+		/* Finally, if we're signing in place, replace the original. */
+		if (replace_orig)
+			ERR(rename(dest_name, module_name) < 0, "%s", dest_name);
+	}

 	return 0;
 }
--
2.39.0


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

* [PATCH 2/4] sign-file: add license identifier
  2023-02-09 16:05 [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
@ 2023-02-09 16:05 ` Shreenidhi Shedi
  2023-02-09 16:05 ` [PATCH 3/4] sign-file: fix few checkpatch issues Shreenidhi Shedi
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Shreenidhi Shedi @ 2023-02-09 16:05 UTC (permalink / raw)
  To: dhowells, dwmw2; +Cc: linux-kernel, Shreenidhi Shedi

Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
---
 sign-file.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sign-file.c b/sign-file.c
index 76fee75..b2619db 100644
--- a/sign-file.c
+++ b/sign-file.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
 /* Sign a module file using the given key.
  *
  * Copyright © 2014-2016 Red Hat, Inc. All Rights Reserved.
-- 
2.39.0


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

* [PATCH 3/4] sign-file: fix few checkpatch issues
  2023-02-09 16:05 [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
  2023-02-09 16:05 ` [PATCH 2/4] sign-file: add license identifier Shreenidhi Shedi
@ 2023-02-09 16:05 ` Shreenidhi Shedi
  2023-02-09 16:05 ` [PATCH 4/4] sign-file: improve help message Shreenidhi Shedi
  2023-02-11 19:34 ` [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
  3 siblings, 0 replies; 6+ messages in thread
From: Shreenidhi Shedi @ 2023-02-09 16:05 UTC (permalink / raw)
  To: dhowells, dwmw2; +Cc: linux-kernel, Shreenidhi Shedi

Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
---
 sign-file.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sign-file.c b/sign-file.c
index b2619db..2faf302 100644
--- a/sign-file.c
+++ b/sign-file.c
@@ -73,7 +73,7 @@ struct module_signature {
 
 #define PKEY_ID_PKCS7 2
 
-static char magic_number[] = "~Module signature appended~\n";
+static const char magic_number[] = "~Module signature appended~\n";
 
 static __attribute__((noreturn))
 void format(void)
@@ -118,7 +118,7 @@ static void drain_openssl_errors(void)
 		if (__cond) {				\
 			errx(1, fmt, ## __VA_ARGS__);	\
 		}					\
-	} while(0)
+	} while (0)
 
 static const char *key_pass;
 
-- 
2.39.0


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

* [PATCH 4/4] sign-file: improve help message
  2023-02-09 16:05 [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
  2023-02-09 16:05 ` [PATCH 2/4] sign-file: add license identifier Shreenidhi Shedi
  2023-02-09 16:05 ` [PATCH 3/4] sign-file: fix few checkpatch issues Shreenidhi Shedi
@ 2023-02-09 16:05 ` Shreenidhi Shedi
  2023-02-11 19:34 ` [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
  3 siblings, 0 replies; 6+ messages in thread
From: Shreenidhi Shedi @ 2023-02-09 16:05 UTC (permalink / raw)
  To: dhowells, dwmw2; +Cc: linux-kernel, Shreenidhi Shedi

Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
---
 sign-file.c | 49 ++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 40 insertions(+), 9 deletions(-)

diff --git a/sign-file.c b/sign-file.c
index 2faf302..0c41a5a 100644
--- a/sign-file.c
+++ b/sign-file.c
@@ -76,13 +76,44 @@ struct module_signature {
 static const char magic_number[] = "~Module signature appended~\n";
 
 static __attribute__((noreturn))
-void format(void)
+void print_usage(int retval)
 {
-	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);
+	fprintf(stderr, "Usage: scripts/sign-file [OPTIONS]... [MODULE]...\n");
+	fprintf(stderr, "Available options:\n");
+	fprintf(stderr, "-h, --help		Print this help message and exit\n");
+
+	fprintf(stderr, "\nOptional args:\n");
+	fprintf(stderr, "-s, --savesig		Save signature\n");
+	fprintf(stderr, "-o, --signonly		Sign only\n");
+	fprintf(stderr, "-b, --bulksign		Sign modules in bulk\n");
+	fprintf(stderr, "-l, --replaceorig	Replace original\n");
+#ifndef USE_PKCS7
+	fprintf(stderr, "-k, --usekeyid		Use key ID\n");
+#endif
+	fprintf(stderr, "-r, --rawsig <sig>	Raw signature\n");
+	fprintf(stderr, "-d, --dest <dest>	Destination path ");
+	fprintf(stderr, "(Exclusive with bulk option)\n");
+
+	fprintf(stderr, "\nMandatory args:\n");
+	fprintf(stderr, "-p, --privkey <key>	Private key\n");
+	fprintf(stderr, "-a, --hashalgo <alg>	Hash algorithm\n");
+	fprintf(stderr, "-x, --x509 <x509>	X509\n");
+
+	fprintf(stderr, "\nExamples:\n");
+
+	fprintf(stderr, "\nRegular signing:\n");
+	fprintf(stderr, "scripts/sign-file -a sha512 -p certs/signing_key.pem ");
+	fprintf(stderr, "-x certs/signing_key.x509 <module>\n");
+
+	fprintf(stderr, "\nSigning with destination path:\n");
+	fprintf(stderr, "scripts/sign-file -a sha512 -p certs/signing_key.pem ");
+	fprintf(stderr, "-x certs/signing_key.x509 <module> -d <path>\n");
+
+	fprintf(stderr, "\nSigning modules in bulk:\n");
+	fprintf(stderr, "scripts/sign-file -a sha512 -p certs/signing_key.pem ");
+	fprintf(stderr, "-x certs/signing_key.x509 -b <module1> <module2> ...\n");
+
+	exit(retval);
 }
 
 static void display_openssl_errors(int l)
@@ -266,7 +297,7 @@ void parse_args(int *argc, char **argv, struct cmd_opts *opts)
 #endif
 		switch (opt) {
 		case 'h':
-			format();
+			print_usage(0);
 			break;
 
 		case 'r':
@@ -317,7 +348,7 @@ void parse_args(int *argc, char **argv, struct cmd_opts *opts)
 			break;
 
 		default:
-			format();
+			print_usage(2);
 			break;
 		}
 	} while (opt != -1);
@@ -374,7 +405,7 @@ int main(int argc, char **argv)
 #endif
 
 	if ((bulk_sign && dest_name) || (!bulk_sign && argc != 1))
-		format();
+		print_usage(2);
 
 	if (dest_name && strcmp(argv[0], dest_name)) {
 		replace_orig = false;
-- 
2.39.0


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

* Re: [PATCH 1/4] sign-file: refactor argument parsing logic
  2023-02-09 16:05 [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
                   ` (2 preceding siblings ...)
  2023-02-09 16:05 ` [PATCH 4/4] sign-file: improve help message Shreenidhi Shedi
@ 2023-02-11 19:34 ` Shreenidhi Shedi
  2023-02-12  7:24   ` Greg KH
  3 siblings, 1 reply; 6+ messages in thread
From: Shreenidhi Shedi @ 2023-02-11 19:34 UTC (permalink / raw)
  To: dhowells, dwmw2, gregkh; +Cc: linux-kernel, Shreenidhi Shedi

On Thu, 9-Feb-2023 21:35, Shreenidhi Shedi wrote:
> Add support for bulk signing of modules.
> 
> Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
> ---
>   sign-file.c | 349 ++++++++++++++++++++++++++++++++++------------------
>   1 file changed, 228 insertions(+), 121 deletions(-)
> 
> diff --git a/sign-file.c b/sign-file.c
> index 598ef54..76fee75 100644
> --- a/sign-file.c
> +++ b/sign-file.c
> @@ -213,15 +213,117 @@ static X509 *read_x509(const char *x509_name)
>   	return x509;
>   }
> 
> +struct cmd_opts {
> +	char *hash_algo;
> +	char *dest_name;
> +	char *private_key_name;
> +	char *raw_sig_name;
> +	char *x509_name;
> +	char *module_name;
> +	bool save_sig;
> +	bool replace_orig;
> +	bool raw_sig;
> +	bool sign_only;
> +	bool bulk_sign;
> +
> +#ifndef USE_PKCS7
> +	unsigned int use_keyid;
> +#endif
> +};
> +
> +void parse_args(int *argc, char **argv, struct cmd_opts *opts)
> +{
> +	struct option cmd_options[] = {
> +		/* These options set a flag. */
> +		{"help", no_argument, 0, 'h'},
> +		{"savesig", no_argument, 0, 's'},
> +		{"signonly", no_argument, 0, 'o'},
> +		{"bulksign", no_argument, 0, 'b'},
> +#ifndef USE_PKCS7
> +		{"usekeyid", no_argument, 0, 'k'},
> +#endif
> +		{"rawsig", required_argument, 0, 'r'},
> +		{"privkey", required_argument, 0, 'p'},
> +		{"hashalgo", required_argument, 0, 'a'},
> +		{"x509", required_argument, 0, 'x'},
> +		{"dest", required_argument, 0, 'd'},
> +		{"replaceorig", required_argument, 0, 'l'},
> +		{0, 0, 0, 0}
> +	};
> +
> +	int opt;
> +	int opt_index;
> +
> +	do {
> +#ifndef USE_PKCS7
> +		opt = getopt_long_only(*argc, argv, "hsobr:p:a:x:d:l:",
> +					cmd_options, &opt_index);
> +#else
> +		opt = getopt_long_only(*argc, argv, "hsobkr:p:a:x:d:l:",
> +					cmd_options, &opt_index);
> +#endif
> +		switch (opt) {
> +		case 'h':
> +			format();
> +			break;
> +
> +		case 'r':
> +			opts->raw_sig = true;
> +			opts->raw_sig_name = optarg;
> +			break;
> +
> +		case 's':
> +			opts->save_sig = true;
> +			break;
> +
> +		case 'o':
> +			opts->sign_only = true;
> +			opts->save_sig = true;
> +			break;
> +
> +#ifndef USE_PKCS7
> +		case 'k':
> +			opts->use_keyid = CMS_USE_KEYID;
> +			break;
> +#endif
> +
> +		case 'p':
> +			opts->private_key_name = optarg;
> +			break;
> +
> +		case 'a':
> +			opts->hash_algo = optarg;
> +			break;
> +
> +		case 'x':
> +			opts->x509_name = optarg;
> +			break;
> +
> +		case 'd':
> +			opts->dest_name = optarg;
> +			break;
> +
> +		case 'l':
> +			opts->replace_orig = true;
> +			break;
> +
> +		case 'b':
> +			opts->bulk_sign = true;
> +			break;
> +
> +		case -1:
> +			break;
> +
> +		default:
> +			format();
> +			break;
> +		}
> +	} while (opt != -1);
> +}
> +
>   int main(int argc, char **argv)
>   {
>   	struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 };
> -	char *hash_algo = NULL;
> -	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;
> @@ -229,13 +331,14 @@ int main(int argc, char **argv)
>   	EVP_PKEY *private_key;
>   #ifndef USE_PKCS7
>   	CMS_ContentInfo *cms = NULL;
> -	unsigned int use_keyid = 0;
>   #else
>   	PKCS7 *pkcs7 = NULL;
>   #endif
>   	X509 *x509;
>   	BIO *bd, *bm;
> -	int opt, n;
> +	int i, n;
> +	struct cmd_opts opts = {0};
> +
>   	OpenSSL_add_all_algorithms();
>   	ERR_load_crypto_strings();
>   	ERR_clear_error();
> @@ -248,159 +351,163 @@ int main(int argc, char **argv)
>   	use_signed_attrs = PKCS7_NOATTR;
>   #endif
> 
> -	do {
> -		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;
> +	parse_args(&argc, argv, &opts);
> +	argc -= optind;
> +	argv += optind;
> +
> +	char *hash_algo = opts.hash_algo;
> +	char *dest_name = opts.dest_name;
> +	char *private_key_name = opts.private_key_name;
> +	char *raw_sig_name = opts.raw_sig_name;
> +	char *x509_name = opts.x509_name;
> +	char *module_name = opts.module_name;
> +	bool save_sig = opts.save_sig;
> +	bool replace_orig = opts.replace_orig;
> +	bool raw_sig = opts.raw_sig;
> +	bool sign_only = opts.sign_only;
> +	bool bulk_sign = opts.bulk_sign;
> +
>   #ifndef USE_PKCS7
> -		case 'k': use_keyid = CMS_USE_KEYID; break;
> +	unsigned int use_keyid = opts.bulk_sign;
>   #endif
> -		case -1: break;
> -		default: format();
> -		}
> -	} while (opt != -1);
> 
> -	argc -= optind;
> -	argv += optind;
> -	if (argc < 4 || argc > 5)
> +	if ((bulk_sign && dest_name) || (!bulk_sign && argc != 1))
>   		format();
> 
> -	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 && strcmp(argv[3], argv[4]) != 0) {
> -		dest_name = argv[4];
> +	if (dest_name && strcmp(argv[0], dest_name)) {
>   		replace_orig = false;
>   	} else {
>   		ERR(asprintf(&dest_name, "%s.~signed~", module_name) < 0,
> -		    "asprintf");
> +				"asprintf");
>   		replace_orig = true;
>   	}
> 
>   #ifdef USE_PKCS7
>   	if (strcmp(hash_algo, "sha1") != 0) {
>   		fprintf(stderr, "sign-file: %s only supports SHA1 signing\n",
> -			OPENSSL_VERSION_TEXT);
> +				OPENSSL_VERSION_TEXT);
>   		exit(3);
>   	}
>   #endif
> 
> -	/* Open the module file */
> -	bm = BIO_new_file(module_name, "rb");
> -	ERR(!bm, "%s", module_name);
> -
> -	if (!raw_sig) {
> -		/* 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);
> +	for (i = 0; i < argc; i++) {
> +		module_name = argv[i];
> 
> -		/* 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");
> +		if (bulk_sign) {
> +			ERR(asprintf(&dest_name, "%s.~signed~", module_name) < 0,
> +					"asprintf");
> +			if (!replace_orig)
> +				replace_orig = true;
> +		}
> +		/* Open the module file */
> +		bm = BIO_new_file(module_name, "rb");
> +		ERR(!bm, "%s", module_name);
> +
> +		if (!raw_sig) {
> +			/* 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);
> +
> +			/* 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;
> -			BIO *b;
> +			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) {
> +				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);
> -	while ((n = BIO_read(bm, buf, sizeof(buf))),
> -	       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);
> +		/* 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);
> +		while ((n = BIO_read(bm, buf, sizeof(buf))),
> +				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) {
> +		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;
> +		} 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);
> -	}
> +			/* 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);
> -	ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name);
> +		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);
> +		ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name);
> 
> -	ERR(BIO_free(bd) < 0, "%s", dest_name);
> +		ERR(BIO_free(bd) < 0, "%s", dest_name);
> 
> -	/* Finally, if we're signing in place, replace the original. */
> -	if (replace_orig)
> -		ERR(rename(dest_name, module_name) < 0, "%s", dest_name);
> +		/* Finally, if we're signing in place, replace the original. */
> +		if (replace_orig)
> +			ERR(rename(dest_name, module_name) < 0, "%s", dest_name);
> +	}
> 
>   	return 0;
>   }
> --
> 2.39.0
> 
> 

+Greg

Hi Greg,

Can you please take this patch series?

Bulk signing of modules is an useful option.
Please let me know your thoughts on this.

--
Shedi


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

* Re: [PATCH 1/4] sign-file: refactor argument parsing logic
  2023-02-11 19:34 ` [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
@ 2023-02-12  7:24   ` Greg KH
  0 siblings, 0 replies; 6+ messages in thread
From: Greg KH @ 2023-02-12  7:24 UTC (permalink / raw)
  To: Shreenidhi Shedi; +Cc: dhowells, dwmw2, linux-kernel, Shreenidhi Shedi

On Sun, Feb 12, 2023 at 01:04:08AM +0530, Shreenidhi Shedi wrote:
> On Thu, 9-Feb-2023 21:35, Shreenidhi Shedi wrote:
> > Add support for bulk signing of modules.
> > 
> > Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
> > ---
> >   sign-file.c | 349 ++++++++++++++++++++++++++++++++++------------------
> >   1 file changed, 228 insertions(+), 121 deletions(-)
> > 
> > diff --git a/sign-file.c b/sign-file.c
> > index 598ef54..76fee75 100644
> > --- a/sign-file.c
> > +++ b/sign-file.c

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- Your patch is malformed (tabs converted to spaces, linewrapped, etc.)
  and can not be applied.  Please read the file,
  Documentation/process/email-clients.rst in order to fix this.

- Your patch did many different things all at once, making it difficult
  to review.  All Linux kernel patches need to only do one thing at a
  time.  If you need to do multiple things (such as clean up all coding
  style issues in a file/driver), do it in a sequence of patches, each
  one doing only one thing.  This will make it easier to review the
  patches to ensure that they are correct, and to help alleviate any
  merge issues that larger patches can cause.

- You did not specify a description of why the patch is needed, or
  possibly, any description at all, in the email body.  Please read the
  section entitled "The canonical patch format" in the kernel file,
  Documentation/process/submitting-patches.rst for what is needed in
  order to properly describe the change.

- You did not write a descriptive Subject: for the patch, allowing Greg,
  and everyone else, to know what this patch is all about.  Please read
  the section entitled "The canonical patch format" in the kernel file,
  Documentation/process/submitting-patches.rst for what a proper
  Subject: line should look like.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot

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

end of thread, other threads:[~2023-02-12  7:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-09 16:05 [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
2023-02-09 16:05 ` [PATCH 2/4] sign-file: add license identifier Shreenidhi Shedi
2023-02-09 16:05 ` [PATCH 3/4] sign-file: fix few checkpatch issues Shreenidhi Shedi
2023-02-09 16:05 ` [PATCH 4/4] sign-file: improve help message Shreenidhi Shedi
2023-02-11 19:34 ` [PATCH 1/4] sign-file: refactor argument parsing logic Shreenidhi Shedi
2023-02-12  7:24   ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).