Skip to content

Commit

Permalink
[backend] aggregate signing: reuse old rpms if the old signatures wer…
Browse files Browse the repository at this point in the history
…e done by the same issuer

We do this to work around rpm --delsign having a bug that makes it
modify the lead.

It also saves some disk space because hard links are saved this way.
  • Loading branch information
mlschroe committed Aug 7, 2020
1 parent 907d54b commit f4aea07
Showing 1 changed file with 35 additions and 9 deletions.
44 changes: 35 additions & 9 deletions src/backend/bs_signer
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,19 @@ sub getsignkey {
return ($algo, $signkey, $pubkey, $cert);
}

sub getsigdata {
my ($rpm) = @_;
my $sigdata;
eval {
my %res = Build::Rpm::rpmq($rpm, 'SIGTAG_GPG', 'SIGTAG_PGP');
my $sig = $res{'SIGTAG_PGP'} || $res{'SIGTAG_GPG'};
$sig = $sig->[0] if $sig;
$sigdata = BSPGP::pk2sigdata($sig) if $sig;
};
warn("getsigdata $rpm: $@") if $@;
return $sigdata ? $sigdata : {};
}

sub signjob {
my ($job, $arch) = @_;

Expand Down Expand Up @@ -530,21 +543,20 @@ sub signjob {
rsasign("$jobdir/$signfile", $jobstatus, @signargs) if $followupfile;
next;
}
my $signtime;
my $signfilefinal;
my ($signtime, $signissuer);
if ($info->{'file'} eq '_aggregate' && ($signfile =~ /\.d?rpm$/)) {
# newer rpm versions sometimes do in-place signature replacement,
# so create a copy first
# (we should add a delsign option to our sign utility...)
BSUtil::cp("$jobdir/$signfile", "$jobdir/.$signfile", "$jobdir/$signfile");
BSUtil::cp("$jobdir/$signfile", "$jobdir/.$signfile");
$signfilefinal = $signfile;
$signfile = ".$signfile";
# special aggregate handling: remove old sigs
# but get old sig time first
eval {
my %res = Build::Rpm::rpmq("$jobdir/$signfile", 'SIGTAG_GPG', 'SIGTAG_PGP');
my $sig = $res{'SIGTAG_PGP'} || $res{'SIGTAG_GPG'};
$sig = $sig->[0] if $sig;
$signtime = BSPGP::pk2signtime($sig) if $sig;
};
warn("get signtime: $@") if $@;
my $sigdata = getsigdata("$jobdir/$signfile");
$signtime = $sigdata->{'signtime'};
$signissuer = $sigdata->{'issuer'};
system('rpm', '--delsign', "$jobdir/$signfile") && warn("delsign $jobdir/$signfile failed: $?\n");
print "using signtime $signtime\n" if $signtime;
}
Expand Down Expand Up @@ -582,8 +594,22 @@ sub signjob {
$jobstatus->{'result'} = 'rebuild';
}
}
unlink("$jobdir/$signfile") if $signfilefinal; # delete tmp file
die("sign $jobdir/$signfile failed\n");
}
if ($signfilefinal) {
# check if the signed rpm has the same issuer
my $sigdata = getsigdata("$jobdir/$signfile");
if ($sigdata->{'issuer'} && $signissuer && $sigdata->{'issuer'} eq $signissuer) {
# old rpm was already signed with the same issuer, reuse
print "same issuer, reusing old rpm\n";
unlink("$jobdir/$signfile");
} else {
rename("$jobdir/$signfile", "$jobdir/$signfilefinal");
}
$signfile = $signfilefinal;
undef $signfilefinal;
}
if ($signfile =~ /\.AppImage$/ && -e "$jobdir/$signfile.zsync") {
print("regenerating zsync file\n");
# re-generate zsync data
Expand Down

0 comments on commit f4aea07

Please sign in to comment.