Hello community,
here is the log from the commit of package pesign-obs-integration for
openSUSE:Factory checked in at 2019-02-06 14:05:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pesign-obs-integration (Old)
and /work/SRC/openSUSE:Factory/.pesign-obs-integration.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pesign-obs-integration"
Wed Feb 6 14:05:12 2019 rev:29 rq:670420 version:10.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/pesign-obs-integration/pesign-obs-integration.changes
2018-11-06 15:32:03.655914179 +0100
+++
/work/SRC/openSUSE:Factory/.pesign-obs-integration.new.28833/pesign-obs-integration.changes
2019-02-06 14:05:13.786672941 +0100
@@ -1,0 +2,5 @@
+Tue Dec 11 10:19:44 UTC 2018 - [email protected]
+- Version 10.1
+- Add modsign-verify for the signature verification (bsc#1118953)
+
+-------------------------------------------------------------------
Old:
----
pesign-obs-integration_10.0.dsc
pesign-obs-integration_10.0.tar.gz
New:
----
pesign-obs-integration_10.1.dsc
pesign-obs-integration_10.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ pesign-obs-integration.spec ++++++
--- /var/tmp/diff_new_pack.2MgIJg/_old 2019-02-06 14:05:17.630672257 +0100
+++ /var/tmp/diff_new_pack.2MgIJg/_new 2019-02-06 14:05:17.634672257 +0100
@@ -21,7 +21,7 @@
Summary: Macros and scripts to sign the kernel and bootloader
License: GPL-2.0-only
Group: Development/Tools/Other
-Version: 10.0
+Version: 10.1
Release: 0
Requires: fipscheck
Requires: mozilla-nss-tools
@@ -33,6 +33,8 @@
Url: http://en.opensuse.org/openSUSE:UEFI_Image_File_Sign_Tools
Source: %{name}_%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-build
+# suse-module-tools <= 15.0.10 contains modsign-verify
+Requires: suse-module-tools >= 15.0.10
%description
This package provides scripts and rpm macros to automate signing of the
@@ -55,6 +57,7 @@
install -m644 pesign-repackage.spec.in %buildroot/usr/lib/rpm/pesign
mkdir -p %buildroot/usr/bin
install modsign-repackage %buildroot/usr/bin/
+install -pm 755 modsign-verify %buildroot/usr/bin/
if test -e _projectcert.crt; then
openssl x509 -inform PEM -in _projectcert.crt \
-outform DER -out %buildroot/usr/lib/rpm/pesign/pesign-cert.x509
@@ -67,6 +70,7 @@
%license COPYING
%doc README
/usr/bin/modsign-repackage
+/usr/bin/modsign-verify
/usr/lib/rpm/*
%changelog
++++++ pesign-obs-integration_10.0.dsc -> pesign-obs-integration_10.1.dsc ++++++
---
/work/SRC/openSUSE:Factory/pesign-obs-integration/pesign-obs-integration_10.0.dsc
2018-11-06 15:32:29.987874261 +0100
+++
/work/SRC/openSUSE:Factory/.pesign-obs-integration.new.28833/pesign-obs-integration_10.1.dsc
2019-02-06 14:05:15.478672641 +0100
@@ -2,7 +2,7 @@
Source: pesign-obs-integration
Binary: pesign-obs-integration, dh-signobs
Architecture: all
-Version: 10.0
+Version: 10.1
Maintainer: Michal Marek <[email protected]>
Standards-Version: 3.9.8
Build-Depends: debhelper (>= 7), openssl, shellcheck
@@ -10,8 +10,8 @@
dh-signobs deb devel optional arch=all
pesign-obs-integration deb devel optional arch=all
Checksums-Sha1:
- 8bc79be8053ea5947a5eafeeb5eb066334e472e6 30698
pesign-obs-integration_10.0.tar.gz
+ 201030b4dc2ca4a8aac813874dff5c70dbaa7b6a 34917
pesign-obs-integration_10.1.tar.gz
Checksums-Sha256:
- da53c7b243c68c147229e11948016d5bd66bebf418b20e985f9bd41e9aaeac78 30698
pesign-obs-integration_10.0.tar.gz
+ aa851dbdad6c83cee002fbe7f4e8b3f72e556da361cbf3843c5bcf479eaeec1e 34917
pesign-obs-integration_10.1.tar.gz
Files:
- cffbd276aed9e05cb59e3477d44eb604 30698 pesign-obs-integration_10.0.tar.gz
+ c1866a4c83c00569df115c04f6b9e919 34917 pesign-obs-integration_10.1.tar.gz
++++++ pesign-obs-integration_10.0.tar.gz -> pesign-obs-integration_10.1.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pesign-obs-integration/debian/changelog
new/pesign-obs-integration/debian/changelog
--- old/pesign-obs-integration/debian/changelog 2018-10-31 03:05:11.000000000
+0100
+++ new/pesign-obs-integration/debian/changelog 2018-12-12 09:08:55.000000000
+0100
@@ -1,3 +1,9 @@
+pesign-obs-integration (10.1) unstable; urgency=medium
+
+ * Update to 10.1
+
+ -- Gary Lin <[email protected]> Tue, 11 Dec 2018 18:31:01 +0800
+
pesign-obs-integration (10.0) unstable; urgency=medium
* Initial Debian packaging.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pesign-obs-integration/modsign-verify
new/pesign-obs-integration/modsign-verify
--- old/pesign-obs-integration/modsign-verify 1970-01-01 01:00:00.000000000
+0100
+++ new/pesign-obs-integration/modsign-verify 2018-12-12 09:08:55.000000000
+0100
@@ -0,0 +1,620 @@
+#!/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);
+use bigint;
+
+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);
+ }
+}
+
+###############################################################################
+## ASN.1 code copied from kernel-sign-file
+###############################################################################
+
+my $x509;
+
+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;
+
+sub encode_asn1_oid($)
+{
+ my ($o1, $o2, @oid) = split(/\./, $_[0]);
+ my @bytes;
+
+ push @bytes, 40*$o1 + $o2;
+
+ while (scalar(@oid) > 0) {
+ my $c = $oid[0];
+ shift @oid;
+ my @base128 = ();
+
+ push @base128, ($c % 128);
+ while ($c > 128) {
+ $c /= 128;
+ push @base128, (($c % 128) | 128);
+ };
+ push @bytes, reverse(@base128);
+ }
+ return pack("C*", @bytes);
+}
+
+my %OIDs = (
+ # joint-iso-itu-t(2) ds(5) attributeType(4)
+ encode_asn1_oid("2.5.4.3") => "commonName",
+ encode_asn1_oid("2.5.4.6") => "countryName",
+ encode_asn1_oid("2.5.4.10") => "organizationName",
+ encode_asn1_oid("2.5.4.11") => "organizationUnitName",
+ # iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
+ encode_asn1_oid("1.2.840.113549.1.1.1") => "rsaEncryption",
+ encode_asn1_oid("1.2.840.113549.1.1.5") => "sha1WithRSAEncryption",
+ encode_asn1_oid("1.2.840.113549.1.9.1") => "emailAddress",
+ # joint-iso-itu-t(2) ds(5) certificateExtension(29)
+ encode_asn1_oid("2.5.29.35") => "authorityKeyIdentifier",
+ encode_asn1_oid("2.5.29.14") => "subjectKeyIdentifier",
+ encode_asn1_oid("2.5.29.19") => "basicConstraints",
+ # iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)
+ encode_asn1_oid("1.2.840.113549.1.7.1") => "pkcs7-data",
+ encode_asn1_oid("1.2.840.113549.1.7.2") => "pkcs7-signed-data",
+);
+
+###############################################################################
+#
+# Extract an ASN.1 element from a string and return information about it.
+#
+###############################################################################
+my $ASN1_EXTRACT_MSG = "asn1_extract";
+sub asn1_extract($$@)
+{
+ my ($cursor, $expected_tag, $optional) = @_;
+
+ return [ -1 ]
+ if ($cursor->[1] == 0 && $optional);
+
+ die $ASN1_EXTRACT_MSG, ": ", $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 $ASN1_EXTRACT_MSG, ": ", $cursor->[0],
+ ": ASN.1 unexpected tag (", $tag, " not ", $expected_tag, ")\n";
+ }
+
+ $cursor->[0] += 2;
+ $cursor->[1] -= 2;
+
+ die $ASN1_EXTRACT_MSG, ": ", $cursor->[0], ": ASN.1 long tag\n"
+ if (($tag & 0x1f) == 0x1f);
+ die $ASN1_EXTRACT_MSG, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
+ if ($len == 0x80);
+
+ if ($len > 0x80) {
+ my $l = $len - 0x80;
+ die $ASN1_EXTRACT_MSG, ": ", $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 $ASN1_EXTRACT_MSG, ": ", $cursor->[0],
+ ": ASN.1 element too long (", $l, ")\n";
+ }
+
+ $cursor->[0] += $l;
+ $cursor->[1] -= $l;
+ }
+
+ die $ASN1_EXTRACT_MSG, ": ", $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);
+}
+
+
+# 2's complement representation of ASN1_INTEGER
+sub asn1_int($)
+{
+ my ($p) = @_;
+ my @bytes = unpack("C*", $p);
+ my $byte;
+ my $neg = 0;
+ my $v = 0;
+
+ if (($bytes[0] & 0x80) != 0) {
+ $neg = 1;
+ $bytes[0] &= ~0x80;
+ }
+ foreach $byte (@bytes) {
+ $v <<= 8;
+ $v += $byte;
+ }
+ if ($neg) {
+ $v -= (2 ** (8 * scalar(@bytes) - 1));
+ };
+ return $v;
+}
+
+sub asn1_pack($@)
+{
+ my ($tag, @data) = @_;
+ my $ret = pack("C", $tag);
+ my $data = join('', @data);
+ my $l = length($data);
+ return pack("CC", $tag, $l) . $data if $l < 127;
+ my $ll = $l >> 8 ? $l >> 16 ? $l >> 24 ? 4 : 3 : 2 : 1;
+ return pack("CCa*", $tag, $ll | 0x80, substr(pack("N", $l), -$ll)) .
$data;
+}
+
+my %hash_algos = (
+ # iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2)
+ 2 => ["sha1", 160/8, encode_asn1_oid("1.3.14.3.2.26")],
+ # joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
nistAlgorithm(4) hashAlgs(2)
+ 4 => ["sha256", 256/8, encode_asn1_oid("2.16.840.1.101.3.4.2.1")],
+ 5 => ["sha384", 384/8, encode_asn1_oid("2.16.840.1.101.3.4.2.2")],
+ 6 => ["sha512", 512/8, encode_asn1_oid("2.16.840.1.101.3.4.2.3")],
+ 7 => ["sha224", 224/8, encode_asn1_oid("2.16.840.1.101.3.4.2.4")],
+);
+
+sub hash_prologue($$)
+{
+ my ($hash_len, $algo) = @_;
+ my $obj = asn1_pack($UNIV | $OBJ_ID, $algo);
+ my $seq = asn1_pack($UNIV | $CONS | $SEQUENCE, $obj . pack("CC", $NULL,
0));
+ my $tail = pack("CC", $OCTET_STRING, $hash_len);
+ my $head = pack("CC", $UNIV | $CONS | $SEQUENCE,
+ length($seq) + length($tail) + $hash_len);
+ return $head . $seq . $tail;
+}
+
+sub find_hash_algo_by_oid($)
+{
+ my ($oid) = @_;
+ my $key;
+ my $k;
+
+ SEARCH:
+ foreach $k (keys %hash_algos) {
+ my ($_h, $_n, $_a) = @{$hash_algos{$k}};
+ if ($oid eq $_a) {
+ $key = $k;
+ last SEARCH;
+ }
+ }
+ die "$module_name: unsupported hash algorithm OID=".sprintf("%v02x", $oid)
+ if !defined($key);
+ return $key;
+}
+
+###############################################################################
+#
+# Roughly parse the X.509 certificate
+#
+###############################################################################
+sub parse_x509_dn(@)
+{
+ my ($parent, $cursor) = @_;
+ my ($offset, $len, $data) = @$cursor;
+ my %result = ();
+
+ while ($cursor->[1]> 0) {
+ my $_set = asn1_extract($cursor, $UNIV | $CONS | $SET);
+ my $_seq = asn1_extract($_set->[1],
+ $UNIV | $CONS | $SEQUENCE);
+ my $_oid = asn1_extract($_seq->[1], $UNIV | $OBJ_ID);
+ my $oid = asn1_retrieve($_oid->[1]);
+ if (defined($OIDs{$oid})) {
+ my $key = "$parent/$OIDs{$oid}";
+ my $_x = asn1_extract($_seq->[1], -1);
+
+ # debug "found $key at $_seq->[1][0]\n";
+ $result{$key} = asn1_retrieve($_x->[1]);
+ };
+ }
+ return \%result;
+}
+
+sub parse_x509_der($)
+{
+ my ($bytes) = @_;
+
+ my $cursor = [ 0, length($bytes), \$bytes ];
+
+ 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 $issuer_dn = parse_x509_dn("issuer", $issuer->[1]);
+ 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 $pubkey = asn1_pack($UNIV | $CONS | $SEQUENCE,
+ asn1_retrieve($key->[1]));
+
+ 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);
+ }
+ }
+ }
+ my %result = (
+ "subject_key_id" => asn1_retrieve($subject_key_id->[1]),
+ "serial" => asn1_int(asn1_retrieve($serial_number->[1])),
+ "pubkey" => $pubkey,
+ %$issuer_dn,
+ );
+ return \%result;
+}
+
+#
+# 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 || return "";
+ }
+ close(write_to) || die "$cmd: $!";
+
+ binmode read_from;
+ read(read_from, $res, 4096) || return "";
+ close(read_from) || return "";
+ waitpid($pid, 0) || die;
+ return "" if ($? >> 8);
+ return $res;
+}
+
+sub cert_matches($$$$) {
+ my ($cert, $subject_key_id, $issuer, $serial) = @_;
+ my $bytes = read_file($cert);
+
+ $ASN1_EXTRACT_MSG = $cert;
+ my $cert_props = parse_x509_der($bytes);
+
+ if (defined($subject_key_id)) {
+ debug("$cert has key id " .
+ unpack("H*", $cert_props->{"subject_key_id"}) . "\n");
+ if ($cert_props->{"subject_key_id"} eq $subject_key_id) {
+ return $cert_props;
+ } else {
+ return 0;
+ }
+ }
+
+ die "missing input data in cert_matches()"
+ if (!defined($issuer) || !defined($serial));
+
+ if (!defined($cert_props->{"serial"}) ||
+ $cert_props->{"serial"} ne $serial) {
+ debug "$cert: serial number mismatch: $serial != ".
$cert_props->{"serial"}."\n";
+ return 0;
+ }
+ foreach my $k (keys(%$issuer)) {
+ if (!defined($cert_props->{$k}) ||
+ $issuer->{$k} ne $cert_props->{$k}) {
+ debug "$cert: $k does not match signature\n";
+ return 0;
+ }
+ }
+ return $cert_props;
+}
+
+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);
+# cert is identified either by subject key id, or by issuer DN + serial no
+my $issuer_dn;
+my $serial;
+my $key_id;
+my $name;
+if ($id_type == 1) {
+
+ if (unpack("n", $signature) != $sig_len - 2) {
+ die "Invalid signature format\n";
+ }
+ $signature = substr($signature, 2);
+ $key_id = eat($key_len);
+ $name = eat($name_len);
+
+ if ($algo != 1) {
+ die "Unsupported signature algorithm\n";
+ }
+} elsif ($id_type == 2) {
+ # PKCS7 signature
+ $ASN1_EXTRACT_MSG = $module_name;
+ my $cursor = [ 0, length($signature), \$signature ];
+ my $seq0 = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
+ my $signed_data = asn1_extract($seq0->[1], $UNIV | $OBJ_ID);
+ die "$module_name: no PKCS#7 signed_data structure\n"
+ if $OIDs{asn1_retrieve($signed_data->[1])} !~ /^pkcs7-signed-data$/;
+
+ my $ctx1 = asn1_extract($seq0->[1], $UNIV | $CONT | $CONS);
+ my $seq1 = asn1_extract($ctx1->[1], $UNIV | $CONS | $SEQUENCE);
+ my $sig_version = asn1_extract($seq1->[1], $UNIV | $INTEGER);
+
+ my $digest_algo_seq_set = asn1_extract($seq1->[1],
+ $UNIV | $CONS | $SET);
+ my $digest_algo_seq = asn1_extract($digest_algo_seq_set->[1],
+ $UNIV | $CONS | $SEQUENCE);
+ my $digest_algo = asn1_extract($digest_algo_seq->[1], $UNIV | $OBJ_ID);
+ $hash = find_hash_algo_by_oid(asn1_retrieve($digest_algo->[1]));
+
+ my $seq2 = asn1_extract($seq1->[1], $UNIV | $CONS | $SEQUENCE);
+ my $pkcs7_data = asn1_extract($seq2->[1], $UNIV | $OBJ_ID);
+ die "$module_name: invalid PKCS#7 data"
+ if $OIDs{asn1_retrieve($pkcs7_data->[1])} !~ /^pkcs7-data$/;
+
+ my $si_set = asn1_extract($seq1->[1], $UNIV | $CONS | $SET);
+ my $si_seq = asn1_extract($si_set->[1], $UNIV | $CONS | $SEQUENCE);
+ my $si_version = asn1_extract($si_seq->[1], $UNIV | $INTEGER);
+
+ my $_key_id = asn1_extract($si_seq->[1], -1);
+ my $key_id;
+
+ if ($_key_id->[0] == ($CONT | 0)) {
+ # key_id: kernel-sign-file -k
+ $key_id = asn1_extract($_key_id->[1], $CONT | 0);
+ } else {
+ # issuer / serial
+ my $issuer = asn1_extract($_key_id->[1],
+ $UNIV | $CONS | $SEQUENCE);
+ my $_serial = asn1_extract($_key_id->[1], $UNIV | $INTEGER);
+ $serial = asn1_int(asn1_retrieve($_serial->[1]));
+ $issuer_dn = parse_x509_dn("issuer", $issuer->[1]);
+ if (defined($issuer_dn->{"issuer/commonName"})) {
+ $name = "cn=" . $issuer_dn->{"issuer/commonName"} .
+ ",serial=$serial";
+ }
+ }
+
+ my $seq4 = asn1_extract($si_seq->[1], $UNIV | $CONS | $SEQUENCE);
+ my $digest2 = asn1_extract($seq4->[1], $UNIV | $OBJ_ID);
+ my $hash2 = find_hash_algo_by_oid(asn1_retrieve($digest2->[1]));
+ die "$module_name: inconsistent hash" if $hash2 != $hash;
+
+ my $seq5 = asn1_extract($si_seq->[1], $UNIV | $CONS | $SEQUENCE);
+ my $enc = asn1_extract($seq5->[1], $UNIV | $OBJ_ID);
+ die "$module_name: invalid encryption type".
+ sprintf("%v02x", asn1_retrieve($enc->[1]))
+ if $OIDs{asn1_retrieve($enc->[1])} ne "rsaEncryption";
+ my $_sig = asn1_extract($si_seq->[1], $UNIV | $OCTET_STRING);
+ $signature = asn1_retrieve($_sig->[1]);
+} else {
+ die "unsupported signature type $id_type";
+}
+
+#
+# Digest the data
+#
+my ($prologue, $hash_len, $dgst, $oid);
+die "Unsupported hash algorithm\n" if not exists $hash_algos{$hash};
+
+($dgst, $hash_len, $oid) = @{$hash_algos{$hash}};
+$prologue = hash_prologue($hash_len, $oid);
+
+verbose("Signature type: ", $id_type == 1 ? "legacy" : "pkcs#7", "\n");
+verbose("Signed by: $name\n") if defined ($name);
+verbose("Key id: " . unpack("H*", $key_id) . "\n") if (defined($key_id));
+verbose("Hash algorithm: $dgst\n");
+
+my $digest = openssl_pipe($module, "openssl dgst -$dgst -binary");
+my $original_message = $prologue . $digest;
+
+my $good = 0;
+my $matched = 0;
+for my $cert (sort @certs) {
+ debug("Trying $cert\n");
+
+ my $cert_props = cert_matches($cert, $key_id, $issuer_dn, $serial);
+ next unless $cert_props;
+ verbose("Found matching certificate $cert\n");
+ $matched = $cert;
+
+ my ($fh, $filename) = tempfile() or die "Cannot create temporary file:
$!\n";
+ print $fh $cert_props->{"pubkey"};
+ close($fh);
+ my $verified_message = openssl_pipe($signature,
+ "openssl rsautl -verify -inkey $filename -keyform DER -pubin");
+ unlink($filename);
+ if ($original_message ne $verified_message) {
+ verbose "$module_name: signature validation failed for $cert\n";
+ next;
+ }
+ print "$module_name: good signature\n";
+ $good = 1;
+ exit(0);
+}
+if (!$matched) {
+ print "certificate not found\n";
+ exit(2);
+} else {
+ print "$module_name: bad signature\n";
+ exit(1);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pesign-obs-integration/pesign-obs-integration.changes
new/pesign-obs-integration/pesign-obs-integration.changes
--- old/pesign-obs-integration/pesign-obs-integration.changes 2018-10-31
03:05:11.000000000 +0100
+++ new/pesign-obs-integration/pesign-obs-integration.changes 2018-12-12
09:08:55.000000000 +0100
@@ -1,4 +1,25 @@
-------------------------------------------------------------------
+Tue Dec 11 10:19:44 UTC 2018 - [email protected]
+- Version 10.1
+- Add modsign-verify for the signature verification (bsc#1118953)
+
+-------------------------------------------------------------------
+Wed Oct 31 10:11:48 UTC 2018 - [email protected]
+
+- rpm: properly forward dep flags
+- Fix new Lintian Error from Debian 10
+
+-------------------------------------------------------------------
+Tue Jun 12 03:30:33 UTC 2018 - [email protected]
+
+- debhelper: restrict wildcard package unpacking
+
+-------------------------------------------------------------------
+Mon Jun 11 03:17:37 UTC 2018 - [email protected]
+
+- debhelper: fix conffiles corner case
+
+-------------------------------------------------------------------
Fri Jun 8 03:08:29 UTC 2018 - [email protected]
- Remove the unstable source url
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pesign-obs-integration/pesign-obs-integration.spec
new/pesign-obs-integration/pesign-obs-integration.spec
--- old/pesign-obs-integration/pesign-obs-integration.spec 2018-10-31
03:05:11.000000000 +0100
+++ new/pesign-obs-integration/pesign-obs-integration.spec 2018-12-12
09:08:55.000000000 +0100
@@ -12,7 +12,7 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
# needssslcertforbuild
@@ -21,7 +21,7 @@
Summary: Macros and scripts to sign the kernel and bootloader
License: GPL-2.0-only
Group: Development/Tools/Other
-Version: 10.0
+Version: 10.1
Release: 0
Requires: fipscheck
Requires: mozilla-nss-tools
@@ -32,7 +32,9 @@
BuildRequires: openssl
Url: http://en.opensuse.org/openSUSE:UEFI_Image_File_Sign_Tools
Source: %{name}_%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-build
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+# suse-module-tools <= 15.0.10 contains modsign-verify
+Requires: suse-module-tools >= 15.0.10
%description
This package provides scripts and rpm macros to automate signing of the
@@ -55,6 +57,7 @@
install -m644 pesign-repackage.spec.in %buildroot/usr/lib/rpm/pesign
mkdir -p %buildroot/usr/bin
install modsign-repackage %buildroot/usr/bin/
+install -pm 755 modsign-verify %buildroot/usr/bin/
if test -e _projectcert.crt; then
openssl x509 -inform PEM -in _projectcert.crt \
-outform DER -out %buildroot/usr/lib/rpm/pesign/pesign-cert.x509
@@ -67,6 +70,7 @@
%license COPYING
%doc README
/usr/bin/modsign-repackage
+/usr/bin/modsign-verify
/usr/lib/rpm/*
%changelog