Webauthn signatures working in the wild, and client-agent support

Damien Miller djm at mindrot.org
Tue Sep 20 08:15:02 AEST 2022


On Mon, 19 Sep 2022, Carlos Cabanero wrote:

> Hey everyone!
> 
> We just added support (maybe a first?) for Webauthn keys in Blink.
> Everything seems to be working great except in one scenario, using
> them with our agent. You can see a quick demo here:
> https://twitter.com/BlinkShell/status/1570427813819486212?s=20&t=2GNv08ro2zyBcI14DK4tIA
> 
> The implementation is making use of Passkeys and Secure Keys with
> Webauthn support. I think the interesting part is how easy creating
> and using keys like this is, and maybe future use cases would showcase
> more possibilities for Webauthn keys.
> 
> This is all based on Damien Miller’s test projects (thanks a lot!) but
> as mentioned, the Client-Agent (at sshconnect2.c) will not accept
> webauthn-sk signatures at the moment. The setup is that we use our
> Agent to forward a key to the remote. Then when trying to sign with
> this key, the SSH Client is expecting a sk-ecdsa signature type, but
> our agent can only provide a webauthn-sk-ecdsa type.

Oh wow, I have not heard of anyone else using this for real before.
Nice work!

> The issue seems to be that the sign_and_send_pubkey will expect a
> sk-ecdsa signature in all cases, and not a webauthn-sk-ecdsa. We have
> been reading the code to see if we could bend things somehow, but it
> looks like everywhere that a transform from key to signature-algorithm
> happens, will always result in the sk-ecdsa type. We also tried
> different flags for Accepted Pubkeys, disabling sk-ecdsa, trying to
> set webauthn-sk type at the top, all with no luck. On the SSHD side
> when logging in, this is not an issue as both are accommodated during
> validation.
> 
> Are we missing something that could make things work? Is there
> anything from our side that we could do to try things out or to
> support this scenario?

Unfortunately this webauthn keys via the agent isn't going to
work ATM and I'm not immediately sure how to fix it.

The problem is between sshconnect2.c:sign_and_send_pubkey() and
identity_sign().

In sign_and_send_pubkey() we have to assembled the data to be
signed (basically the SSH2_MSG_USERAUTH_REQUEST we're about to
send), and that includes the signature algorithm:

>    if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
>        (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||
>        (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
>        (r = sshbuf_put_cstring(b, method)) != 0 ||
>        (r = sshbuf_put_u8(b, 1)) != 0 ||
>        (r = sshbuf_put_cstring(b, alg)) != 0 ||
>        (r = sshkey_puts(id->key, b)) != 0) {
>            fatal_fr(r, "assemble signed data");

Unfortunately, we don't learn that the key is only capable of making
webauthn signatures until we attempt signing via identity_sign() and
observe (via sshkey_check_sigtype()) that we got a webauthn signature
back.

Perhaps there should be some way for ssh-agent to signal to the client
that a particular key can only make webauthn signatures, but I'm not
sure how best to do this.

It would be best if the agent simply told the client about it but, at
the moment, the SSH_AGENTC_REQUEST_IDENTITIES agent request used to
obtain the list of keys from the agent has no extra data fields that
could be used to signal this.

Now, we could extend the agent protocol to add an extra field to
carry stuff like this, but that has a number of costs including
time-to-deploy (this is less of a problem if you control the agent
and the ssh client).

One uglier IMO option would be to use the key comment field returned by
SSH_AGENTC_REQUEST_IDENTITIES to signal that a key is webauthn only.
This is possible, but since comments are user-specified, a user could
break their key if they put the magic signalling string in a key
comment.

Another possibility is abusing the key blob format returned by
SSH_AGENTC_REQUEST_IDENTITIES and having the webauthn keys identify
themselves as webauthn-sk-ecdsa-sha2-nistp256 at openssh.com rather than
as sk-ecdsa-sha2-nistp256 at openssh.com, and add associated plumbing to
carry the webauthn-only status of these keys through to sshconnect2.c.
IDK how other tools will handle this, as it's strictly a spec
violation to use a signature algorithm name in place of a key name
(though OpenSSH has hardly been sinless in this regard historically...)

Hope this clarifies the problem a little (it sure doesn't solve it
though).

-d


More information about the openssh-unix-dev mailing list