* [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2]
@ 2012-10-19 22:51 David Howells
2012-10-19 22:51 ` [PATCH 2/2] MODSIGN: Cleanup .gitignore " David Howells
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: David Howells @ 2012-10-19 22:51 UTC (permalink / raw)
To: torvalds, rusty; +Cc: dhowells, davem, linux-kernel
Turn sign-file into perl and merge in x509keyid. The latter doesn't need to be
a separate script as it doesn't actually need to work out the SHA1 sum of the
X.509 certificate itself, since it can get that from the X.509 certificate.
Signed-off-by: David Howells <dhowells@redhat.com>
---
Makefile | 2
kernel/module.c | 3
kernel/module_signing.c | 2
scripts/sign-file | 477 +++++++++++++++++++++++++++++++++++++++--------
scripts/x509keyid | 268 --------------------------
5 files changed, 404 insertions(+), 348 deletions(-)
mode change 100644 => 100755 scripts/sign-file
delete mode 100755 scripts/x509keyid
diff --git a/Makefile b/Makefile
index 4fd82f7..14b9874 100644
--- a/Makefile
+++ b/Makefile
@@ -723,7 +723,7 @@ ifeq ($(CONFIG_MODULE_SIG),y)
MODSECKEY = ./signing_key.priv
MODPUBKEY = ./signing_key.x509
export MODPUBKEY
-mod_sign_cmd = sh $(srctree)/scripts/sign-file $(MODSECKEY) $(MODPUBKEY) $(srctree)/scripts/x509keyid
+mod_sign_cmd = perl $(srctree)/scripts/sign-file $(MODSECKEY) $(MODPUBKEY)
else
mod_sign_cmd = true
endif
diff --git a/kernel/module.c b/kernel/module.c
index 0e2da86..ae0972b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2427,6 +2427,8 @@ static int module_sig_check(struct load_info *info,
const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
const void *p = mod, *end = mod + *len;
+ printk("Check for sig\n");
+
/* Poor man's memmem. */
while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) {
if (p + markerlen > end)
@@ -2435,6 +2437,7 @@ static int module_sig_check(struct load_info *info,
if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) {
const void *sig = p + markerlen;
/* Truncate module up to signature. */
+ printk("Found sig\n");
*len = p - mod;
err = mod_verify_sig(mod, *len, sig, end - sig);
break;
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index 6b09f69..c823a02 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
-
+#define DEBUG
#include <linux/kernel.h>
#include <linux/err.h>
#include <crypto/public_key.h>
diff --git a/scripts/sign-file b/scripts/sign-file
old mode 100644
new mode 100755
index d014abd..c8a2e7c
--- a/scripts/sign-file
+++ b/scripts/sign-file
@@ -1,108 +1,429 @@
-#!/bin/bash
+#!/usr/bin/perl -w
#
# Sign a module file using the given key.
#
-# Format: sign-file <key> <x509> <keyid-script> <module>
+# Format:
#
+# ./scripts/sign-file [-v] <key> <x509> <module> [<dest>]
+#
+#
+use strict;
+use FileHandle;
+use IPC::Open2;
+
+my $verbose = 0;
+if ($#ARGV >= 0 && $ARGV[0] eq "-v") {
+ $verbose = 1;
+ shift;
+}
+
+die "Format: ./scripts/sign-file [-v] <key> <x509> <module> [<dest>]\n"
+ if ($#ARGV != 2 && $#ARGV != 3);
+
+my $private_key = $ARGV[0];
+my $x509 = $ARGV[1];
+my $module = $ARGV[2];
+my $dest = ($#ARGV == 3) ? $ARGV[3] : $ARGV[2] . "~";
+
+die "Can't read private key\n" unless (-r $private_key);
+die "Can't read X.509 certificate\n" unless (-r $x509);
+die "Can't read module\n" unless (-r $module);
+
+#
+# Read the kernel configuration
+#
+my %config = (
+ CONFIG_MODULE_SIG_SHA512 => 1
+ );
+
+if (-r ".config") {
+ open(FD, "<.config") || die ".config";
+ while (<FD>) {
+ if ($_ =~ /^(CONFIG_.*)=[ym]/) {
+ $config{$1} = 1;
+ }
+ }
+ close(FD);
+}
-scripts=`dirname $0`
+#
+# Function to read the contents of a file into a variable.
+#
+sub read_file($)
+{
+ my ($file) = @_;
+ my $contents;
+ my $len;
+
+ open(FD, "<$file") || die $file;
+ binmode FD;
+ my @st = stat(FD);
+ die $file if (!@st);
+ $len = read(FD, $contents, $st[7]) || die $file;
+ close(FD) || die $file;
+ die "$file: Wanted length ", $st[7], ", got ", $len, "\n"
+ if ($len != $st[7]);
+ return $contents;
+}
+
+###############################################################################
+#
+# First of all, we have to parse the X.509 certificate to find certain details
+# about it.
+#
+# We read the DER-encoded X509 certificate and parse it to extract the Subject
+# name and Subject Key Identifier. Theis provides the data we need to build
+# the certificate identifier.
+#
+# The signer's name part of the identifier is fabricated from the commonName,
+# the organizationName or the emailAddress components of the X.509 subject
+# name.
+#
+# The subject key ID is used to select which of that signer's certificates
+# we're intending to use to sign the module.
+#
+###############################################################################
+my $x509_certificate = read_file($x509);
-CONFIG_MODULE_SIG_SHA512=y
-if [ -r .config ]
-then
- . ./.config
-fi
+my $UNIV = 0 << 6;
+my $APPL = 1 << 6;
+my $CONT = 2 << 6;
+my $PRIV = 3 << 6;
-key="$1"
-x509="$2"
-keyid_script="$3"
-mod="$4"
+my $CONS = 0x20;
-if [ ! -r "$key" ]
-then
- echo "Can't read private key" >&2
- exit 2
-fi
+my $BOOLEAN = 0x01;
+my $INTEGER = 0x02;
+my $BIT_STRING = 0x03;
+my $OCTET_STRING = 0x04;
+my $NULL = 0x05;
+my $OBJ_ID = 0x06;
+my $UTF8String = 0x0c;
+my $SEQUENCE = 0x10;
+my $SET = 0x11;
+my $UTCTime = 0x17;
+my $GeneralizedTime = 0x18;
-if [ ! -r "$x509" ]
-then
- echo "Can't read X.509 certificate" >&2
- exit 2
-fi
+my %OIDs = (
+ pack("CCC", 85, 4, 3) => "commonName",
+ pack("CCC", 85, 4, 6) => "countryName",
+ pack("CCC", 85, 4, 10) => "organizationName",
+ pack("CCC", 85, 4, 11) => "organizationUnitName",
+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
+ pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
+ pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
+ pack("CCC", 85, 29, 19) => "basicConstraints"
+);
+
+###############################################################################
+#
+# Extract an ASN.1 element from a string and return information about it.
+#
+###############################################################################
+sub asn1_extract($$@)
+{
+ my ($cursor, $expected_tag, $optional) = @_;
+
+ return [ -1 ]
+ if ($cursor->[1] == 0 && $optional);
+
+ die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
+ if ($cursor->[1] < 2);
+
+ my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
+
+ if ($expected_tag != -1 && $tag != $expected_tag) {
+ return [ -1 ]
+ if ($optional);
+ die $x509, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
+ " not ", $expected_tag, ")\n";
+ }
+
+ $cursor->[0] += 2;
+ $cursor->[1] -= 2;
+
+ die $x509, ": ", $cursor->[0], ": ASN.1 long tag\n"
+ if (($tag & 0x1f) == 0x1f);
+ die $x509, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
+ if ($len == 0x80);
+
+ if ($len > 0x80) {
+ my $l = $len - 0x80;
+ die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
+ if ($cursor->[1] < $l);
+
+ if ($l == 0x1) {
+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
+ } elsif ($l = 0x2) {
+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
+ } elsif ($l = 0x3) {
+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
+ } elsif ($l = 0x4) {
+ $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
+ } else {
+ die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
+ }
+
+ $cursor->[0] += $l;
+ $cursor->[1] -= $l;
+ }
+
+ die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
+ if ($cursor->[1] < $len);
+
+ my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
+ $cursor->[0] += $len;
+ $cursor->[1] -= $len;
+
+ return $ret;
+}
+
+###############################################################################
+#
+# Retrieve the data referred to by a cursor
+#
+###############################################################################
+sub asn1_retrieve($)
+{
+ my ($cursor) = @_;
+ my ($offset, $len, $data) = @$cursor;
+ return substr($$data, $offset, $len);
+}
+
+###############################################################################
+#
+# Roughly parse the X.509 certificate
+#
+###############################################################################
+my $cursor = [ 0, length($x509_certificate), \$x509_certificate ];
+
+my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
+my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
+my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
+my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
+my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
+my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
+my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
+
+my $subject_key_id = ();
+my $authority_key_id = ();
+
+#
+# Parse the extension list
+#
+if ($extension_list->[0] != -1) {
+ my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
+
+ while ($extensions->[1]->[1] > 0) {
+ my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
+ my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
+ my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
+ my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
+
+ my $raw_oid = asn1_retrieve($x_oid->[1]);
+ next if (!exists($OIDs{$raw_oid}));
+ my $x_type = $OIDs{$raw_oid};
+
+ my $raw_value = asn1_retrieve($x_val->[1]);
+
+ if ($x_type eq "subjectKeyIdentifier") {
+ my $vcursor = [ 0, length($raw_value), \$raw_value ];
+
+ $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
+ }
+ }
+}
+
+###############################################################################
+#
+# Determine what we're going to use as the signer's name. In order of
+# preference, take one of: commonName, organizationName or emailAddress.
+#
+###############################################################################
+my $org = "";
+my $cn = "";
+my $email = "";
+
+while ($subject->[1]->[1] > 0) {
+ my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
+ my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
+ my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
+ my $n_val = asn1_extract($attr->[1], -1);
+
+ my $raw_oid = asn1_retrieve($n_oid->[1]);
+ next if (!exists($OIDs{$raw_oid}));
+ my $n_type = $OIDs{$raw_oid};
+
+ my $raw_value = asn1_retrieve($n_val->[1]);
+
+ if ($n_type eq "organizationName") {
+ $org = $raw_value;
+ } elsif ($n_type eq "commonName") {
+ $cn = $raw_value;
+ } elsif ($n_type eq "emailAddress") {
+ $email = $raw_value;
+ }
+}
+
+my $signers_name = $email;
+
+if ($org && $cn) {
+ # Don't use the organizationName if the commonName repeats it
+ if (length($org) <= length($cn) &&
+ substr($cn, 0, length($org)) eq $org) {
+ $signers_name = $cn;
+ goto got_id_name;
+ }
+
+ # Or a signifcant chunk of it
+ if (length($org) >= 7 &&
+ length($cn) >= 7 &&
+ substr($cn, 0, 7) eq substr($org, 0, 7)) {
+ $signers_name = $cn;
+ goto got_id_name;
+ }
+
+ $signers_name = $org . ": " . $cn;
+} elsif ($org) {
+ $signers_name = $org;
+} elsif ($cn) {
+ $signers_name = $cn;
+}
+
+got_id_name:
+
+die $x509, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
+ if (!$subject_key_id);
+
+my $key_identifier = asn1_retrieve($subject_key_id->[1]);
+
+###############################################################################
+#
+# Create and attach the module signature
+#
+###############################################################################
#
# Signature parameters
#
-algo=1 # Public-key crypto algorithm: RSA
-hash= # Digest algorithm
-id_type=1 # Identifier type: X.509
+my $algo = 1; # Public-key crypto algorithm: RSA
+my $hash = 0; # Digest algorithm
+my $id_type = 1; # Identifier type: X.509
#
# Digest the data
#
-dgst=
-if [ "$CONFIG_MODULE_SIG_SHA1" = "y" ]
-then
- prologue="0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14"
- dgst=-sha1
- hash=2
-elif [ "$CONFIG_MODULE_SIG_SHA224" = "y" ]
-then
- prologue="0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C"
- dgst=-sha224
- hash=7
-elif [ "$CONFIG_MODULE_SIG_SHA256" = "y" ]
-then
- prologue="0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20"
- dgst=-sha256
- hash=4
-elif [ "$CONFIG_MODULE_SIG_SHA384" = "y" ]
-then
- prologue="0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30"
- dgst=-sha384
- hash=5
-elif [ "$CONFIG_MODULE_SIG_SHA512" = "y" ]
-then
- prologue="0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40"
- dgst=-sha512
- hash=6
-else
- echo "$0: Can't determine hash algorithm" >&2
- exit 2
-fi
-
-(
-perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $?
-openssl dgst $dgst -binary $mod || exit $?
-) >$mod.dig || exit $?
+my ($dgst, $prologue) = ();
+if (exists $config{"CONFIG_MODULE_SIG_SHA1"}) {
+ $prologue = pack("C*",
+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+ 0x2B, 0x0E, 0x03, 0x02, 0x1A,
+ 0x05, 0x00, 0x04, 0x14);
+ $dgst = "-sha1";
+ $hash = 2;
+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA224"}) {
+ $prologue = pack("C*",
+ 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
+ 0x05, 0x00, 0x04, 0x1C);
+ $dgst = "-sha224";
+ $hash = 7;
+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA256"}) {
+ $prologue = pack("C*",
+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x20);
+ $dgst = "-sha256";
+ $hash = 4;
+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA384"}) {
+ $prologue = pack("C*",
+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
+ 0x05, 0x00, 0x04, 0x30);
+ $dgst = "-sha384";
+ $hash = 5;
+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA512"}) {
+ $prologue = pack("C*",
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+ 0x05, 0x00, 0x04, 0x40);
+ $dgst = "-sha512";
+ $hash = 6;
+} else {
+ die "Can't determine hash algorithm";
+}
+
+#
+# Generate the digest and read from openssl's stdout
+#
+my $digest;
+$digest = readpipe("openssl dgst $dgst -binary $module") || die "openssl dgst";
#
# Generate the binary signature, which will be just the integer that comprises
# the signature with no metadata attached.
#
-openssl rsautl -sign -inkey $key -keyform PEM -in $mod.dig -out $mod.sig || exit $?
-siglen=`stat -c %s $mod.sig`
+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;
+my $signature;
+read(read_from, $signature, 4096) || die "pipe from openssl rsautl";
+close(read_from) || die "pipe from openssl rsautl";
+$signature = pack("n", length($signature)) . $signature,
-SIGNER="`perl $keyid_script $x509 signer-name`"
-KEYID="`perl $keyid_script $x509 keyid`"
-keyidlen=$(echo -n "$KEYID" | wc -c)
-signerlen=$(echo -n "$SIGNER" | wc -c)
+waitpid($pid, 0) || die;
+die "openssl rsautl died: $?" if ($? >> 8);
#
# Build the signed binary
#
-(
- cat $mod || exit $?
- echo '~Module signature appended~' || exit $?
- echo -n "$SIGNER" || exit $?
- echo -n "$KEYID" || exit $?
+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));
- # Preface each signature integer with a 2-byte BE length
- perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $?
- cat $mod.sig || exit $?
+if ($verbose) {
+ print "Size of unsigned module: ", length($unsigned_module), "\n";
+ print "Size of magic number : ", length($magic_number), "\n";
+ print "Size of signer's name : ", length($signers_name), "\n";
+ print "Size of key identifier : ", length($key_identifier), "\n";
+ print "Size of signature : ", length($signature), "\n";
+ print "Size of informaton : ", length($info), "\n";
+ print "Signer's name : '", $signers_name, "'\n";
+ print "Digest : $dgst\n";
+}
- # Generate the information block
- perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $?
-) >$mod~ || exit $?
+open(FD, ">$dest") || die $dest;
+binmode FD;
+print FD
+ $unsigned_module,
+ $magic_number,
+ $signers_name,
+ $key_identifier,
+ $signature,
+ $info
+ ;
+close FD || die $dest;
-mv $mod~ $mod || exit $?
+if ($#ARGV != 3) {
+ rename($dest, $module) || die $module;
+}
diff --git a/scripts/x509keyid b/scripts/x509keyid
deleted file mode 100755
index 4241ec6..0000000
--- a/scripts/x509keyid
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Generate an identifier from an X.509 certificate that can be placed in a
-# module signature to indentify the key to use.
-#
-# Format:
-#
-# ./scripts/x509keyid <x509-cert> <signer's-name> <key-id>
-#
-# We read the DER-encoded X509 certificate and parse it to extract the Subject
-# name and Subject Key Identifier. The provide the data we need to build the
-# certificate identifier.
-#
-# The signer's name part of the identifier is fabricated from the commonName,
-# the organizationName or the emailAddress components of the X.509 subject
-# name and written to the second named file.
-#
-# The subject key ID to select which of that signer's certificates we're
-# intending to use to sign the module is written to the third named file.
-#
-use strict;
-
-my $raw_data;
-
-die "Need a filename [keyid|signer-name]\n" if ($#ARGV != 1);
-
-my $src = $ARGV[0];
-
-open(FD, "<$src") || die $src;
-binmode FD;
-my @st = stat(FD);
-die $src if (!@st);
-read(FD, $raw_data, $st[7]) || die $src;
-close(FD);
-
-my $UNIV = 0 << 6;
-my $APPL = 1 << 6;
-my $CONT = 2 << 6;
-my $PRIV = 3 << 6;
-
-my $CONS = 0x20;
-
-my $BOOLEAN = 0x01;
-my $INTEGER = 0x02;
-my $BIT_STRING = 0x03;
-my $OCTET_STRING = 0x04;
-my $NULL = 0x05;
-my $OBJ_ID = 0x06;
-my $UTF8String = 0x0c;
-my $SEQUENCE = 0x10;
-my $SET = 0x11;
-my $UTCTime = 0x17;
-my $GeneralizedTime = 0x18;
-
-my %OIDs = (
- pack("CCC", 85, 4, 3) => "commonName",
- pack("CCC", 85, 4, 6) => "countryName",
- pack("CCC", 85, 4, 10) => "organizationName",
- pack("CCC", 85, 4, 11) => "organizationUnitName",
- pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
- pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
- pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
- pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
- pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
- pack("CCC", 85, 29, 19) => "basicConstraints"
-);
-
-###############################################################################
-#
-# Extract an ASN.1 element from a string and return information about it.
-#
-###############################################################################
-sub asn1_extract($$@)
-{
- my ($cursor, $expected_tag, $optional) = @_;
-
- return [ -1 ]
- if ($cursor->[1] == 0 && $optional);
-
- die $src, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
- if ($cursor->[1] < 2);
-
- my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
-
- if ($expected_tag != -1 && $tag != $expected_tag) {
- return [ -1 ]
- if ($optional);
- die $src, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
- " not ", $expected_tag, ")\n";
- }
-
- $cursor->[0] += 2;
- $cursor->[1] -= 2;
-
- die $src, ": ", $cursor->[0], ": ASN.1 long tag\n"
- if (($tag & 0x1f) == 0x1f);
- die $src, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
- if ($len == 0x80);
-
- if ($len > 0x80) {
- my $l = $len - 0x80;
- die $src, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
- if ($cursor->[1] < $l);
-
- if ($l == 0x1) {
- $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
- } elsif ($l = 0x2) {
- $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
- } elsif ($l = 0x3) {
- $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
- $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
- } elsif ($l = 0x4) {
- $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
- } else {
- die $src, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
- }
-
- $cursor->[0] += $l;
- $cursor->[1] -= $l;
- }
-
- die $src, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
- if ($cursor->[1] < $len);
-
- my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
- $cursor->[0] += $len;
- $cursor->[1] -= $len;
-
- return $ret;
-}
-
-###############################################################################
-#
-# Retrieve the data referred to by a cursor
-#
-###############################################################################
-sub asn1_retrieve($)
-{
- my ($cursor) = @_;
- my ($offset, $len, $data) = @$cursor;
- return substr($$data, $offset, $len);
-}
-
-###############################################################################
-#
-# Roughly parse the X.509 certificate
-#
-###############################################################################
-my $cursor = [ 0, length($raw_data), \$raw_data ];
-
-my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
-my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
-my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
-my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
-my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
-my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
-my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
-
-my $subject_key_id = ();
-my $authority_key_id = ();
-
-#
-# Parse the extension list
-#
-if ($extension_list->[0] != -1) {
- my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
-
- while ($extensions->[1]->[1] > 0) {
- my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
- my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
- my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
- my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
-
- my $raw_oid = asn1_retrieve($x_oid->[1]);
- next if (!exists($OIDs{$raw_oid}));
- my $x_type = $OIDs{$raw_oid};
-
- my $raw_value = asn1_retrieve($x_val->[1]);
-
- if ($x_type eq "subjectKeyIdentifier") {
- my $vcursor = [ 0, length($raw_value), \$raw_value ];
-
- $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
- }
- }
-}
-
-###############################################################################
-#
-# Determine what we're going to use as the signer's name. In order of
-# preference, take one of: commonName, organizationName or emailAddress.
-#
-###############################################################################
-my $org = "";
-my $cn = "";
-my $email = "";
-
-while ($subject->[1]->[1] > 0) {
- my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
- my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
- my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
- my $n_val = asn1_extract($attr->[1], -1);
-
- my $raw_oid = asn1_retrieve($n_oid->[1]);
- next if (!exists($OIDs{$raw_oid}));
- my $n_type = $OIDs{$raw_oid};
-
- my $raw_value = asn1_retrieve($n_val->[1]);
-
- if ($n_type eq "organizationName") {
- $org = $raw_value;
- } elsif ($n_type eq "commonName") {
- $cn = $raw_value;
- } elsif ($n_type eq "emailAddress") {
- $email = $raw_value;
- }
-}
-
-my $id_name = $email;
-
-if ($org && $cn) {
- # Don't use the organizationName if the commonName repeats it
- if (length($org) <= length($cn) &&
- substr($cn, 0, length($org)) eq $org) {
- $id_name = $cn;
- goto got_id_name;
- }
-
- # Or a signifcant chunk of it
- if (length($org) >= 7 &&
- length($cn) >= 7 &&
- substr($cn, 0, 7) eq substr($org, 0, 7)) {
- $id_name = $cn;
- goto got_id_name;
- }
-
- $id_name = $org . ": " . $cn;
-} elsif ($org) {
- $id_name = $org;
-} elsif ($cn) {
- $id_name = $cn;
-}
-
-got_id_name:
-
-###############################################################################
-#
-# Output the signer's name and the key identifier that we're going to include
-# in module signatures.
-#
-###############################################################################
-die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
- if (!$subject_key_id);
-
-my $id_key_id = asn1_retrieve($subject_key_id->[1]);
-
-if ($ARGV[1] eq "signer-name") {
- print $id_name;
-} elsif ($ARGV[1] eq "keyid") {
- print $id_key_id;
-} else {
- die "Unknown arg";
-}
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/2] MODSIGN: Cleanup .gitignore [ver #2]
2012-10-19 22:51 [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2] David Howells
@ 2012-10-19 22:51 ` David Howells
2012-10-19 22:54 ` [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid " David Howells
2012-10-19 22:58 ` Linus Torvalds
2 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2012-10-19 22:51 UTC (permalink / raw)
To: torvalds, rusty; +Cc: dhowells, davem, linux-kernel
The module build process no longer creates intermediate files for module
signing, so remove them from .gitignore.
Signed-off-by: David Howells <dhowells@redhat.com>
---
.gitignore | 6 ------
1 file changed, 6 deletions(-)
diff --git a/.gitignore b/.gitignore
index 0f2f40f..92bd0e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,10 +14,6 @@
*.o.*
*.a
*.s
-*.ko.unsigned
-*.ko.stripped
-*.ko.stripped.dig
-*.ko.stripped.sig
*.ko
*.so
*.so.dbg
@@ -95,6 +91,4 @@ GTAGS
extra_certificates
signing_key.priv
signing_key.x509
-signing_key.x509.keyid
-signing_key.x509.signer
x509.genkey
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2]
2012-10-19 22:51 [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2] David Howells
2012-10-19 22:51 ` [PATCH 2/2] MODSIGN: Cleanup .gitignore " David Howells
@ 2012-10-19 22:54 ` David Howells
2012-10-19 22:58 ` Linus Torvalds
2 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2012-10-19 22:54 UTC (permalink / raw)
Cc: dhowells, torvalds, rusty, davem, linux-kernel
David Howells <dhowells@redhat.com> wrote:
> + printk("Check for sig\n");
> +
> ...
> + printk("Found sig\n");
> ...
> +#define DEBUG
And I also forgot to remove the debugging. Sigh.
David
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2]
2012-10-19 22:51 [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2] David Howells
2012-10-19 22:51 ` [PATCH 2/2] MODSIGN: Cleanup .gitignore " David Howells
2012-10-19 22:54 ` [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid " David Howells
@ 2012-10-19 22:58 ` Linus Torvalds
2012-10-19 23:06 ` Linus Torvalds
2 siblings, 1 reply; 5+ messages in thread
From: Linus Torvalds @ 2012-10-19 22:58 UTC (permalink / raw)
To: David Howells; +Cc: rusty, davem, linux-kernel
This version still seems to have some debug turds in it:
On Fri, Oct 19, 2012 at 3:51 PM, David Howells <dhowells@redhat.com> wrote:
>
> + printk("Check for sig\n");
> +
...
> + printk("Found sig\n");
...
> +#define DEBUG
Also, I wonder how standard this /usr/bin/perl is:
> +#!/usr/bin/perl -w
and maybe we should use Unix best practices and make it do
#!/usr/bin/env perl
instead?
But I dunno, maybe /usr/bin/perl has become sufficiently standardized..
Linus
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2]
2012-10-19 22:58 ` Linus Torvalds
@ 2012-10-19 23:06 ` Linus Torvalds
0 siblings, 0 replies; 5+ messages in thread
From: Linus Torvalds @ 2012-10-19 23:06 UTC (permalink / raw)
To: David Howells; +Cc: rusty, davem, linux-kernel
On Fri, Oct 19, 2012 at 3:58 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> Also, I wonder how standard this /usr/bin/perl is:
>
>> +#!/usr/bin/perl -w
Well, we have other uses of that path in the kernel already, and your
v3 patch uses 'perl' in the Makefile to run it, so it will pick up the
path that way.
So I think it all looks fine now. Will apply, thanks,
Linus
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-10-19 23:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-19 22:51 [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid [ver #2] David Howells
2012-10-19 22:51 ` [PATCH 2/2] MODSIGN: Cleanup .gitignore " David Howells
2012-10-19 22:54 ` [PATCH 1/2] MODSIGN: perlify sign-file and merge in x509keyid " David Howells
2012-10-19 22:58 ` Linus Torvalds
2012-10-19 23:06 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®