wiki:OpenPGPandSSH

Version 14 (modified by dkg, 5 years ago) (diff)

--

Using OpenPGP certificates with SSH connections

This page tries to document a proposal for using OpenPGP certificates with SSH connections.

Goals

  • Use all free software
  • Use OpenPGP certificates for authentication in both directions (client->server and server->client)
  • Authorization should use User IDs, not keys
  • Key revocation/transition should be straightforward and effective without explicit notification of individual hosts or users
  • End users and server administrators should be able to choose who they trust to properly identify/introduce other entities during authentication
  • Any implementation should be cleanly interoperable with a non-OpenPGP-capable SSH implementation
  • Minimize the amount of patching of upstream sources. Ideally, people should be able to use this framework with the existing tools

Overview

OpenSSH provides a functional way for management of explicit RSA keys (without certification of any type). The basic idea of this project is to create a framework that uses GPG's keyring manipulation capabilities and public keyservers to generate files that OpenSSH will accept and handle without complaint.

Both entities in an OpenSSH connection (client and server) thus have the responsibility to explicitly designate who they trust to "introduce" others. They can explicitly indicate this trust relationship with traditional GPG keyring trust indicators. No modification is made to the SSH protocol on the wire, which continues to use raw RSA public keys.

Simplifying Assumptions

These assumptions might not be necessary, but we'll humor them for the sake of a clean implementation at the moment.

  • Only use RSA keys, since RSA is known to work with both OpenSSH and GPG.
  • This framework will use a specialized keyring, so that explicit trust relationships mapped here don't necessarily overflow into other OpenPGP-covered domains.
  • A redundant set of public keyservers is available for both client and server to access (both query and upload) at will.

Key Translations

How do we use the same key for GPG and OpenSSH?

Private Keys

At the least, we need to have a way to convert the private key from one format to another. While i have no problem using an OpenSSH-generated RSA private key as the private part of an X.509 key/cert pair (and vice versa), i'm having difficulty figuring out how to translate the PEM-encoded RSA keys into OpenPGP-encoded RSA keys.

This conversion should be do-able by reading the OpenPGP spec for Secret Key packet formats and the RSA encryption standard's Private Key Syntax. It's also possible that GnuTLS (which is capable of dealing with both OpenPGP and TLS) might be able to do the conversion.

Public Keys

We'll also probably need to be able to translate public keys, since the keyservers will offer OpenPGP-formatted public keys, but OpenSSH's ssh-keygen can convert from the IETF's SECSH Public Key Format, which is different. AFAICT, ssh-keygen isn't capable of converting from an OpenPGP public key. When i try it, i get:

0 dkg@ape:~/.keys$ ssh-keygen -i -f gpg.pubkey 
uudecode failed.
1 dkg@ape:~/.keys$ 

Validating the User

The server's job when a connection is created is to authenticate an incoming request, and to verify that the authenticated entity is authorized to connect.

Identification

When an RSA public key is offered to the server by a user proposing to make a connection, it is looked up in the user's authorized_keys file. The framework's job is therefore to populate that file with the public keys that should be acceptable.

Authenticating the Server

When initiating a connection, a user needs to verify that she is actually connecting to the specific host she expects it to be.

OpenPGP Host User ID format

To get an OpenPGP certificate to identify an SSH host, there needs to be a binding between a User ID and a public key where the User ID unambiguously specifies the SSH host. The OpenPGP Spec indicates that the User ID packets can be arbitrary UTF-8 strings, though by convention they are RFC 822 addresses, but that this is not a requirement.

I'm unaware of any registry of definitions of other forms of User ID. In the absence of other definitions, i'd like to propose that the relevant User ID should look like this:

ssh://monkey.example.net

Specifically, it should be formatted in accordance with the draft for ssh URIs, but with no username, and the path-abempty part entirely empty.

With gpg, this may require the use of --allow-freeform-uid

Fetching a host key

A user should be able to query a public keyserver for a hostkey matching the pattern mentioned. Could we do such a check

Key revocation

How does key revocation work? How can we be sure that a revoked key is no longer accepted within a reasonable period of time after the revocation takes place?

Key transitions

Say a user or a host needs to change keys. How can a new key be adopted smoothly without explicit notification of all the relevant hosts?

Open Questions

Protecting public keyservers from DoS attacks

If anyone can upload keys to a public keyserver, how do we keep them from being drowned in irrelevance? How do we avoid DoS attacks of various sorts?

Other Work

Resources

What tools might come in handy for this project?