Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPG key gets broken while importing #1974

Open
marmarek opened this issue Jul 28, 2023 · 0 comments
Open

GPG key gets broken while importing #1974

marmarek opened this issue Jul 28, 2023 · 0 comments

Comments

@marmarek
Copy link

When DNF is importing a key, it first mangles it via GnuPG, and only then import to rpmdb (which nowadays uses Sequoia). Those two PGP implementations are not 100% compatible which leads to issues - specifically, some keys that GnuPG is happy about (or even produced by GnuPG) are not accepted by Sequoia.
In this particular case, I hit https://gitlab.com/sequoia-pgp/sequoia/-/issues/1023 (similar to https://gitlab.com/sequoia-pgp/sequoia/-/issues/1024).

When using DNF, the package verification fails:

# /usr/bin/dnf -y --releasever=37 --installroot=/builder/dnfroot --config=/builder/dnfroot/etc/dnf/dnf.conf --downloaddir=/builder/plugins/installer/work/202307282149/x86_64/os/Packages --downloadonly install qubes-template-whonix-workstation-17
...
Importing GPG key 0x6D5C71B3:
 Userid     : "Qubes OS Release 4.2 Community Templates Signing Key"
 Fingerprint: 8F24 D388 C9DA 21A5 5D7D BC8F 08D0 8ABE 6D5C 71B3
 From       : /tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community
error: Certificate 08D08ABE6D5C71B3:
  Policy rejects 08D08ABE6D5C71B3: No binding signature at time 2023-07-28T22:19:01Z
Key import failed (code 2). Failing package is: qubes-template-whonix-gateway-17-4.2.0-202307131323.noarch
 GPG Keys are configured as: file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community
Public key for qubes-template-whonix-workstation-17-4.2.0-202307131323.noarch.rpm is not installed. Failing package is: qubes-template-whonix-workstation-17-4.2.0-202307131323.noarch
 GPG Keys are configured as: file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community

But, when I import the key using rpmkeys directly, it works:

$ rpmkeys --import --root $PWD/rpmdb --verbose --define='_pkgverify_level signature' --define='_pkgverify_flags 0x0' /tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community 
$ rpmkeys --checksig --root $PWD/rpmdb --verbose --define='_pkgverify_level signature' --define='_pkgverify_flags 0x0' /builder/plugins/installer/work/202307282149/x86_64/os/Packages/qubes-template-whonix-gateway-17-4.2.0-202307131323.noarch.rpm 
/builder/plugins/installer/work/202307282149/x86_64/os/Packages/qubes-template-whonix-gateway-17-4.2.0-202307131323.noarch.rpm:
    Header V4 EdDSA/SHA256 Signature, key ID 6d5c71b3: OK
    Header SHA256 digest: OK
    Header SHA1 digest: OK
    Payload SHA256 digest: OK
    V4 EdDSA/SHA256 Signature, key ID 6d5c71b3: OK
    MD5 digest: OK

Similarly, if I import the key into rpmdb in /builder/dnfroot (as used in the dnf call earlier here), it works fine then.

This seems to be related to this part of crypto.py (called from Base._get_key_for_package()):

def rawkey2infos(key_fo):
    pb_dir = tempfile.mkdtemp()
    keyinfos = []
    with pubring_dir(pb_dir), Context() as ctx:
        ctx.op_import(key_fo)
        for key in ctx.keylist():
            subkey = _extract_signing_subkey(key)
            if subkey is None:
                continue
            keyinfos.append(Key(key, subkey))
        ctx.armor = True
        for info in keyinfos:
            with Data() as sink:
                ctx.op_export(info.id_, 0, sink)
                sink.seek(0, os.SEEK_SET)
                info.raw_key = sink.read()
    dnf.util.rm_rf(pb_dir) 
    return keyinfos

def retrieve(keyurl, repo=None):
    if keyurl.startswith('http:'):
        logger.warning(_("retrieving repo key for %s unencrypted from %s"), repo.id, keyurl)
    with dnf.util._urlopen(keyurl, repo=repo) as handle:
        keyinfos = rawkey2infos(handle)
    for keyinfo in keyinfos:
        keyinfo.url = keyurl
    return keyinfos

I have confirmed the above is breaking the key. It can be also reproduced outside of dnf:

$ sq inspect /tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community
/tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community: OpenPGP Certificate.

    Fingerprint: 8F24D388C9DA21A55D7DBC8F08D08ABE6D5C71B3
Public-key algo: EdDSA
Public-key size: 256 bits
  Creation time: 2023-03-14 14:35:36 UTC
      Key flags: certification, signing

         UserID: Qubes OS Release 4.2 Community Templates Signing Key
$ mkdir test
$ gpg --homedir $PWD/test --import /tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.2-templates-community
gpg: WARNING: unsafe permissions on homedir '/home/user/test'
gpg: key 08D08ABE6D5C71B3: public key "Qubes OS Release 4.2 Community Templates Signing Key" imported
gpg: Total number processed: 1
gpg:               imported: 1
$ gpg --homedir $PWD/test -a --export | sq inspect
gpg: WARNING: unsafe permissions on homedir '/home/user/test'
-: OpenPGP Certificate.

    Fingerprint: 8F24D388C9DA21A55D7DBC8F08D08ABE6D5C71B3
                 Invalid: No binding signature at time 2023-07-28T22:29:23Z
Public-key algo: EdDSA
Public-key size: 256 bits
  Creation time: 2023-03-14 14:35:36 UTC

         UserID: Qubes OS Release 4.2 Community Templates Signing Key
                 Invalid: No binding signature at time 2023-07-28T22:29:23Z

While technically it can be qualified as a GnuPG bug, I don't think it's smart to mix two parsers, especially this way (transform using loose one then pass the output to a stricter one). It will lead to issues like this, especially given the GnuPG code shape.

The key in question can be found at https://github.com/QubesOS/qubes-qubes-release/blob/main/RPM-GPG-KEY-qubes-4.2-templates-community (if you look at its commit history, you'll see I needed to fix it there). Example package signed with it is at https://yum.qubes-os.org/r4.2/templates-community/rpm/qubes-template-whonix-gateway-17-4.2.0-202307131323.noarch.rpm (it's a big one, sorry).

$ dnf --version
4.15.0
  Installed: dnf-0:4.15.0-1.fc38.noarch at Sat May 20 01:44:10 2023
  Built    : Fedora Project at Thu Apr  6 08:24:21 2023

  Installed: rpm-0:4.18.1-3.fc38.x86_64 at Sat May 20 01:44:11 2023
  Built    : Fedora Project at Wed Apr 26 05:35:27 2023
marmarek added a commit to marmarek/qubes-builderv2 that referenced this issue Jul 28, 2023
DNF mangles the key on import, import it with rpmkeys beforehand. More
details at rpm-software-management/dnf#1974.
@pkratoch pkratoch removed their assignment Aug 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants