10 November 2008

rpm -import of GPG keys, revisited

Dbacks at the BOB
Color commentary guy

Okay, I guess I covered too much too fast last time I discussed adding a signing key to RPM. Let's do it again with more annotation and color commentary.

The RPM package manager (see: the old RPM.ORG website, which I maintained as 'rpm.org' for several years; JBJ's 'way forward' for RPM development site; and the rather sparse, intentionally stale, and to me useless site controlled by and populated to suit the Red Hat corporate agenda -- details of the fork in RPM are out of scope here) has the capability to verify through strong cryptography that a package is intact, and is counter-signed by a person in possession both halves of an asymmetric public and private keypair. Assuming that reasonable care (where 'reasonable' is a very large and paranoid number) is used to protect the confidential nature of the private half, the chances of a successful substitution are vanishingly small.

Anyone can examine and inventory the keys in RPM's trusted keystore. The process of additions, changes, and deletions of keys is an operation requiring root level privileges, and so assuming a machine can be trusted (both network level and local physical level attacks need to be considered)

Enumerate the keys present:

$ rpm -qa gpg\*

Examine a specific key:

$ rpm -qi gpg-pubkey-e8562897-459f07a4

If we know or can determine the 'fingerprint' of the public half of a signing key, and if that key has been placed at a public keyserver, we can retrieve it, examine it, or even directly import it. For the sake of this example, we again consider the Raw Hide SRPM signing key (with the re-organizations over time, Red Hat presently signs Raw Hide content with key: 0x4F2A6FD2 which the MIT keyserver identifies thus)

The CGI query on the link above used the 'op=index' modifier; the next uses the 'op=get' -- one assumes 'op' is shorthand for the type of query operation made -- terse, or key-bearing. In any event, we retrieve the key into a local file thus:

$ wget -O fedora-key "http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x4F2A6FD2"

and then may examine it with the conventional 'nix tools:

$ less fedora-key
<title>Public Key Server -- Get ``0x4F2A6FD2
''</title><p>
<h1>Public Key Server -- Get ``0x4F2A6FD2
''</h1><p>
<pre>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: PGP Key Server 0.9.6

mQGiBD+dnTsRBACwnlz4AhctOLlVBAsq+RaU82nb5P3bD1YJJpsAce1Ckd2sBUOJ
D11NUCqH8c7EctOquOZ5zTcWxHiWWbLyKQwUw2SUvnWa5SSbi8kI8q9MTPsPvhwt
... snip ...
r/T7zLrJeiljDxvX+6TyawyWQngF6v1Hq6FRV0O0bOp9Npt5zqCbDGs/iE4EGBEC
AAYFAj+dnTwAEgkQtEJp0E8qb9IHZUdQRwABAf/+AJwNVicN6A0I7EOfWx50PDHD
7SHw5wCfUJkeh/XlCrGdPASe/AXZB44jl2c=
=aXEw
-----END PGP PUBLIC KEY BLOCK-----
</pre>


The important thing to notice, amid the HTML markup, is that the key is 'armoured text' well set off with start and end markers, so that GnuPG (and also RPM) may pick the key out of the chaff.

We discussed previously the chain of steps we used to decide that the key was authentic, and worthy of trust; as such we do not repeat them here.

Then, using the 'sudo' command to temporarily attain 'root' rights for the importation step, we can insert (import into the RPM database) the locally checked key:

$ sudo rpm -import fedora-key

Or, assuming that we will do a post-insertion check, we can do the import directly from the keyserver:

$ sudo rpm -import "http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x4F2A6FD2"

Then we can re-inventory keys, and see the new one present, and the full name under which it may be found; part of the name is, conveniently, the 'fingerprint' of that key.

$ rpm -qa gpg\*
$ rpm -qi gpg-pubkey-4f2a6fd2-3fcdf8c9


Hopefully this clears things up a bit.