Monkeysphere is a project to verify identities of sites using the PGP web of trust. For example, you can verifiy SSH keys using the WoT, rather than by getting fingerprints directly from the server admin (or however it is that you currently decide to accept SSH keys. You don't just accept them without checking, do you? :p). The Monkeysphere docs have details on common tasks.

Maintaining a client SSH key

You can generate a new SSH key attached to your PGP key with

$ monkeysphere gen-subkey

Which adds a new RSA subkey to your gpg keyring. The new key is set to never expire, so you may want to set an expiration date by hand (See GnuPG maintenance).

You can export your new public key in the usual OpenSSH format with

$ monkeysphere keys-for-userid "Jane Doe <jdoe@example.com>"
ssh-rsa ...==

You can then use this public key in the usual way (see my SSH post), if you don't want to use Monkeysphere to manage your ~/.ssh/authorized-keys file automatically.

You can add the private part of your RSA key to your ssh-agent with

$ monkeysphere subkey-to-ssh-agent

If you're running an OpenSSH version >=5.7p1 and <5.9, you may be bit by this OpenSSH regression. If you are affected by this bug but don't want to recompile a patched OpenSSH, you can work around the problem with these changes to the current Monkeysphere source (the patch also removes the passphrase prompt, so you should only use the patch if you're using GnuPGv2+, which uses pinentry for out-of-band passphrase entry).

You can list the current SSH keys in your agent with ssh-add -l.

You can get the OpenSSH fingerprint for a key with

$ monkeysphere sshfprs-for-userid "Jane Doe <jdoe@example.com>"
01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef

By default, monkeysphere will fetch that key from a keyserver if you do not already have it in your keyring (see MONKEYSPHERE_CHECK_KEYSERVER in monkeyserver(1)).

Maintaining a host SSH key

Import a SSH key with

$ monkeysphere-host import-key /path/to/secret/key ssh://server.example.net
ms: host key imported:
pub   2048R/01234567 2011-05-28
uid                  ssh://server.example.net
OpenPGP fingerprint: 0123456789ABCDF0123456789ABCDF0123456789
ssh fingerprint: 2048 01:23:45:67:89:AB:CD:EF:01:23:45:67:89:AB:CD:EF (RSA)

Show known keys with

$ monkeysphere-host show-keys

If you don't want to publish this key on a public keyserver, you can export it using the usual

$ GNUPGHOME=/var/lib/monkeysphere/host/ gpg --no-permission-warning --armor --export 01234567
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----

where /var/lib/monkeysphere/host/ is the location in which monkeysphere-host keeps its keyrings and --no-permission-warning ignores the group read/write/execute permissions I'd set there so I could run monkeysphere-host as my usual user.

Once you've created the host key, you'll need to sign it. Import the key as your usual user and run

$ gpg --sign-key '=ssh://server.example.net'

You can list current signatures on the key with

$ gpg --check-sigs '=ssh://server.example.net'

Now post that signed key somewhere (e.g. a keyserver). You should also probably import the signature into the monkeysphere-host keyring:

$ gpg --armor --export '=ssh://server.example.net' \
  | GNUPGHOME=/var/lib/monkeysphere/host/ gpg --no-permission-warning --import

Checking a host SSH key

Once you have a signed host key on your keyring, you can check the fingerprints with the same command you use check user fingerprints:

$ monkeysphere sshfprs-for-userid 'ssh://server.example.net'

You can add known_hosts entries for any host in your keyring with

$ monkeysphere update-known_hosts 'server.example.net'

and update any hosts in your known_hosts file that monkeysphere already knows about with

$ MONKEYSPHERE_CHECK_KEYSERVER=false monkeysphere update-known_hosts

Without the MONKEYSPHERE_CHECK_KEYSERVER=false, monkeysphere will search the keyserver for current keys which may be useful when you don't yet have a key for that server, or if you're worried the key you have may be out of date (expired, revoked, etc.).

Validating HTTPS connections

The OpenPGP side of this is similar to the SSH protocol, with public keys for https://server.example.net etc. stored in your keyring. There's a neat little server msva-perl that checks your trust in a particular (context, peer, PKC type, peer type, PKC data) tuple (e.g. (https, server.example.net, x509pem, server, cert.pem)), which you can do by hand (via msva-query-agent). There's also a XUL extension (works in Firefox and related tools) that uses the msva server to validate HTTPS connections automatically. Nice.

If you don't want to use the the validation agent and plugin, you can verify keys by hand using openpgp2pem (this patch has not yet been accepted upstream).

$ gpg --export 'https://server.example.net' | openpgp2pem | openssl rsa -in /dev/stdin -pubin -text
Public-Key: (1024 bit)
Modulus:
    00:ae:0b:...
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

Compare the modulus and exponent with those listed for the public key offered by the target server.

Packages

I've added app-crypt/monkeysphere, app-crypt/msva-perl, and virtual/monkeysphere-validation-agent ebuilds to my Gentoo overlay, as they are not currently in the base tree.