Mailing List Archive

Insert certificate into agent for existing key?
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?

Thanks,

Brian.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Insert certificate into agent for existing key? [ In reply to ]
On 2/7/21 1:09 PM, 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?

Hi,
this was discussed in the following two bugs in context of pkcs11 keys,
but without any definite solution.

https://bugzilla.mindrot.org/show_bug.cgi?id=2472
https://bugzilla.mindrot.org/show_bug.cgi?id=2808

To support this, we would need and update of ssh-agent protocol (or
extension) and some variant of a patch in the first bug above.

Regards,
--
Jakub Jelen
Senior Software Engineer
Crypto Team, Security Engineering
Red Hat, Inc.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Insert certificate into agent for existing key? [ In reply to ]
On 08/02/2021 12:58, Jakub Jelen wrote:
> this was discussed in the following two bugs in context of pkcs11
> keys, but without any definite solution.
>
> https://bugzilla.mindrot.org/show_bug.cgi?id=2472
> https://bugzilla.mindrot.org/show_bug.cgi?id=2808

Thanks for those references.

I'm not sure I understand the last comment
<https://bugzilla.mindrot.org/show_bug.cgi?id=2808#c2>:

"BTW You can use certificates in ssh already using keys stored in an
agent or token. Certificates are grafted to external keys at
authentication time if they are available."

I *think* it's saying that you can authenticate using a private key in
an agent together with a corresponding id_xxx.cert file on the
filesystem.  But that means if you download your certificate from
somewhere, you have to write it to the filesystem in a suitable
location. Also, if you're doing multiple login hops using agent
forwarding, you'd have to copy the certificate to each hop where the ssh
client runs to ssh to the next hop.  Is that right?

Alternatively: you could reload your private key and cert together into
the agent . That would presumably require re-unlocking the private key
with passphrase, and wouldn't work for private keys stored in hardware
tokens.

Thanks,

Brian.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Insert certificate into agent for existing key? [ In reply to ]
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@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@openssh.com"
string certificate blob
mpint dsa_priv

ECDSA

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

ED25519

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

ECDSA/FIDO

string "sk-ecdsa-sha2-nistp256-cert-v01@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@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.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Insert certificate into agent for existing key? [ In reply to ]
On 09/02/2021 23:51, Damien Miller wrote:
>> 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.

That's how to send a (private key, certificate) pair - I have that
working already, thanks to the go x/crypto/ssh/agent library.

However, the question was whether it's possible to send just a
certificate by itself, which corresponds to a private key that the agent
already has.  And at the moment, I think the answer is "no you can't".

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Insert certificate into agent for existing key? [ In reply to ]
On Wed, 10 Feb 2021, Brian Candler wrote:

> On 09/02/2021 23:51, Damien Miller wrote:
> > > 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.
>
> That's how to send a (private key, certificate) pair - I have that working
> already, thanks to the go x/crypto/ssh/agent library.
>
> However, the question was whether it's possible to send just a certificate by
> itself, which corresponds to a private key that the agent already has.  And at
> the moment, I think the answer is "no you can't".

No - there's a patch to support it at
https://bugzilla.mindrot.org/show_bug.cgi?id=2472 but I'm not sure it's
the correct approach.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev