lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 26 Mar 2013 23:58:21 +0100
From:	Michal Marek <mmarek@...e.cz>
To:	Rusty Russell <rusty@...tcorp.com.au>
Cc:	David Howells <dhowells@...hat.com>, linux-kernel@...r.kernel.org
Subject: [PATCH] MODSIGN: Discard previous signature when signing modules

The format only supports one signature, so discard any previous
signature before signing the module.

Signed-off-by: Michal Marek <mmarek@...e.cz>
---
 scripts/sign-file |   62 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/scripts/sign-file b/scripts/sign-file
index 2b7c448..b390dc3 100755
--- a/scripts/sign-file
+++ b/scripts/sign-file
@@ -60,6 +60,23 @@ sub read_file($)
     return $contents;
 }
 
+sub openssl_pipe($$) {
+	my ($input, $cmd) = @_;
+	my ($pid, $res);
+
+	$pid = open2(*read_from, *write_to, $cmd) || die $cmd;
+	binmode write_to;
+	print write_to $input || die "pipe to $cmd";
+	close(write_to) || die "pipe to $cmd";
+
+	binmode read_from;
+	read(read_from, $res, 4096) || die "pipe from $cmd";
+	close(read_from) || die "pipe from $cmd";
+	waitpid($pid, 0) || die;
+	die "$cmd died: $?" if ($? >> 8);
+	return $res;
+}
+
 ###############################################################################
 #
 # First of all, we have to parse the X.509 certificate to find certain details
@@ -350,6 +367,24 @@ if ($dgst eq "sha1") {
     die "Unknown hash algorithm: $dgst\n";
 }
 
+my $unsigned_module = read_file($module);
+
+my $magic_number = "~Module signature appended~\n";
+my $magic_len = length($magic_number);
+my $info_len = 12;
+
+# Truncate existing signarure, if any
+if (substr($unsigned_module, -$magic_len) eq $magic_number) {
+	my $info = substr($unsigned_module, -$magic_len - $info_len, $info_len);
+	my ($name_len, $key_len, $sig_len) = unpack("xxxCCxxxN", $info);
+	my $subtract = $name_len + $key_len + $sig_len + $info_len + $magic_len;
+	if ($subtract > length($unsigned_module)) {
+		die "$module: Existing signature is malformed\n";
+	}
+	$unsigned_module = substr($unsigned_module, 0,
+		length($unsigned_module) - $subtract);
+}
+
 my $signature;
 if ($signature_file) {
 	$signature = read_file($signature_file);
@@ -357,41 +392,30 @@ if ($signature_file) {
 	#
 	# Generate the digest and read from openssl's stdout
 	#
-	my $digest;
-	$digest = readpipe("openssl dgst -$dgst -binary $module") || die "openssl dgst";
+	my $digest = openssl_pipe($unsigned_module,
+		"openssl dgst -$dgst -binary");
 
 	#
 	# Generate the binary signature, which will be just the integer that
 	# comprises the signature with no metadata attached.
 	#
-	my $pid;
-	$pid = open2(*read_from, *write_to,
-		     "openssl rsautl -sign -inkey $private_key -keyform PEM") ||
-	    die "openssl rsautl";
-	binmode write_to;
-	print write_to $prologue . $digest || die "pipe to openssl rsautl";
-	close(write_to) || die "pipe to openssl rsautl";
-
-	binmode read_from;
-	read(read_from, $signature, 4096) || die "pipe from openssl rsautl";
-	close(read_from) || die "pipe from openssl rsautl";
-	waitpid($pid, 0) || die;
-	die "openssl rsautl died: $?" if ($? >> 8);
+	$signature = openssl_pipe($prologue . $digest,
+		     "openssl rsautl -sign -inkey $private_key -keyform PEM");
 }
 $signature = pack("n", length($signature)) . $signature,
 
 #
 # Build the signed binary
 #
-my $unsigned_module = read_file($module);
-
-my $magic_number = "~Module signature appended~\n";
-
 my $info = pack("CCCCCxxxN",
 		$algo, $hash, $id_type,
 		length($signers_name),
 		length($key_identifier),
 		length($signature));
+# Make sure that $info_len value used above matches reality
+if (length($info) != $info_len) {
+	die "Signature info size changed ($info_len -> @{[length($info)]}";
+}
 
 if ($verbose) {
     print "Size of unsigned module: ", length($unsigned_module), "\n";
-- 
1.7.3.1

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ