Insert certificate into agent for existing key?

Damien Miller djm at mindrot.org
Wed Feb 10 10:51:22 AEDT 2021


On Sun, 7 Feb 2021, Brian Candler wrote:

> Does the ssh-agent protocol allow adding a certificate for a private key 
> which it already has? The idea is to issue a certificate for a key the 
> agent already has, to avoid the entropy drain of generating a new key.
> 
> https://tools.ietf.org/html/draft-miller-ssh-agent-04 shows private 
> keys, and doesn't mention certificates at all.  However it does say:
> 
> "Typically only the public components of any keys supported on a 
> hardware token will be loaded into an agent" - which suggests that the 
> SSH_AGENTC_ADD_IDENTITY message might be able to carry only the public 
> parts of a key.
> 
> https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys 
> defines new *public* key formats for certificates - they don't contain 
> the private key components as far as I can see.
> 
> However, looking at the Go ssh-agent client, it inserts a private key 
> and certificate in a single SSH_AGENTC_ADD_IDENTITY or 
> SSH_AGENTC_ADD_ID_CONSTRAINED message:
> 
> https://github.com/golang/crypto/blob/master/ssh/agent/client.go#L664
> 
> (and I haven't been able to find documentation which defines that 
> private key + certificate message format).
> 
> So basically: can I send just a certificate to ssh-agent?  And if so, 
> how is that done?

Yes, it is possible but poorly documented (patches welcome as always).
The format for encoding a certificate with private key is is roughly
{cert, private fields}. See sshkey.c:sshkey_private_serialize_opt() for
the actual code, but it's basically the following, where "certificate
blob" is the entire public certificate key.

RSA

string "ssh-rsa-cert-v01 at openssh.com"
string certificate blob
mpint rsa_n
mpint rsa_e
mpint rsa_d
mpint rsa_iqmp
mpint rsa_p
mpint rsa_q

DSA

string "ssh-dsa-cert-v01 at openssh.com"
string certificate blob
mpint dsa_priv

ECDSA

string "ecdsa-sha2-nistp256-cert-v01 at openssh.com" /
       "ecdsa-sha2-nistp384-cert-v01 at openssh.com" /
       "ecdsa-sha2-nistp521-cert-v01 at openssh.com"
string certificate blob
mpint ecdsa_priv

ED25519

string "ssh-ed25519-cert-v01 at openssh.com"
string certificate blob
string ed25519_pubkey
string ed25519_privkey

ECDSA/FIDO

string "sk-ecdsa-sha2-nistp256-cert-v01 at openssh.com"
string certificate blob
string sk_application
uint8 sk_flags
string sk_key_handle
string sk_reserved

ED25519/FIDO

string "sk-ssh-ed25519-cert-v01 at openssh.com"
string certificate blob
string ed25519_pubkey
string sk_application
uint8 sk_flags
string sk_key_handle
string sk_reserved

Note in ED25519 and FIDO key types there are some redundant fields between
the cert blob and the subsequent fields.


More information about the openssh-unix-dev mailing list