A common feature at computer conferences is a PGP Keysigning Party, which is rather less glamorous than it sounds. The overall aim is to provide people with an opportunity to have other people confirm the match between a given PGP Key (used to sign emails, computer software, etc) and a person. With the idea that then someone who has not met them would have more reason to believe that a given PGP Key really belongs to that person. That is then useful when it comes to judging whether a piece of software (or an email) signed with a particular PGP Key is likely to be legitimate. The certainty about the origin of many free software releases relies on this process, particularly for Debian Linux.

In theory one might expect this process to involve a detailed review of whatever proof someone can provide that they really are who they say they are, before following some formal process to add a confirmation on to their key. In practice that proves to be rather time consuming when there are 50+ people hoping that 50+ people will sign their keys, so various approaches have been taken to attempt to reduce the bureaucracy.

The "keysigning parties" at Linux.Conf.au have typically been held via the Sassaman Projected method, which essentially involves someone making a list of all the keys to be signed in advance, and then the documents "proving" people's identity being projected to the whole room so that attendees can verify the details. The security of this method relies on (a) checksums on the list being calculated, (b) those checksums being projected so everyone can verify them, (c) everyone actually verifying them, and (d) each person confirming that both their details are correct in the list and that they have personally verified that the checksum of the list is as was projected at the time. And the security of the checksum algorithms being used. (Unfortunately both of these elements seem to be, umm, "less than optimal" these days; which I may write about some other time.)

A result of this is that one comes away from the keysigning party with a list of key details, and some indications of which ones legitimately associate with the stated person. In order to turn this into something useful for computers to recognise, it has to be (a) turned into PGP key signatures and (b) sent to the relevant people (eg, via email) so that when they give their PGP key to someone else, it'll have the new signtaure attached. Doing this for one key at a time, by hand, is managable; doing it for 50 keys gets painful. So I spent a little time re-setting up the automation that I'd used previously on my new computer, which involved a little translation because Mac OS X and Linux are not quite the same.

This time I used three scripts:

  1. gpgkeysign: Import and sign key with one or more secret keys
  2. sendsignedkey: Email signed key to owner (encrypted)
  3. gpg: A wrapper around the gpg tool to make it work better with gpg-agent

plus gpg and gpg-agent. (gpg-agent is a small process that stays in memory and remembers the decrypted version of your secret key for a while -- it saves typing your passphrase a lot of times if you're doing many operations with the same keys in a short period of time.)

The gpg wrapper is necessary to avoid errors like this:

gpg: cancelled by user
gpg: no default secret key: bad passphrase
gpg: [stdin]: sign+encrypt failed: bad passphrase

when trying to sign or decrypt with gpg-agent run from within a shell script; it just tries to automatically figure out what tty gpg-agent should use for authentication and set it in GPG_TTY. (There are more things it could try to identify the tty, including who am i, but I've not found them necessary yet.)

Setup

eval $(gpg-agent --daemon)     # Start GPG Agent
SOURCE_KEYRING=/path/to/keyring/file/from/party/keyring.gpg
export SOURCE_KEYRING

And ensure that the gpg wrapper script is first in the path (and has the correct path for the real binary), so that it can set GPG_TTY and add the flags to ensure the gpg-agent is consulted.

Signing keys

Go through your list of keys and pick out the ones where you're convinced that the person named actually owns that key (based on what happened at the keysigning party).

For each one run:

gpgkeysign KEYID

which will then import the key from the keyring from the keysigning party and offer you a chance to sign it with each of your secret keys.

With each key you should check the fingerprint printed by the gpg tool against the one printed in the list from the keysigning party that the person verfied was theirs. If they don't match then something has gone wrong in the verification process and you shouldn't sign the key. If they do match run:

uid 1
sign 
save

to sign the first identity. Optionally you may wish to run uid N for some other identities if you are sure that those identities are valid too (eg, from personal knowledge of where the person works or what other email addresses they have).

Sending keys

When you've signed all the keys you want to sign, you can then send them all out with:

sendsignedkey KEYID [KEYID [KEYID [....]]]

which will go through each key, show you the fingerprint information and offer to send the key. If you agree to send it, it'll create a message template and append the PGP key with your new signature to the email in encrypted form. This means that only someone who actually has the private key associated with that GPG key will be able retrieve the signature -- which is a final check that the key belongs to the right person (or at least the right email address).

OS X setup

There is one additional piece of setup required on OS X. The sendsignedkey script assumes that it can use sendmail directly to send out the message (common on most Unix systems). On OS X, postfix is installed with suitable compatibility scripts. But it doesn't start by default and may not be set up to send mail out in a way that remote systems will receive it (eg, most systems won't accept mail from dynamic IPs any longer).

To get it working one needs to do:

  1. Edit /etc/postfix/main.cf
  2. Set myhostname and mydomain appropriately (eg, something with at least a MX record and preferably reverse DNS)
  3. Set relayhost appropriately to a system which will pass the mail (and if that system needs SMTP AUTH, set up the appropriate credentials)
  4. Start postfix: sudo launchctl start org.postfix.master