Bad signatures or NOKEY errors on RPMs I just signed
I'm having serious problems getting RPM signing working for RHEL / CentOS 5 hosts.
TL;DR: RPM signing isn't working, and it's working in a variety of insane and erratic ways depending on the exact GPG key size and format and even where it was generated, producing NOKEY errors when the key is shown by rpm -qa gpg-*
as present; BAD
signature errors on an RPM that was just signed on the same machine with the same key; invalid passphrase errors on a key where gpg accepts the passphrase directly without trouble; etc.
I have tested with 4096, 2048 and 1024 bit RSA keys, and a 2048 bit DSA key, doing the signing and the verification on the same CentOS 5.10 VM. Behaviour varies with key type and size, but I haven't found anything that actually works yet.
With names, emails and RPM filenames masked by XXX but no other edits, for example, the DSA 2048 key:
$ rpm --version
RPM version 4.4.2.3
$ gpg --list-secret 92fb1e62
sec 2048D/92FB1E62 2014-08-29 [expires: 2015-08-29]
uid XXX <[email protected]>
ssb 2048g/2E0F0A24 2014-08-29 [expires: 2015-08-29]
$ gpg -a --export 92fb1e62 > /tmp/packagers
$ sudo rpm --import /tmp/packagers
$ rpm -qa gpg*
gpg-pubkey-92fb1e62-54001945
$ rpmsign --define '%_gpg_name [email protected]' --resign test.el5.x86_64.rpm
Enter pass phrase:
Pass phrase is good.
test.el5.x86_64.rpm:
gpg: WARNING: standard input reopened
gpg: WARNING: standard input reopened
$ rpm -v -K test.el5.x86_64.rpm
test.el5.x86_64.rpm:
Header V3 DSA signature: NOKEY, key ID 92fb1e62
Header SHA1 digest: OK (47271f9fa8ac0ce03b980ff75a37f10d3b78ee7c)
MD5 digest: OK (f453985ee4331d36cb82d2c4f6009509)
V3 DSA signature: NOKEY, key ID 92fb1e62
NOKEY
? How does that make any sense?
I imported the key with rpm --import
as normal. It imported with no errors. It's listed in the RPM DB. Yet RPM's verify command doesn't see it.
I see the same problem with a 4096 bit RSA key on CentOS 5.
(On Fedora 20, it instead fails with:
$ rpmsign --define '%_gpg_name [email protected]' --resign test.x86_64.rpm
Enter pass phrase:
Pass phrase is good.
test.x86_64.rpm:
error: Unsupported PGP signature
... which is at least a failure at signing time, not later.)
If I use a 2048 or 1024 bit RSA key on CentOS 5, I instead get a BAD signature reported when the signature is verified, despite the fact that I just signed the RPM with that key:
$ gpg --import /mnt/repo/packaging-key-secret-1024
gpg: key 1FC138CC: secret key imported
gpg: key 1FC138CC: public key "XXX <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
gpg: secret keys read: 1
gpg: secret keys imported: 1
$ gpg -a --export [email protected] > /tmp/packagers
$ sudo rpm --import /tmp/packagers
$ rpm --define '%_gpg_name [email protected]' --resign test.x86_64.rpm
Enter pass phrase:
Pass phrase is good.
test.x86_64.rpm:
gpg: WARNING: standard input reopened
gpg: WARNING: standard input reopened
$ $ rpm -v -K test.x86_64.rpm
test.x86_64.rpm:
Header V3 RSA/SHA1 signature: BAD, key ID 1fc138cc
Header SHA1 digest: OK (1befc128ddd02a79d1b1098bc16aff4532b5af6c)
V3 RSA/SHA1 signature: BAD, key ID 1fc138cc
MD5 digest: OK (2aaacbe1db08a2c63c94f2f705693c7d)
Seriously. W.T.F? I'm at a head-meets-wall level of frustration and am throwing myself upon Stack Exchange's mercy. RPM packagers, please share your secret signing voodoo.
It doesn't seem to be do to with the warnings about stdin being re-opened.
(I'd love to simply not support EL5, but I'm stuck with supporting it for a little longer, as well as newer and saner distros).
Other relevant info:
$ gpg --version
gpg (GnuPG) 1.4.5
...blahcopyrightblah...
Supported algorithms:
Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
$ cat /etc/redhat-release
CentOS release 5.10 (Final)
Oh, and for bonus WTF points, I generated a throwaway new key directly on the CentOS box, with the passphrase "fred". I can sign stuff with it:
$ gpg -q -a -b --sign -u [email protected] testfile
You need a passphrase to unlock the secret key for
user: "XXX <[email protected]>"
1024-bit DSA key, ID 99188B9C, created 2014-08-29
and verify it:
$ gpg -v testfile.asc
gpg: armor header: Version: GnuPG v1.4.5 (GNU/Linux)
gpg: assuming signed data in `testfile.asc'
gpg: Signature made Fri 29 Aug 2014 08:02:47 AM UTC using DSA key ID 99188B9C
gpg: Good signature from "XXX <[email protected]>"
gpg: binary signature, digest algorithm SHA1
but rpmsign is being even more insane. With exactly the same passphrase it's rejecting it:
$ rpmsign --define '%_gpg_name [email protected]' --resign test.el5.x86_64.rpm
Enter pass phrase:
Pass phrase check failed
whether typed or copied & pasted. Using rpm
as a wrapper instead of rpmsign
directly makes no difference.
Update: For new bonus crazy points, on CentOS 6.5 using a 2048 bit DSA key, using a test.rpm
that was just compiled using mock
within a CentOS 6.5 target mock environment (i.e. with a matching RPM version):
$ rpmsign --define '%_gpg_name 92FB1E62' --resign test.rpm
Enter pass phrase:
Pass phrase is good.
test.rpm:
$ rpm -v -K test.rpm
error: skipping package test.rpm with unverifiable V4 signature
Yup - rpmsign just signed the package, then rejected its own signature.
Clearly most people don't have these problems. What am I missing?
Solution 1:
It's a cluster of RPM bugs. Not just one bug, or two bugs. A nest of the critters. RPM fails (failed?) to validate signed packages, didn't understand v4 GPG signatures but didn't notice it didn't understand them, didn't understand some key sizes and types but didn't notice it didn't understand that, and also choked on subkeys!
This lifesaving blog entry by Jacob Helwig, as pointed out by a colleague, covers the issues:
You must force GnuPG to use v3 signatures when signing on/for RHEL / CentOS 5 or 6 in your `
%__gpg_sign_cmd %{__gpg} \
gpg --force-v3-sigs --digest-algo=sha1 --batch --no-verbose --no-armor \
--passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" \
-sbo %{__signature_filename} %{__plaintext_filename}
because RPM doesn't check the sigversion or validate the signed package after signing it, and these distros contain GPG versions that default to v4 signatures.
You must also generate a 2048 bit signing-only RSA key with no subkeys.
A couple of relevant bugs:
RPM seems unable to find (GPG) RSA keys for verifying signatures
rpm --sign with 4096bit or 2048bit RSA key creates broken signature