webauthn signatures: SecurityKeyProvider, json parsing

Scott C Wang wangsc at cs.wisc.edu
Wed Jan 12 16:05:52 AEDT 2022


Awesome! Thank you, Damien.

> AFAIK clientData is
> prepared from origin, extensions and H(message), so there's not need
> to pass that explicitly.

The trouble with not passing clientData is that the spec reserves the right to append new keys to it in the future. To validate the signature, the OpenSSH server has to be apprised of the entire clientData blob returned from the webauthn API. Ergo, the OpenSSH client does need to be passed the entire clientData blob explicitly, as opposed to reconstructing it, lest there be extra keys. (Chromium already randomly appends an extra "reminder" key to break implementations that attempt such a construction. [0])

> As far as communicating with the webauthn signer via the ssh-sk API,
> nothing in OpenSSH uses the extensions field and the existing
> application field could be used to pass origin.

Are you referring to passing in, or passing back? Does "extensions" refer to the authenticatorData attestedCredentialData and extensions [0]? If so, then the SecurityKeyProvider will need to pass those back to OpenSSH so that the server can include them in the hash computation, even if it doesn't parse them.

Could you clarify what you mean by passing back the origin in the "existing application field"? Since the origin is part of clientData, which as discussed above the SecurityKeyProvider needs to pass back anyway, the OpenSSH client can parse it out of there to populate the signature with.

> That just leaves signalling that the signer wants an origin rather
> than a bare application, and signalling back from the signer that the
> signature should be packed as a webauthn one.

To be clear, the SecurityKeyProvider will want the application ("mindrot.org") from the key, as opposed to the origin. The SecurityKeyProvider will pass the application into the webauthn credential request as the relying party ID. Nobody knows the origin ("https://www.mindrot.org") until it appears as the output of the webauthn credential request as part of the clientData.


Scott C Wang

[0] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/content/browser/webauth/client_data_json.cc#146



From: Damien Miller <djm at mindrot.org>
Sent: 11 January 2022 16:33
To: Scott C Wang <wangsc at cs.wisc.edu>
Cc: openssh-unix-dev at mindrot.org <openssh-unix-dev at mindrot.org>
Subject: Re: webauthn signatures: SecurityKeyProvider, json parsing 
 
On Tue, 11 Jan 2022, Scott C Wang wrote:

> Damien, thanks for clarifying.
> 
> (1 SecurityKeyProvider)
> 
> I don't have a FIDO security key, but I do have an Android phone, and
> the Android phone can act as a webauthn key via Google Chrome. So
> these were the shower thoughts I had for getting this to work.
>
> I implement a SecurityKeyProvider that prints a https URL upon
> sk_sign. I open this URL in Google Chrome. The script on the page
> calls the webauthn authentication API; Google Chrome prompts
> me to choose an authentication method, and I pick my phone.
> Authenticating my fingerprint on my phone yields a webauthn signature
> to the script, which POSTs the signature, origin, clientData, and
> extensions back to the same URL. The SecurityKeyProvider polls
> the URL (or some endpoint) until the signature arrives, which it
> returns, along with the origin, clientData, and extensions, to the
> OpenSSH client. The OpenSSH client now has what it needs to pack a
> "webauthn-sk-ecdsa-sha2-nistp256 at openssh.com" signature message, all
> of which the OpenSSH server currently already supports validating.
>
> More generally, this one SecurityKeyProvider implementation would be
> able to bridge the OpenSSH client's security key authentication to any
> platform running a web browser exposing the webauthn API.
>
> I've only given preliminary thought to this as yet -- have I gone mad?

No, I've wondered about the same thing too :)

As far as communicating with the webauthn signer via the ssh-sk API,
nothing in OpenSSH uses the extensions field and the existing
application field could be used to pass origin. AFAIK clientData is
prepared from origin, extensions and H(message), so there's not need
to pass that explicitly.

That just leaves signalling that the signer wants an origin rather
than a bare application, and signalling back from the signer that the
signature should be packed as a webauthn one.

Am I missing anything? (I apologise for forgetting most of the details
since I implemented webauthn in OpenSSH)

> (2 json key order) Perfect! Very prudent.
>
> (3 mindrot.org) Excellent, thank you for the link. (I was trying
> /webauthn.html, but hadn't thought to try /webauthn.) Perhaps
> the hardcoded "mindrot.org" relying party can be changed to
> window.location.host, so that the standalone page can be hosted
> without modification on anyone's domain.

good idea - done.

-d


More information about the openssh-unix-dev mailing list