forked from pool/pesign-obs-integration
Accepting request 178980 from home:michal-m:branches:Base:System
- Put debuginfo packages to %_topdir/OTHER (bnc#824971). - Version 10 - Add modsign-repackage tool to repackage RPMs outside the buildservice OBS-URL: https://build.opensuse.org/request/show/178980 OBS-URL: https://build.opensuse.org/package/show/Base:System/pesign-obs-integration?expand=0&rev=18
This commit is contained in:
parent
0952d005e5
commit
c9543f88db
@ -68,6 +68,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
|
||||
@ -358,6 +375,26 @@ if ($dgst eq "sha1") {
|
||||
die "Unknown hash algorithm: $dgst\n";
|
||||
}
|
||||
|
||||
my $unsigned_module = read_file($module);
|
||||
|
||||
my $magic_number = $sign_fw ?
|
||||
"~Linux firmware signature~\n" :
|
||||
"~Module signature appended~\n";
|
||||
my $magic_len = length($magic_number);
|
||||
my $info_len = 12;
|
||||
|
||||
# Truncate existing signarure, if any
|
||||
if (!$sign_fw && 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);
|
||||
@ -365,43 +402,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 = $sign_fw ?
|
||||
"~Linux firmware signature~\n" :
|
||||
"~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 $mode_name: ", length($unsigned_module), "\n";
|
||||
|
142
modsign-repackage
Normal file
142
modsign-repackage
Normal file
@ -0,0 +1,142 @@
|
||||
#!/bin/bash
|
||||
# Script to sign kernel modules and create new RPM packages with these
|
||||
# modules. Uses pesign-gen-repackage-spec for the repackaging.
|
||||
#
|
||||
# Copyright (c) 2013 SUSE Linux Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
USAGE="$0 --key <private key> --certificate <x509 cert> rpm ..."
|
||||
|
||||
options=`getopt -o hk:c: --long help,key:,certificate: -- "$@"`
|
||||
if test $? -ne 0; then
|
||||
echo "$USAGE" >&2
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "$options"
|
||||
key=
|
||||
cert=
|
||||
while :; do
|
||||
case "$1" in
|
||||
-k|--key)
|
||||
key=$2
|
||||
shift 2
|
||||
;;
|
||||
-c|--certificate)
|
||||
cert=$2
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
echo "$USAGE"
|
||||
exit
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
esac
|
||||
done
|
||||
if test -z "$key" -o -z "$cert"; then
|
||||
echo "$0: The --key and --certificate options are mandatory" >&2
|
||||
echo "$USAGE" >&2
|
||||
exit 1
|
||||
fi
|
||||
if test "$#" -eq 0; then
|
||||
echo "$0: No packages specified" >&2
|
||||
echo "$USAGE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
workdir="$PWD/rpm-files.$$"
|
||||
buildroot="$workdir/buildroot"
|
||||
rpmdir=RPMS
|
||||
srpmdir=SRPMS
|
||||
disturl=
|
||||
rpms=()
|
||||
rm -rf "$workdir"
|
||||
mkdir "$workdir" || exit
|
||||
mkdir -p "$rpmdir" "$srpmdir" || exit
|
||||
mkdir "$buildroot"
|
||||
echo "Unpacking original RPMs..."
|
||||
for rpm; do
|
||||
# XXX: Use a common script in pesign-repackage.spec.in and here
|
||||
case "$rpm" in
|
||||
*.src.rpm | *.nosrc.rpm)
|
||||
cp "$rpm" "$srpmdir/"
|
||||
continue
|
||||
;;
|
||||
# Do not repackage debuginfo packages (bnc#806637)
|
||||
*-debuginfo-*.rpm | *-debugsource-*.rpm)
|
||||
dir="$rpmdir/$(rpm -qp --qf '%{arch}' "$rpm")"
|
||||
mkdir -p "$dir"
|
||||
cp "$rpm" "$dir"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
# do not repackage baselibs packages
|
||||
# FIXME: needs more generic test (if architecture has different
|
||||
# bitness => skip)
|
||||
case "$(rpm -qp --qf '%{name}/%{arch}' "$rpm")" in
|
||||
*-32bit/x86_64 | *-32bit/s390x | *-32bit/ppc64 | \
|
||||
*-64bit/ppc | *-x86/ia64)
|
||||
mkdir -p "$rpmdir/$(rpm -qp --qf '%{arch}')/"
|
||||
cp "$rpm" "$_"
|
||||
continue
|
||||
esac
|
||||
rpm2cpio "$rpm" | (cd "$buildroot"; cpio -idm --quiet) || exit
|
||||
d=$(rpm -qp --qf '%{disturl}' "$rpm")
|
||||
if test -z "$disturl"; then
|
||||
disturl=$d
|
||||
fi
|
||||
if test "$disturl" != "$d"; then
|
||||
echo "Error: packages have different disturl: $d vs $disturl"
|
||||
exit 1
|
||||
fi
|
||||
rpms=("${rpms[@]}" "$rpm")
|
||||
done
|
||||
set -e
|
||||
echo "Signing kernel modules..."
|
||||
for module in $(find "$buildroot" -type f -name '*.ko'); do
|
||||
/usr/lib/rpm/pesign/kernel-sign-file \
|
||||
sha256 "$key" "$cert" "$module"
|
||||
done
|
||||
# Add the certificate
|
||||
mkdir -p "$buildroot/etc/uefi/certs"
|
||||
h=$(openssl x509 -inform DER -fingerprint -noout -in "$cert")
|
||||
filename=/etc/uefi/certs/$(echo "$h" | \
|
||||
sed -rn 's/^SHA1 Fingerprint=//; T; s/://g; s/(.{8}).*/\1/p').crt
|
||||
cp "$cert" "$buildroot/$filename"
|
||||
|
||||
echo "Generating new specfile..."
|
||||
if ! test -e /usr/lib/rpm/kernel-cert-subpackage; then
|
||||
echo "/usr/lib/rpm/kernel-cert-subpackage missing" >&2
|
||||
echo "please install the kernel-source package" >&2
|
||||
exit 1
|
||||
fi
|
||||
/usr/lib/rpm/pesign/pesign-gen-repackage-spec \
|
||||
--cert-subpackage=/usr/lib/rpm/kernel-cert-subpackage \
|
||||
--directory="$buildroot" --output="$workdir" "${rpms[@]}"
|
||||
echo "Running rpmbuild..."
|
||||
rpmbuild --define "buildroot $buildroot" --define "disturl $disturl" \
|
||||
--define "_builddir $workdir" \
|
||||
--define "_suse_insert_debug_package %{nil}" \
|
||||
--define "_rpmdir $rpmdir" \
|
||||
-bb "$workdir/repackage.spec" >"$workdir/log" 2>&1
|
||||
grep 'RPMS/.*\.rpm$' "$workdir/log"
|
||||
echo "Cleaning up $workdir..."
|
||||
rm -r "$workdir"
|
||||
echo "Done."
|
||||
exit 0
|
||||
|
||||
|
@ -28,6 +28,8 @@ use Fcntl qw(:mode :seek);
|
||||
|
||||
my $directory;
|
||||
my $output = ".";
|
||||
my $cert_subpackage;
|
||||
my $kmp_basename;
|
||||
my @rpms;
|
||||
|
||||
$ENV{LC_ALL} = "en_US.UTF-8";
|
||||
@ -36,6 +38,7 @@ GetOptions(
|
||||
"help|h" => sub { print $USAGE; exit; },
|
||||
"directory|d=s" => \$directory,
|
||||
"output|o=s" => \$output,
|
||||
"cert-subpackage|c=s" => \$cert_subpackage,
|
||||
) or die $USAGE;
|
||||
@rpms = @ARGV;
|
||||
if (!@rpms) {
|
||||
@ -155,7 +158,7 @@ sub load_package {
|
||||
my @files;
|
||||
my @list = query_array($rpm, qw(filenames fileflags filemodes fileusername filegroupname filesizes filemtimes filelinktos));
|
||||
for my $file (@list) {
|
||||
push(@files, {
|
||||
my $new = {
|
||||
name => $file->[0],
|
||||
flags => $file->[1],
|
||||
mode => $file->[2],
|
||||
@ -164,7 +167,11 @@ sub load_package {
|
||||
size => $file->[5],
|
||||
mtime => $file->[6],
|
||||
target => $file->[7],
|
||||
});
|
||||
};
|
||||
push(@files, $new);
|
||||
if ($new->{name} =~ /\.ko$/ && S_ISREG($new->{mode})) {
|
||||
$res{is_kmp} = 1;
|
||||
}
|
||||
}
|
||||
$res{files} = \@files;
|
||||
while (my ($dep, $tag) = each(%dep2tag)) {
|
||||
@ -264,6 +271,9 @@ sub print_package {
|
||||
for my $dep (keys(%dep2tag)) {
|
||||
print_deps($dep, $p->{$dep});
|
||||
}
|
||||
if ($cert_subpackage && $p->{is_kmp}) {
|
||||
print SPEC "Requires: $kmp_basename-ueficert\n";
|
||||
}
|
||||
print SPEC "\%description -n $p->{name}\n";
|
||||
print SPEC quote($p->{description}) . "\n\n";
|
||||
|
||||
@ -424,12 +434,50 @@ if (!exists($packages{$main_name})) {
|
||||
}
|
||||
$packages{$main_name}->{nosource} = $nosrc ? 1 : 0;
|
||||
|
||||
# Find out the basename of <name>-kmp-<flavor>, falling back to the
|
||||
# main package name
|
||||
for my $p (values(%packages)) {
|
||||
next unless $p->{is_kmp};
|
||||
(my $n = $p->{name}) =~ s/-kmp-.*//;
|
||||
$kmp_basename = $n unless $kmp_basename;
|
||||
if ($n ne $kmp_basename) {
|
||||
$kmp_basename = undef;
|
||||
last;
|
||||
}
|
||||
}
|
||||
$kmp_basename = $main_name unless $kmp_basename;
|
||||
|
||||
open(SPEC, '>', "$output/repackage.spec") or die "$output/repackage.spec: $!\n";
|
||||
print_package($packages{$main_name}, 1);
|
||||
for my $p (values(%packages)) {
|
||||
next if $p->{name} eq $main_name;
|
||||
print_package($p, 0);
|
||||
}
|
||||
if ($cert_subpackage) {
|
||||
my $certdir = "/etc/uefi/certs";
|
||||
my $certs = "";
|
||||
if (-d "$directory/$certdir") {
|
||||
opendir(my $dh, "$directory/$certdir") or die "$directory/$certdir";
|
||||
while (my $cert = readdir($dh)) {
|
||||
next if $cert =~ /^\.\.?$/;
|
||||
if ($cert !~ /\.crt$/) {
|
||||
print STDERR "warning: Ignoring $directory/$certdir/$cert (no .crt suffix)\n";
|
||||
next;
|
||||
}
|
||||
$certs .= " $certdir/$cert";
|
||||
}
|
||||
}
|
||||
if (!$certs) {
|
||||
print STDERR "warning: --cert-subpackage specified, but no certs found in $directory/$certdir\n";
|
||||
}
|
||||
local $/ = undef;
|
||||
open(my $fh, '<', $cert_subpackage) or die "$cert_subpackage: $!\n";
|
||||
my $template = <$fh>;
|
||||
close($fh);
|
||||
$template =~ s/\%{-n\*}/$kmp_basename/g;
|
||||
$template =~ s/\@CERTS\@/$certs/g;
|
||||
print SPEC $template;
|
||||
}
|
||||
print SPEC "\%changelog\n";
|
||||
print SPEC quote($packages{$main_name}->{changelog});
|
||||
close(SPEC);
|
||||
|
@ -1,3 +1,14 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Jun 14 12:19:47 UTC 2013 - mmarek@suse.cz
|
||||
|
||||
- Put debuginfo packages to %_topdir/OTHER (bnc#824971).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Mar 28 15:55:10 UTC 2013 - mmarek@suse.cz
|
||||
|
||||
- Version 10
|
||||
- Add modsign-repackage tool to repackage RPMs outside the buildservice
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Mar 26 06:19:45 UTC 2013 - glin@suse.com
|
||||
|
||||
|
@ -22,7 +22,7 @@ Name: pesign-obs-integration
|
||||
Summary: Macros and scripts to sign the kernel and bootloader
|
||||
License: GPL-2.0
|
||||
Group: Development/Tools/Other
|
||||
Version: 9.0
|
||||
Version: 10.0
|
||||
Release: 0.<RELEASE15>
|
||||
Requires: mozilla-nss-tools
|
||||
Requires: openssl
|
||||
@ -37,6 +37,7 @@ Source4: brp-99-pesign
|
||||
Source5: COPYING
|
||||
Source6: README
|
||||
Source7: kernel-sign-file
|
||||
Source8: modsign-repackage
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
%description
|
||||
@ -56,6 +57,8 @@ cd %_sourcedir
|
||||
install pesign-gen-repackage-spec kernel-sign-file %buildroot/usr/lib/rpm/pesign
|
||||
install brp-99-pesign %buildroot/usr/lib/rpm/brp-suse.d
|
||||
install -m644 pesign-repackage.spec.in %buildroot/usr/lib/rpm/pesign
|
||||
mkdir -p %buildroot/usr/bin
|
||||
install modsign-repackage %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
|
||||
@ -66,6 +69,7 @@ fi
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc COPYING README
|
||||
/usr/bin/modsign-repackage
|
||||
/usr/lib/rpm/*
|
||||
|
||||
%changelog
|
||||
|
@ -54,9 +54,8 @@ for rpm in %_sourcedir/*.rpm; do
|
||||
;;
|
||||
# Do not repackage debuginfo packages (bnc#806637)
|
||||
*-debuginfo-*.rpm | *-debugsource-*.rpm)
|
||||
dir=%_rpmdir/$(rpm -qp --qf '%%{arch}' "$rpm")
|
||||
mkdir -p "$dir"
|
||||
cp "$rpm" "$dir"
|
||||
mkdir -p "%_topdir/OTHER"
|
||||
cp "$rpm" "$_"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
Loading…
x
Reference in New Issue
Block a user