rpm-software-management / librepo

A library providing C and Python (libcURL like) API for downloading packages and linux repository metadata in rpm-md format
http://rpm-software-management.github.io/librepo/
GNU Lesser General Public License v2.1
74 stars 90 forks source link

Binary PGP keys cannot be imported if PGP backend is RPM library #284

Closed DaanDeMeyer closed 10 months ago

DaanDeMeyer commented 10 months ago

When trying to build Fedora images using mkosi with dnf5 from Fedora 39 or rawhide, I get the following error:

‣  Installing Fedora
Updating and loading repositories:
 fedora                                                                                                                                                                                             100% | 104.7 KiB/s |  18.6 KiB |  00m00s
 updates                                                                                                                                                                                            100% |  95.3 KiB/s |  15.7 KiB |  00m00s
 updates                                                                                                                                                                                            100% |   3.0 MiB/s |   3.1 MiB |  00m01s
Repositories loaded.
Package                                                                          Arch              Version                                                                          Repository                                          Size
Installing:                                                                                                                                                                                                                                 
 filesystem                                                                      x86_64            3.18-3.fc38                                                                      fedora                                         106.0   B
Installing dependencies:                                                                                                                                                                                                                    
 fedora-gpg-keys                                                                 noarch            38-1                                                                             fedora                                         120.7 KiB
 fedora-release                                                                  noarch            38-36                                                                            updates                                          0.0   B
 fedora-release-common                                                           noarch            38-36                                                                            updates                                         17.1 KiB
 fedora-release-identity-basic                                                   noarch            38-36                                                                            updates                                        668.0   B
 fedora-repos                                                                    noarch            38-1                                                                             fedora                                           4.5 KiB
 setup                                                                           noarch            2.14.3-2.fc38                                                                    fedora                                         720.2 KiB

Transaction Summary:
 Installing:        7 packages

Total size of inbound packages is 1 MiB. Need to download 0 B.
After this operation 863 KiB will be used (install 863 KiB, remove 0 B).
[1/7] filesystem-0:3.18-3.fc38.x86_64                                                                                                                                                               100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
[2/7] setup-0:2.14.3-2.fc38.noarch                                                                                                                                                                  100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
[3/7] fedora-release-0:38-36.noarch                                                                                                                                                                 100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
[4/7] fedora-release-common-0:38-36.noarch                                                                                                                                                          100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
[5/7] fedora-repos-0:38-1.noarch                                                                                                                                                                    100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
[6/7] fedora-gpg-keys-0:38-1.noarch                                                                                                                                                                 100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
[7/7] fedora-release-identity-basic-0:38-36.noarch                                                                                                                                                  100% |   0.0   B/s |   0.0   B |  00m00s
>>> Already downloaded
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[7/7] Total                                                                                                                                                                                         100% |   0.0   B/s |   0.0   B |  00m00s
[1/8] https://fedoraproject.org/fedora.gpg                                                                                                                                                          100% |  66.8 KiB/s |  11.4 KiB |  00m00s
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[8/8] Total                                                                                                                                                                                         100% |   0.0   B/s |   0.0   B |  00m00s
Failed to import pgp keys into temporary keyring: Public key not found
‣ "/usr/bin/dnf5 --assumeyes --config=/home/daandemeyer/projects/mkosi/.mkosi-tmpal_fz7as/pkgmngr/etc/dnf/dnf.conf --best --releasever=38 --installroot=/home/daandemeyer/projects/mkosi/.mkosi-tmpal_fz7as/root --setopt=keepcache=1 '--setopt=cachedir=/home/daandemeyer/projects/mkosi/mkosi.cache/fedora~38' --setopt=reposdir=/home/daandemeyer/projects/mkosi/.mkosi-tmpal_fz7as/pkgmngr/etc/yum.repos.d --setopt=varsdir=/home/daandemeyer/projects/mkosi/.mkosi-tmpal_fz7as/pkgmngr/etc/dnf/vars --setopt=persistdir=/home/daandemeyer/projects/mkosi/.mkosi-tmpal_fz7as/pkgmngr/var/lib/dnf --setopt=check_config_file_age=0 '--disableplugin=*' --enableplugin=builddep --no-docs install filesystem" returned non-zero exit code 1.

This error seems to come from lr_gpg_import_key_from_memory() in librepo. The error does not occur on Fedora 38 which makes me think it is caused by librepo 1.16.0.

DaanDeMeyer commented 10 months ago

cc @jrohel

ppisar commented 10 months ago

Could please tell us what dnf5, librepo, and rpm do you use? Are that Fedora-39 provided builds, or your own ones? Do you know what PGP key you attempt to import into DNF? Is that only https://fedoraproject.org/fedora.gpg? Can you see something interesting in DNF5 log (/var/log/dnf5.log)?

DaanDeMeyer commented 10 months ago

dnf5, librepo and rpm come straight from Fedora rawhide or Fedora 39 (The problem reproduces on both). The PGP key we attempt to import is from "https://fedoraproject.org/fedora.gpg".

The relevant logs from dnf5.log:

2023-10-03T09:38:25+0000 [2] DEBUG [librepo] lr_download: Target: https://fedoraproject.org/fedora.gpg (-)
2023-10-03T09:38:25+0000 [2] DEBUG [librepo] Selecting mirror for: https://fedoraproject.org/fedora.gpg
2023-10-03T09:38:25+0000 [2] INFO [librepo] Downloading: https://fedoraproject.org/fedora.gpg
2023-10-03T09:38:25+0000 [2] DEBUG [librepo] prepare_next_transfer: Resume ignored, existing file was not originally being downloaded by Librepo
2023-10-03T09:38:25+0000 [2] DEBUG [librepo] lr_download: Downloading started
2023-10-03T09:38:25+0000 [2] DEBUG [librepo] Transfer finished: https://fedoraproject.org/fedora.gpg (Effective url: https://fedoraproject.org/fedora.gpg)
2023-10-03T09:38:25+0000 [2] DEBUG [librepo] lr_gpg_import_key_from_memory: Error: Public key not found
2023-10-03T09:38:25+0000 [2] ERROR Command returned error: Failed to import pgp keys into temporary keyring: Public key not found

If you want to reproduce (without having to be on rawhide or f39):

git clone https://github.com/systemd/mkosi
cd mkosi
bin/mkosi -d fedora --tools-tree=default --debug-shell -f

This will first build a Fedora rawhide image and then try to use that image to build a regular Fedora image. The second image build will fail with the error from this issue. You'll end up in a shell from which you can run ls -a to find the mkosi temporary directory which will be named something like .mkosi-tmp.... In there you'll find a root folder which contains the image directory where you'll find /var/log/dnf5.log.

DaanDeMeyer commented 10 months ago

Looking at https://fedoraproject.org/fedora.gpg, it just seems to not be in the format that lr_gpg_import_key_from_memory() expects. But it seems like the previous implementation did handle this without any problems.

ppisar commented 10 months ago

Yes, RPM only support ASCII-armored key format:

# rpm --import fedora.gpg 
error: fedora.gpg: key 1 not an armored public key.
# rpm -q rpm-libs
rpm-libs-4.19.0-1.fc40.x86_64
DaanDeMeyer commented 10 months ago

Should we revert back to the gpgme implementation in rawhide/f39 until this can be addressed?

ppisar commented 10 months ago

Maybe it's only rpm tool not supporting it. In Fedora 40, having this repository:

[foo]
name=Fedora $releasever - $basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch
enabled=0
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=https://fedoraproject.org/fedora.gpg
skip_if_unavailable=False

"dnf5 --use-host-config --repoid=foo --assumeyes --releasever=38 --installroot=/tmp/ir install filesystem" reports a better error for me (actually I had to recompile librepo, distribution one cashes for me, I suspect libxml2 broke ABI):

Importing PGP key 0x352C64E5:
 Userid     : "Fedora EPEL (7) <epel@fedoraproject.org>"
 Fingerprint: 91E97D7C4A5E96F17F3E888F6A2FAEA2352C64E5
 From       : https://fedoraproject.org/fedora.gpg
Importing PGP key 0x2F86D6A1:
 Userid     : "Fedora EPEL (8) <epel@fedoraproject.org>"
 Fingerprint: 94E279EB8D8F25B21810ADF121EA45AB2F86D6A1
 From       : https://fedoraproject.org/fedora.gpg
Importing PGP key 0x3228467C:
 Userid     : "Fedora (epel9) <epel@fedoraproject.org>"
 Fingerprint: FF8AD1344597106ECE813B918A3872BF3228467C
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0x9867C58F:
 Userid     : "Fedora (35) <fedora-35-primary@fedoraproject.org>"
 Fingerprint: 787EA6AE1147EEE56C40B30CDB4639719867C58F
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0x38AB71F4:
 Userid     : "Fedora (36) <fedora-36-primary@fedoraproject.org>"
 Fingerprint: 53DED2CB922D8B8D9E63FD18999F7CBF38AB71F4
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0x5323552A:
 Userid     : "Fedora (37) <fedora-37-primary@fedoraproject.org>"
 Fingerprint: ACB5EE4E831C74BB7C168D27F55AD3FB5323552A
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0xEB10B464:
 Userid     : "Fedora (38) <fedora-38-primary@fedoraproject.org>"
 Fingerprint: 6A51BBABBA3D5467B6171221809A8D7CEB10B464
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0x18B8E74C:
 Userid     : "Fedora (39) <fedora-39-primary@fedoraproject.org>"
 Fingerprint: E8F23996F23218640CB44CBE75CF5AC418B8E74C
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0xA15B79CC:
 Userid     : "Fedora (40) <fedora-40-primary@fedoraproject.org>"
 Fingerprint: 115DF9AEF857853EE8445D0A0727707EA15B79CC
 From       : https://fedoraproject.org/fedora.gpg
The key was successfully imported.
Importing PGP key 0xDBBDCF7C:
 Userid     : "Fedora (iot 2019) <fedora-iot-2019@fedoraproject.org>"
 Fingerprint: C2A3FA9DC67F68B98BB543F47BB90722DBBDCF7C
 From       : https://fedoraproject.org/fedora.gpg

Transaction failed: Signature verification failed.
An error occurred importing key "https://fedoraproject.org/fedora.gpg": Failed to import public key "https://fedoraproject.org/fedora.gpg" to rpmdb: Certificate 6A2FAEA2352C64E5:
  Policy rejects 6A2FAEA2352C64E5: No binding signature at time 2023-10-03T11:38:27Z
An error occurred importing key "https://fedoraproject.org/fedora.gpg": Failed to import public key "https://fedoraproject.org/fedora.gpg" to rpmdb: Certificate 21EA45AB2F86D6A1:
  Policy rejects 21EA45AB2F86D6A1: No binding signature at time 2023-10-03T11:38:27Z
An error occurred importing key "https://fedoraproject.org/fedora.gpg": Failed to import public key "https://fedoraproject.org/fedora.gpg" to rpmdb: Certificate 7BB90722DBBDCF7C:
  Policy rejects 7BB90722DBBDCF7C: No binding signature at time 2023-10-03T11:38:27Z
PGP check for package "filesystem-3.18-3.fc38.x86_64" (/var/cache/libdnf5/foo-376ef8e983c65ce0/packages/filesystem-3.18-3.fc38.x86_64.rpm) from repo "foo" has failed: Public key import failed.

What crypto policy to you have set on the host system? I have:

$ cat /etc/crypto-policies/state/current 
TEST-FEDORA39

That policy, e.g. forbids SHA-1.

The 3 offending keys from fedora.gpg keyring bundle are:

$ gpg --list-keys 6A2FAEA2352C64E5
pub   rsa4096 2013-12-16 [SCE]
      91E97D7C4A5E96F17F3E888F6A2FAEA2352C64E5
uid       [  neznámá   ] Fedora EPEL (7) <epel@fedoraproject.org>

petr@dhcp-0-146:~ $ gpg --list-keys 21EA45AB2F86D6A1
pub   rsa4096 2019-06-05 [SCE]
      94E279EB8D8F25B21810ADF121EA45AB2F86D6A1
uid       [  neznámá   ] Fedora EPEL (8) <epel@fedoraproject.org>

petr@dhcp-0-146:~ $ gpg --list-keys 7BB90722DBBDCF7C
pub   rsa4096 2018-11-13 [SCE] [platnost skončí: 2028-12-31]
      C2A3FA9DC67F68B98BB543F47BB90722DBBDCF7C
uid       [  neznámá   ] Fedora (iot 2019) <fedora-iot-2019@fedoraproject.org>

E.g. the "EPEL (7)" key has a self-signature with SHA-1 ("digest algo 2"):

$ gpg --list-packets 91E97D7C4A5E96F17F3E888F6A2FAEA2352C64E5.key 
# off=0 ctb=99 tag=6 hlen=3 plen=525
:public key packet:
        version 4, algo 1, created 1387161732, expires 0
        pkey[0]: [4096 bits]
        pkey[1]: [17 bits]
        keyid: 6A2FAEA2352C64E5
# off=528 ctb=b4 tag=13 hlen=2 plen=40
:user ID packet: "Fedora EPEL (7) <epel@fedoraproject.org>"
# off=570 ctb=89 tag=2 hlen=3 plen=568
:signature packet: algo 1, keyid 6A2FAEA2352C64E5
        version 4, created 1387161732, md5len 0, sigclass 0x13
        digest algo 2, begin of digest c7 c6
        hashed subpkt 2 len 4 (sig created 2013-12-16)
        hashed subpkt 27 len 1 (key flags: 0F)
        hashed subpkt 11 len 5 (pref-sym-algos: 9 8 7 3 2)
        hashed subpkt 21 len 5 (pref-hash-algos: 8 2 9 10 11)
        hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1)
        hashed subpkt 30 len 1 (features: 01)
        hashed subpkt 23 len 1 (keyserver preferences: 80)
        subpkt 16 len 8 (issuer key ID 6A2FAEA2352C64E5)
        data: [4094 bits]

And is forbidden by TEST-FEDORA39 crypto policy.

DaanDeMeyer commented 10 months ago
sh-5.2# cat /etc/crypto-policies/state/current 
DEFAULT

I assume I'll run into the problems you mentioned after this issue is fixed. But currently I just get the error from librepo 1.16.0.

ppisar commented 10 months ago

I'm sorry for confusing you. I accidentally compiled librepo with gpgme support and that's when got the detailed error about "No binding signature".

ppisar commented 10 months ago

I confirm that:

So indeed the problem is that Sequoia RPM PGP backend does not support binary serialization.

DaanDeMeyer commented 10 months ago

Where do we report issues for the fedora.gpg keyring? I assume those keys should be removed.

ppisar commented 10 months ago

I guess at https://pagure.io/releng/issues.

ppisar commented 10 months ago

I think that instead of reverting Fedora's librepo to GPGME, librepo could convert binary key files into ASCII-armor format before passing them to RPM. The conversion is specified in section 6 of RFC 4880 https://www.rfc-editor.org/rfc/rfc4880#section-6. It's MIME Base64 with CRC-24. Until RPM or rpm-sequoia implements it properly.

jrohel commented 10 months ago

I did the tests. The original gpgme OpenPGP implementation supports importing binary (not ASCII-armored) keys. I will add this support to the OpenPGP backend that uses the librpm API.

jrohel commented 10 months ago

I added support for importing binary public keys into the OpenPGP backend that uses the librpm API. PR: https://github.com/rpm-software-management/librepo/pull/286