Hello community,

here is the log from the commit of package suse-module-tools for 
openSUSE:Factory checked in at 2014-03-18 13:38:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/suse-module-tools (Old)
 and      /work/SRC/openSUSE:Factory/.suse-module-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "suse-module-tools"

Changes:
--------
--- /work/SRC/openSUSE:Factory/suse-module-tools/suse-module-tools.changes      
2014-03-12 14:45:40.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.suse-module-tools.new/suse-module-tools.changes 
2014-03-18 13:38:11.000000000 +0100
@@ -1,0 +2,12 @@
+Tue Mar 11 12:57:36 UTC 2014 - [email protected]
+
+- Add modsign-verify tool to verify signatures of modules
+  (fate#314507).
+
+-------------------------------------------------------------------
+Tue Mar 11 12:38:39 UTC 2014 - [email protected]
+
+- weak-modules2: Support XZ compressed initrds (bnc#778119,
+  bnc#867312)
+
+-------------------------------------------------------------------

New:
----
  modsign-verify

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ suse-module-tools.spec ++++++
--- /var/tmp/diff_new_pack.iPYbr2/_old  2014-03-18 13:38:12.000000000 +0100
+++ /var/tmp/diff_new_pack.iPYbr2/_new  2014-03-18 13:38:12.000000000 +0100
@@ -37,6 +37,7 @@
 Source6:        weak-modules2
 Source7:        driver-check.sh
 Source8:        suse-module-tools.rpmlintrc
+Source9:        modsign-verify
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 %description
@@ -76,6 +77,10 @@
 install -pm 755 %_sourcedir/weak-modules{,2} "$b/usr/lib/module-init-tools/"
 install -pm 755 %_sourcedir/driver-check.sh "$b/usr/lib/module-init-tools/"
 
+# modsign-verify for verifying module signatures
+install -d -m 755 "$b/usr/bin"
+install -pm 755 %_sourcedir/modsign-verify "$b/usr/bin/"
+
 %post
 test_allow_on_install()
 {
@@ -139,6 +144,7 @@
 %dir               /etc/depmod.d
 %config            /etc/depmod.d/00-system.conf
 %_docdir/module-init-tools
+/usr/bin/modsign-verify
 /usr/lib/module-init-tools
 
 %changelog

++++++ modsign-verify ++++++
#!/usr/bin/perl
# 
# Verify kernel module signature generated by /usr/src/linux/scripts/sign-file
# 
# Parts of this script were copied from sign-file, written by David Howels
#

my $USAGE = "Usage: modsign-verify [-v] [-q] [--certificate <x509> | --cert-dir 
<dir>] <module>\n";

use strict;
use warnings;
use IPC::Open2;
use Getopt::Long;
use File::Temp qw(tempfile);

my $cert;
my $cert_dir;
my $verbose = 1;
GetOptions(
        "certificate=s" => \$cert,
        "cert-dir=s" => \$cert_dir,
        "q|quiet" => sub { $verbose-- if $verbose; },
        "v|verbose" => sub { $verbose++; },
        "h|help" => sub {
                print $USAGE;
                print "Return codes: 0 good signature\n";
                print "              1 bad signature\n";
                print "              2 certificate not found\n";
                print "              3 module not signed\n";
                print "             >3 other error\n";
                exit(0);
        }
) or die($USAGE);

sub _verbose {
        my $level = shift;

        return if $verbose < $level;
        print STDERR @_;
}

sub info    { _verbose(1, @_); }
sub verbose { _verbose(2, @_); }
sub debug   { _verbose(3, @_); }

if (@ARGV > 1) {
        print STDERR "Excess arguments\n";
        die($USAGE);
} elsif (@ARGV < 1) {
        print STDERR "No module supplied\n";
        die($USAGE);
} elsif ($cert && $cert_dir) {
        print STDERR "Please specify either --certificate or --cert-dir, not 
both.\n";
        die($USAGE);
}
my $module_name = shift(@ARGV);
if (!$cert && !$cert_dir) {
        $cert_dir = "/etc/uefi/certs";
        verbose("Using default certificate directory $cert_dir\n");
}
my @certs;
if ($cert) {
        push(@certs, $cert);
} else {
        my $dh;
        if (!opendir($dh, $cert_dir)) {
                print STDERR "$cert_dir: $!\n";
                exit(2);
        }
        while (my $entry = readdir($dh)) {
                next if $entry =~ /^\./;
                next if !-f "$cert_dir/$entry";
                push(@certs, "$cert_dir/$entry");
        }
        closedir($dh);
        if (!@certs) {
                print STDERR "No certificates found in $cert_dir\n";
                exit(2);
        }
}


#
# 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;
}

sub openssl_pipe($$) {
        my ($input, $cmd) = @_;
        my ($pid, $res);

        $pid = open2(*read_from, *write_to, $cmd) || die $cmd;
        binmode write_to;
        if (defined($input) && $input ne "") {
                print write_to $input || die "$cmd: $!";
        }
        close(write_to) || die "$cmd: $!";

        binmode read_from;
        read(read_from, $res, 4096) || die "$cmd: $!";
        close(read_from) || die "$cmd: $!";
        waitpid($pid, 0) || die;
        die "$cmd died: $?" if ($? >> 8);
        return $res;
}

sub cert_matches {
        my ($cert, $subject_key_id, $subject_name) = @_;

        open(my $pipe, '-|', "openssl", "x509", "-noout", "-text",
                "-inform", "DER", "-in", $cert) or die "openssl x509: $!\n";
        my $found = 0;
        my $found_key_id;
        while (<$pipe>) {
                chomp;
                if (/^\s*X509v3 Subject Key Identifier:/) {
                        $found = 1;
                        next;
                }
                if ($found) {
                        s/[\s:]*//g;
                        $found_key_id = pack("H*", $_);
                        last;
                }
        }
        if (!$found_key_id) {
                print STDERR "Warning: no subject key identifier in $cert\n";
                return 0;
        }
        debug("$cert has hey id " . unpack("H*", $found_key_id));
        # FIXME: Also check subject_name
        return ($found_key_id eq $subject_key_id);
}

my $module = read_file($module_name);
my $module_len = length($module);
my $magic_number = "~Module signature appended~\n";
my $magic_len = length($magic_number);
my $info_len = 12;

sub eat
{
        my $length = shift;
        if ($module_len < $length) {
                die "Module size too short\n";
        }
        my $res = substr($module, -$length);
        $module = substr($module, 0, $module_len - $length);
        $module_len -= $length;
        return $res;
}

if (eat($magic_len) ne $magic_number) {
        print "$module_name: module not signed\n";
        exit(3);
}
my $info = eat($info_len);
my ($algo, $hash, $id_type, $name_len, $key_len, $sig_len) =
        unpack("CCCCCxxxN", $info);
my $signature = eat($sig_len);
if (unpack("n", $signature) != $sig_len - 2) {
        die "Invalid signature format\n";
}
$signature = substr($signature, 2);
my $key_id = eat($key_len);
my $name = eat($name_len);

if ($algo != 1) {
        die "Unsupported signature algorithm\n";
}
#
# Digest the data
#
my ($prologue, $dgst);
if ($hash == 2) {
    $prologue = pack("C*",
                     0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
                     0x2B, 0x0E, 0x03, 0x02, 0x1A,
                     0x05, 0x00, 0x04, 0x14);
    $dgst = "sha1";
} elsif ($hash == 7) {
    $prologue = pack("C*",
                     0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
                     0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
                     0x05, 0x00, 0x04, 0x1C);
    $dgst = "sha224";
} elsif ($hash == 4) {
    $prologue = pack("C*",
                     0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
                     0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
                     0x05, 0x00, 0x04, 0x20);
    $dgst = "sha256";
} elsif ($hash == 5) {
    $prologue = pack("C*",
                     0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
                     0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
                     0x05, 0x00, 0x04, 0x30);
    $dgst = "sha384";
} elsif ($hash == 6) {
    $prologue = pack("C*",
                     0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
                     0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
                     0x05, 0x00, 0x04, 0x40);
    $dgst = "sha512";
} else {
    die "Unsupported hash algorithm\n";
}

verbose("Signed by: $name\n");
verbose("Key id: " . unpack("H*", $key_id) . "\n");
verbose("Hash algorithm: $dgst\n");

my $digest = openssl_pipe($module, "openssl dgst -$dgst -binary");
my $original_message = $prologue . $digest;

for my $cert (sort @certs) {
        debug("Trying $cert\n");
        next unless cert_matches($cert, $key_id, $name);
        verbose("Found certificate $cert\n");

        my ($fh, $filename) = tempfile() or die "Cannot create temporary file: 
$!\n";
        my $pubkey = openssl_pipe("",
                "openssl x509 -noout -in $cert -inform DER -pubkey");
        print $fh $pubkey;
        close($fh);
        my $verified_message = openssl_pipe($signature,
                "openssl rsautl -verify -inkey $filename -keyform PEM -pubin");
        unlink($filename);
        if ($original_message ne $verified_message) {
                print "$module_name: bad signature\n";
                exit(1);
        }
        print "$module_name: good signature\n";
        exit(0);
}
print "certificate not found\n";
exit(2);
++++++ weak-modules2 ++++++
--- /var/tmp/diff_new_pack.iPYbr2/_old  2014-03-18 13:38:12.000000000 +0100
+++ /var/tmp/diff_new_pack.iPYbr2/_new  2014-03-18 13:38:12.000000000 +0100
@@ -287,6 +287,16 @@
     echo "$old_kmp"
 }
 
+# write GZIP / XZ uncompressed file to stdout
+uncomp() {
+    local file=$1
+
+    if gzip -cd "$file" 2>/dev/null; then
+       return
+    fi
+    xz -cd "$file"
+}
+
 # test if mkinitrd is needed for $krel. This should be decided by initrd itself
 # actually
 # stdin - list of changed modules ("_kernel_" for the whole kernel)
@@ -317,7 +327,7 @@
     if [ ! -e /boot/initrd-$krel ]; then
        return 0
     fi
-    local initrd_basenames=($( (gzip -cd /boot/initrd-$krel | cpio -t --quiet 
| filter_basenames; INITRD_MODULES=; . /etc/sysconfig/kernel &>/dev/null; 
printf '%s.ko\n' $INITRD_MODULES) | sort -u))
+    local initrd_basenames=($( (uncomp /boot/initrd-$krel | cpio -t --quiet | 
filter_basenames; INITRD_MODULES=; . /etc/sysconfig/kernel &>/dev/null; printf 
'%s.ko\n' $INITRD_MODULES) | sort -u))
     local i=($(join <(printf '%s\n' "${changed_basenames[@]}") \
                    <(printf '%s\n' "${initrd_basenames[@]}") ))
     log "changed initrd modules for kernel $krel: ${i[@]-none}"

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to