Recently, we were alerted that when receiving the Puppet Labs gpg
signing key from a keyserver, a user was offered two keys.
The key exchange went something like this:
# gpg --fingerprint --search-keys 0x4BD6EC30
gpg: searching for "0x4BD6EC30" from hkp server
pgp.mit.edu
(1) Puppet Labs Release Key (Puppet Labs Release Key) <
in...@puppetlabs.com
4096 bit RSA key 4BD6EC30, created: 2010-07-10
(2) Puppet Labs Release Key (Puppet Labs Release Key) <
in...@puppetlabs.com
4096 bit RSA key 4BD6EC30, created: 2010-07-10
Keys 1-2 of 2 for "0x4BD6EC30". Enter number(s), N)ext, or Q)uit >
GPG offers no way of differentiating between the two keys at this
stage, even though one is from us and one is not.
Researching the problem turned up
https://evil32.com, where some folks
have brute forced short key collisions on the strong set of the web of
trust. Our keys were used in their example of how
to compromise tarball signatures on this page:
https://evil32.com/examples.html
This is a problem for anyone verifying our packages/tarballs using gpg
short key IDs, which was the method formerly recommend in our our
documentation.
0x1054B7A24BD6EC30 is the long key ID of the real signing key, and it
has been signed by some previous and current employees. Its
fingerprint is 47B3 20EB 4C7C 375A A9DA E1A0 1054 B7A2 4BD6 EC30.
0x0F65842D4BD6EC30 is the long key ID of the collision key and its
fingerprint is 22A6 C997 D0F3 2A3D 984B BE13 0F65 842D 4BD6 EC30. It
has since been revoked by the authors of
evil32.com.
While the colliding key has been revoked, this is a good opportunity
to recommend some best practices for validating our tarballs using
gpg.
First, always get the gpg key directly from us. This allows the use of
authenticated https instead of http, which gpg keyservers default to.
Here is an easy way to import our gpg key using https:
# wget -O -
https://downloads.puppetlabs.com/puppetlabs-gpg-signing-key.pub
| gpg --import
Second, always validate the fingerprint of the key matches what you
expect. The fingerprint of our key should match what was listed above.
The fingerprint can be shown using `gpg --fingerprint
0x1054B7A24BD6EC30`. Some versions of gpg will show the fingerprint
when files are verified. In the following example, the last line shows
the fingerprint of the matching key:
# gpg --verify puppet-3.6.2.tar.gz.asc puppet-3.6.2.tar.gz
gpg: Signature made Tue 10 Jun 2014 12:44:55 PM EDT using RSA key ID 4BD6EC30
gpg: Good signature from "Puppet Labs Release Key (Puppet Labs Release
Key) <
in...@puppetlabs.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 47B3 20EB 4C7C 375A A9DA E1A0 1054 B7A2 4BD6 EC30
Finally, when listing keys, if "--keyid-format LONG" is passed to gpg,
it will list the full long key IDs instead of short IDs, as shown
below. This should make differentiating between keys with matching
short IDs easier.
# gpg --keyid-format LONG -k 0x4BD6EC30
pub 4096R/1054B7A24BD6EC30 2010-07-10 [expires: 2016-07-08]
uid Puppet Labs Release Key (Puppet Labs
Release Key) <
in...@puppetlabs.com>
pub 4096R/0F65842D4BD6EC30 2010-07-10 [revoked: 2014-09-11]
uid Puppet Labs Release Key (Puppet Labs
Release Key) <
in...@puppetlabs.com>
Many thanks to duritong on IRC, who alerted us to the collision, and
to evil32 for revoking their colliding key.
--
Matthaus Owens
Puppet Labs
Join us at PuppetConf 2014, September 20-24 in San Francisco -
www.puppetconf.com