Question about webauthn signatures?
djm at mindrot.org
Fri May 7 12:41:17 AEST 2021
On Thu, 6 May 2021, Tyson Whitehead wrote:
> > The webauthn signature type (note: note a key type) was added to support
> > browser-based SSH clients that can only interact with FIDO keys via the
> > webauthn APIs. These APIs do not allow "bare" FIDO signatures, but
> > implictly include weborigin information in the signed data.
> Thank you for the clarification. I believe I understand now it is for the
> signature in the SSH_MSG_USERAUTH_REQUEST when the client only has access to
> the device via the webauthn API. That makes sense.
> Many of our non-unix savvy users just use passwords as settings up keys is
> difficult for them. From reading up on the FIDO2 standard, it would seem that
> it should be possible to just have server-side FIDO2 keys. This could be a
> huge plus as we could generate and register these keys on our clusters for
> them off our website. They could just use them without having to setup
> anything on their end.
That's true of FIDO web authentication. What we implemented in SSH
(ab-)uses the FIDO spec to fit SSH's existing publickey user
authentication, because users and lots of tooling is built around that.
This unfortunately precluded the use of server-side keys, as there is no
mechanism for the server to communicate key handles to the client.
I do have vague plans to do a more web-like FIDO authentication method
for OpenSSH in the future, but haven't got around to it yet.
> I was looking at RFC4252 (The SSH Authentication Protocol) to see if
> FIDO2-based server-side could be retrofitted into the SSH protocol, and it
> seemed to me like it could be done. Specifically, the "publickey"
> authentication protocol has the client send
> byte SSH_MSG_USERAUTH_REQUEST
> string user name in ISO-10646 UTF-8 encoding
> string service name in US-ASCII
> string "publickey"
> boolean FALSE
> string public key algorithm name
> string public key blob
> and the server respond with
> byte SSH_MSG_USERAUTH_PK_OK
> string public key algorithm name from the request
> string public key blob from the request
> so I am thinking it could be (slightly) abused by
> 1. creating a another esk-ecdsa key type where the key handle was stored with
> the public key
> 2. have the client pass an empty "public key blob" when sending the
> SSH_MSG_USERAUTH_REQUEST message for this key type
> 3. have the server respond back with the key handle (or the entire public key
> with the key handle) in the "public key blob" of its SSH_MSG_USERAUTH_PK_OK
> Support for multiple keys could be done by having repeated queries return
> subsequent ones. The server could also reply with fakes to avoid leaking
> information about whether any such keys actually exist.
I was thinking something like:
string service name
string "fido-discover-v00 at openssh.com"
(this message number was defined for GSS authentication, w/
SSH_MSG_USERAUTH_INFO_REQUEST always going in the s->c direction and
SSH_MSG_USERAUTH_INFO_RESPONSE always going c->s).
where each key_info member contains
string key handle
The client could then try the key handles supplied against their attached
security keys to find one that will sign a challenge and then make a
regular public key authentication attempt:
string service name
The protocol bits are pretty easy, the UI is a bit more complicated. The
main problem is that we need some way to store the keys eligible for
fido-discover-v00 at openssh.com.
One possibility is marking them using some tag in authorized_keys, but
the information we need to return is more than currently exists in the
sk-* public key formats. So we'd need a new encoding that stores the
extra information and likely some ugly special-casing to glue it all
Perhaps authorized_keys entries like
fido[,option...] sk-ecdsa-sha2-nistp256 at openssh.com pubkeyblob keyhandleblob
flags would be reconstructed from the options listed on the key:
no-touch-required, verify-required, etc.
Another alternative would be to define a pubkey blob format that includes
all the information. Not sure which is nicer...
> > regress/unittests/sshsig/webauthn.html in the source distribution. If you
> > stick it on a web server then you can generate FIDO keys and webauthn
> > signatures that you can verify using ssh-keygen -Y. It's the basis of
> > the webauthn signature unit tests.
> private key to see if we could do the key generation sever side in order to
> make things easier for our non-unix-savvy users
ah good idea, this inspired me to add a similar feature to mine now too.
> The resulting keys seem to work fine in SSH, which makes me think, if SSH
> could support pure server-side key, and we could generate these keys with
> Webauthn, it would actually make things even easier for our non-unix-savvy
> users (buy a key, press a button on our website to register it) while really
> tightening up user accounts and thereby decreasing the attack vectors against
yep, agree. I think a FIDO-style authn method would be a nice addition.
More information about the openssh-unix-dev