#3670 RFE: preservation of signed RPMs
Opened a year ago by fche. Modified a year ago

Recently, fedora koji has started applying per-file (IMA) signatures
to RPMs it has built. This is in addition to the overall GPG
signature of the RPM payload as a whole. While this extra capability
is not yet fully developed in userspace, we do have one ready user
(elfutils debuginfod [1]), which is unfortunately frustrated by a
policy in the koji code base.

That policy problem is the periodic pruning of signed RPMs. That is,
"koji prune-signed-copies" is run on the fedora infra every now and
then. This operation nukes data/signed/KEYHEX/ARCH/N-V-R.rpm files.
While it leaves behind data/sigcache/ARCH/*, those files appear not to
include the IMA signature content. That means the IMA signatures are
simply lost, like tears in rain.

We'd like to correct this somehow - to make the IMA signatures
available indefinitely - at least as long as the built RPMs stay of
any interest. (That means: not restricted to the most-recent-update
of a given fedora release.)

But how?

1) have the pruning operate by replacing the unsigned binaries with the
signed ones (hardlink or rename)?

2) have the pruning operate on the unsigned binaries, preserving the
signed ones?

3) preserve the IMA signature content somewhere nearby (sigcache?)
to give us a chance at finding the data there after a prune

4) ---> some other way? <---

[1] https://fedoraproject.org/wiki/Debuginfod

(also submitted to koji-devel@ cc: https://sourceware.org/pipermail/elfutils-devel/2023q1/005804.html )


Hmm, sigcache seems to me like most consistent way. But need to check the format if it is easy to strip them and reconstruct it as needed. @mikem any other preference?

Metadata Update from @tkopecek:
- Custom field Size adjusted to None

a year ago

Metadata Update from @tkopecek:
- Issue tagged with: bug

a year ago

Basically it means partly reusing extract/insert from https://github.com/fedora-iot/rpm-head-signing

Do we've some example of files which differs from original?

(What do you mean? Signed vs. unsigned RPMs?)

Maybe I'm confused here (after reading also e-mail thread in koji-devel). I've understood that imported signed rpm is binary different from what is produced by write-signed-rpm reconstruction. So, if it is the case I would like to see original (correctly signed) rpm and koji's variant of reconstructed rpm (from signed directory).

I haven't tried the write-signed-rpm reconstruction, tbh, but from the current files under sigcache, that's not possible. That's because all the sigcache files for new IMA-signed RPMs are the same small size, so cannot possibly contain per-file signatures (which are variable sized, depending on number of files in the rpm).

It is part of sigheader and they differ by size now (at least in f38). Check e.g. https://kojipkgs.fedoraproject.org/packages/AMF/1.4.29/1.fc38/data/sigcache/eb10b464/noarch/ sizes. It seems that koji and compose contain correctly signed rpms.

rpm -qp --qf '%{FILESIGNATURES:arraysize}\n' AMF-devel-1.4.29-1.fc38.noarch.rpm
warning: AMF-devel-1.4.29-1.fc38.noarch.rpm: Header V4 RSA/SHA256 Signature, key ID eb10b464: NOKEY
84

I've tried to import it to dev koji, delete the signatures from imported file and recreate it via sigcache:

$  ./koji import --create-build ~/Download/AMF-devel-1.4.29-1.fc38.noarch.rpm 
Missing build or srpm: AMF-1.4.29-1.fc38
Creating empty build: AMF-1.4.29-1.fc38
uploading /home/tkopecek/Download/AMF-devel-1.4.29-1.fc38.noarch.rpm... done
importing /home/tkopecek/Download/AMF-devel-1.4.29-1.fc38.noarch.rpm... mc
done

$ cd <packagedir>
$ find -type f -exec sha256sum {} \;
2040f1d418171248dccea5ac10f8524a27ec8f7c8480efb14142d6775df113bb  ./noarch/AMF-devel-1.4.29-1.fc38.noarch.rpm
3bb2b303fbd7682d989bec3905d025b8e26aeb66d279c397cf70175f6ec6b139  ./data/sigcache/eb10b464/noarch/AMF-devel-1.4.29-1.fc38.noarch.rpm.sig
$ cd  ./noarch/
$ rpmsign --delsign AMF-devel-1.4.29-1.fc38.noarch.rpm
AMF-devel-1.4.29-1.fc38.noarch.rpm:
$ rpmsign --delfilesign AMF-devel-1.4.29-1.fc38.noarch.rpm
AMF-devel-1.4.29-1.fc38.noarch.rpm:
$ sha256sum sha256sum AMF-devel-1.4.29-1.fc38.noarch.rpm
15626fd43ba176a61333b4c5550f668a266a0dec82713268b8fe0a33b8934f4d  AMF-devel-1.4.29-1.fc38.noarch.rpm
$ cd ..
$ koji write-signed-rpm eb10b464 AMF-devel-1.4.29-1.fc38.noarch.rpm
[1/1] AMF-devel-1.4.29-1.fc38.noarch
$ find -name '*rpm' -exec sha256sum {} \;
2040f1d418171248dccea5ac10f8524a27ec8f7c8480efb14142d6775df113bb  ./noarch/AMF-devel-1.4.29-1.fc38.noarch.rpm
2040f1d418171248dccea5ac10f8524a27ec8f7c8480efb14142d6775df113bb  ./data/signed/eb10b464/noarch/AMF-devel-1.4.29-1.fc38.noarch.rpm

So, it looks to me that it works fine now. One note, there is a small difference (not breaking the functionality, but altering checksum (1-bit flip in header)) in current version which will be fixed by #3690 (which I've used here). (@mikem - nice test for your code)

diff --git a/orig.xxd b/signed.xxd
index e2e5094..3ad7028 100644
--- a/downloaded.xxd
+++ b/reconstructed.xxd
@@ -1,4 +1,4 @@
-00000000: edab eedb 0300 0000 00ff 414d 462d 6465  ..........AMF-de
+00000000: edab eedb 0300 0000 0001 414d 462d 6465  ..........AMF-de
 00000010: 7665 6c2d 312e 342e 3239 2d31 2e66 6333  vel-1.4.29-1.fc3
 00000020: 3800 0000 0000 0000 0000 0000 0000 0000  8...............
 00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Is that sigcache/ file format documented somewhere, so a tool could read them in lieu of headers in purged signed rpms, and not by reconstituting them (i.e., not running a koji cmd)?

It is standard [rpm header|http://ftp.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html]. It is just cut out from rpm itself. So, reconstitution means, take base header from usigned rpm, add sigcache file, add payload and you're done.
So, it could be parsed directly, or koji's RawHeader abstraction can be used here koji.RawHeader(open('xyz.sig', 'rb').read())

I've added #3711 for easier reading of file signatures - rawheader.get(274) would return list of file signatures in order of fileinfos in header. (274 is RPMSIGTAG_FILESIGNATURES tag)

I've added #3711 for easier reading of file signatures

Do you mean #3713 ?

I've been taking a look at the data/sigcache/* directories and was wondering how they are meant to be navigated? They contain a mixture of ARCH directories (with the .sig files within which are mostly empty), but also the KEYHEX/ARCH/ directories which have the signature containing headers. The issue with that is without those headers, we don't know the KEYHEX so we can't know what directory to check. Moreso there are sometimes multiple KEYHEX directories all of which have the headers only with different package signing keys. Is there a recommended way of accessing these files without knowing the specific KEYHEX beforehand (i.e given a package-version-distro-arch combo such as https://kojipkgs.fedoraproject.org/packages/AMF/1.4.29/1.fc38/noarch/ get an IMA signature containing directory path such as https://kojipkgs.fedoraproject.org/packages/AMF/1.4.29/1.fc38/data/sigcache/eb10b464/noarch/)

Login to comment on this ticket.

Metadata