From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030309 Description of problem: RPM 4.1/test-4.1.1 seems to be totally oblivious to RSA keys when verifying package signatures. It can find DSA keys just fine, however. As far as I can tell from the RPM manpage, either should work though... Version-Release number of selected component (if applicable): rpm-4.1.1-0.1.8x or rpm-4.1-1.06 How reproducible: Always Steps to Reproduce: Approximate steps: 1. Create a public RSA signing key with GPG 2. Set up .rpmmacros as appropriate 3. Export an ASCII-armored version of your public key. 4. rpm --import that 5. Take a package and --resign (or --addsign) it 6. Try to verify that. Notice it fails to find the key, even though it's been imported. See "Actual Results" for a detailed example. Actual Results: Bugzilla choked when I tried to include the actual results inline, so I will be attaching them. Expected Results: Errr... key d0fde7fe is in the RPM database. Shouldn't it be able to find it? Also, why does it think I put a V3 DSA signature on my popt package? In any case, I was expecting it to work the way that 4.0.4 does. Additional info: The error happens whether I sign the package with RPM 4.0.4-19mdk, 4.1-1.06, or 4.1.1-0.1.8x (test-4.1.1 from ftp.rpm.org). The signed packages can be verified on 4.0.4-19mdk just fine. A possible workaround is to use DSA instead of RSA. If we're not supposed to use RSA keys to sign our own packages, or if it's known to be flaky and that's the accepted status quo, it would be nice for that to be documented more strongly than just "DSA is preferred". (OTOH, if it's actually supposed to work, then it would be good if it could be fixed.)
Created attachment 90572 [details] A detailed example of a failure scenario. It doesn't exactly illustrate best practices (no passphrase on the key, among other things) but it does illustrate the bug in question.
RSA/MD5 header+payload signature verification works just fine. For example, here's the output when verifying the rpm package from Red Hat 5.2: bash$ rpm -Kvv rpm-2.5.5-5.2.i386.rpm D: Expected size: 427519 = lead(96)+sigs(268)+pad(4)+data(427151) D: Actual size: 427487 D: opening db index /var/lib/rpm/Packages rdonly mode=0x0 D: locked db index /var/lib/rpm/Packages D: opening db index /var/lib/rpm/Pubkeys rdonly mode=0x0 D: read h# 212 Header sanity check: OK D: ========== RSA pubkey id a520e8f1cba29bf9 rpm-2.5.5-5.2.i386.rpm: V3 RSA/MD5 signature: OK, key ID cba29bf9 MD5 digest: OK (bf23932df29ea6bffc2b01956b6ae344) D: closed db index /var/lib/rpm/Pubkeys D: closed db index /var/lib/rpm/Packages Since Red Hat uses DSA for signing packages (since Red Hat 6.2), you are traversing code paths that only occaisionally (like now) get tested. OTOH I know of no reason why you shouldn't be able to use gpg with RSA/MD5 for signing packages, the RFC-2440 OpenPGP parser within rpm should parse RSA/MD5 packets just fine, and signing is still done using a helper binary. What's a little schizoid is that rpm has always confused the implementation (e.g. "gpg" or "pgp") with the signature type (e.g. "DSA" or "RSA/MD5"), so you may need to generate RSA/MD5 signatures using pgp rather than gnupg, with associated (and confusing) configuration in rpm. So think of "pgp" as synonomous with "RSA/MD5" when reading rpm man pages. What isn't tested (and there are pieces that may not be implemented), is RSA/MD5 header-only signatures. I know that I've tested RSA/MD5 signing using pgp. I also know that I have *not* tested RSA/MD5 using gpg. Is there any particular reason why DSA is not good enough?
At least when I use GPG from the command line to sign files, it seems to be using RSA/SHA1, not RSA/MD5. I plan on avoiding the MD5 hash so I plan on avoiding RSA/MD5. Anyway, the reason I wanted to try using RSA/SHA1 is that DSA is limited to a 1024-bit key length, and I'm paranoid enough that I thought it might be neat to have a key longer than that. (I only used a 1024-bit key in the example I attached to this bug, but the key I generated with the intent of "production" use is longer than that.) I'll probably just generate another keypair, using DSA, and use that for now (and maybe into the future too). The strange [from a user's perspective] thing is, unless there's anything special about Mandrake 9.0's RPM 4.0.4, this is a regression. It's not urgent, so feel free to defer it if you wish. (If Red Hat decides not to fix this even in the long term, I'd like to at least see a suggestion/clarification in the documentation, at some point in the future. It's probably not worth delaying any errata packages though.)
RSA/SHA1 in gnupg explains your output. There's no attempt to handle RSA/SHA1 in rpm. 'Twouldn't be hard, but handling v4 OpenPGP signatures needs doing first.
Well wouldn't it be simple to just modify the gpg macros to call --pgp2 which will then be sure to create RSA/md5 signatures otherwise indistinguishable from PGP created? The other problem is that it outright fails to find the key after you've imported it. If you do rpm -qa you'll see some bizarro interpretation of what the keyid of the RSA key is. (My RSA key is in fact a pgp2.x era RSA key, but it has some DSA signatures on it. Your old beecrypt stuff is getting confused by the DSA signatures on my key and assigning my key the keyid of the lexically first DSA signature on my key.) What the previous poster described is kind of broken too, and I'd think should be fixed... My related bug shows that in fact even using pgp5+ basically breaks because those keys typically have DSA keys on them. So what is someone going to do to verify my signed RPM? Well they'll fetch my key from the key servers, run rpm --import on it, and boom, it'll get a garbage keyid according to rpm beecrypt stuff, and then the signature will universally fail. There is nothing I can do about the DSA signatures on the key server because the key servers don't let you remove sigantures. In addition it would detract from security to remove signatures anyway because they are part of my web of trust. Wouldn't it be like simpler to outright use gpg rather than reimplement a gpg signature verifying and key parsing subset in beecrypt?
Just spent another 2 hours or so trying to pgp sign the package. (Rather than gpg sign the package as that is a monumental flop if you try to use an RSA key with DSA signatures on it). There is no documentation relating to pgp. man (8) rpm talks only in the specific about how to edit a .rpmmacro to use gpg. But reverse engineering the /usr/lib/rpm/macros file one can figure out what macros one might be supposed to be using: %_signature pgp %_pgp_path /root/.pgp %_pgp_name Adam Back <adam> %_pgpbin /usr/local/bin/pgp (My pgp is 6.5.8, the latest unix command line version). But after that I can't sign didly squat. To check here is my key in my keyring: % pgp -kv adam Type bits keyID Date User ID RSA 2048 0xD8F056DD 1999/11/14 *** DEFAULT SIGNING KEY *** Adam Back <adam> so firstly despite what it says in rpm (8) the %_gpgbin has precisely no effect as it's not even used in /usr/lib/rpm/macros. (No doubt it happens to be where the example says on a default redhat9... but that won't help users who don't ahve it living there and are trying in vain to adjust by using %_gpgbin). %_pgpbin is listed in macros but it says it deprecated, and is only assigned never read or used in any macros. So you should fix the macros file or the rpm (8) man page. So if you have no binary you'll get "Broken pipe" when you try to sign. So if I make this changes, I can now sign with pgp6.5.8. % cat ~/.rpmmacros %_signature pgp %_pgp_path /root/.pgp %_pgp_name Adam Back <adam> %__pgp /usr/local/bin/pgp However: % rpm --checksig /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm still fails with: /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm: sha1 (MD5) (PGP) md5 NOT OK (MISSING KEYS: PGP#d8f056dd) which is blatantly false as: % rpm -qa gpg-pubkey gpg-pubkey-02d77dd6-3e83040c gpg-pubkey-db42a60e-37ea5438 (the 1st of which is my key, the other being redhat default). Then: % rpm -qi gpg-pubkey-02d77dd6-3e83040c | pgpacket | grep -i d8f056dd Key ID: 0x143C9F41D8F056DD so the key is in fact in there just misnamed / mis-indexed for the reasons I gave above. So, as a last resort, I'll now try removing all signatures made by DSA keys on my public key and re-importing that: % rpm -e gpg-pubkey-02d77dd6-3e83040c % pgp -kxa adam adam.asc % pgpacket adam.asc | less # to figure which sigs are from DSA keys % pgp -krs adam #remove the offending sigs % pgp -kxa adam adam.asc % rpm --import adam.asc now I should be able to check... however boom, for another reason! % rpm --checksig /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm: sha1 MD5 PGP md5 NOT OK % rpm --checksig -v -v /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm Header SHA1 digest: OK (0ec8d8fe63ebaf0e6658ab6a3992a3279ba6c32c) V3 RSA/MD5 signature: BAD, key ID d8f056dd MD5 digest: OK (b07b5c7987ca8d0eccbd9113604bdd73) so one thought was the lack of support for v4 signatures, but as I have a v3 key it is not likely. To test I signed a message with pgp -s and indeed it creates a v3 signature by default (at least with my v3 public key). Next thought is one of the RSA signatures on my key is a v4 key signature, so I remove that one also! % pgp -krs adam % pgp -kxa adam adam.asc % rpm -e gpg-pubkey-d8f056dd-382eb35c % rpm --import adam.asc but still broken: % rpm --checksig -vv /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm Header SHA1 digest: OK (0ec8d8fe63ebaf0e6658ab6a3992a3279ba6c32c) V3 RSA/MD5 signature: BAD, key ID d8f056dd MD5 digest: OK (b07b5c7987ca8d0eccbd9113604bdd73) so try resigning (with pgp): % rpmbuild -ba --sign /usr/src/redhat/SPECS/hashcash-0.26.spec still broken: % rpm --checksig -vv /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm Header SHA1 digest: OK (ebe16e09867c6c852395cd7fa04e7890e04fc145) V3 RSA/MD5 signature: BAD, key ID d8f056dd MD5 digest: OK (2d35d2877093d26bf81eea4ab76d2148) try resigning with gpg (put my .rpmmacro file back the way it was): % cat .rpmmacros %_signature gpg %_gpg_path /root/.gnupg %_gpg_name Adam Back <adam> resign: % rpmbuild -ba --sign /usr/src/redhat/SPECS/hashcash-0.26.spec recheck: % rpm --checksig -vv /usr/src/redhat/RPMS/i386/hashcash-0.26-1.i386.rpm Header V3 DSA signature: NOKEY, key ID d8f056dd Header SHA1 digest: OK (71ed581c95b11f58c0b6e2da1955a0c6fef0590b) MD5 digest: OK (c865d6d10bbe47840c76c0741ded5944) V3 DSA signature: NOKEY, key ID d8f056dd so in summary I'd say the pgp support is pretty comprehensively broken. Probably the best thing you could do is rollback signature verification to the rpm 4.0x where rpm was using GPG/PGP to verify signatures until the bee crypt code is fixed. Or simply give up on bee crypt. Even though I have a good signature now I only have a few signatures left on my key, and anyone who verifies the RPM will fetch the full key (replete with rpm signature verification busting DSA signatures) from the key server and be unable to verify. So I'm fucked either way. I think at this point I'm going to generate a DSA key-pair for code-signing, and sign it with my RSA key as a work around as I can see this mess having repercussions for years as people slowly upgrade to the future version in which you fix this. btw if microsoft did something analogous to this and broke code signing they'd be roundly lambasted for breaking security. It arguably by reconning would warrant a security fix pushed via the redhat update, except even that wouldn't fix the problem as lots of people don't use it, and I presume it was already broken in rpm 4.1, and so no one in their right mind would sign an RPM with an RSA key. This seems like a case of "fixing" what wasn't broken with devastating consequences which are going to be felt for years. I think practically you've just killed RSA keys as RPM signing keys from here on out. Adam
btw the default gpg gpg.conf file includes: no-force-v3-sigs with the result that gpg by default creates v4 sigs, and then you get error, which I'm presuming means the sig goes unchecked: % rpmbuild -ba --sign /usr/src/redhat/SPECS/hashcash-0.26.spec only V3 signatures can be verified, skipping V4 signature only V3 signatures can be verified, skipping V4 signature so to fix this the user can uncomment that line in his gpg.conf file. But a better fix is to add the -force-v3-sigs option to the gpg command in /usr/lib/rpm/macros. there is I think an analogous option for pgp to achieve the same thing there.
You're not exactly f*cked, gpg can still be used to verify signatures, see /usr/lib/rpm/tgpg. rpm implements signature verification internally for performance. Writing files and invoking gpg helper are not exactly lightweight operations. And beecrypt, not libgcrypt, was used for the implementation in rpm because at the time, libgcrypt was GPL, not LGPL (rpm is LGPL only). In fact, a seperate and independent OpenPGP implementation based on beecrypt in rpm had some small role in the GPL -> LGPL libgcrypt decision. Or so I'm told <shrug> ... Yes, the OpenPGP implementation in rpm is deficient in many ways from a crypto POV. That's why rpm is a package manager, not a crypto implementation. Yes, it is very unfortunate that key servers are delivering pubkeys that cannot be directly used by rpm --import. There are other means to transport OpenPGP pubkeys, however. I'd suggest generating a key that is useful for signing packages rather than attempting to sign with whatever key you happen to use. No matter what: There are definite security advantages to verifying package metadata when read, even if the implementaion is clunky and primitive atm.