At present whenever non-resident keys are used the key_handle required to use the token must be given by selecting the ssh 'private key' file generated by ssh-keygen during negotiation. In the more common webauthn context this key_handle would be stored on the server and then transmitted to the client during authentication. The client then checks connected tokens for one that reports it understands that key_handle and can sign on its behalf. Compared to SSH this approach means there are no external files required to use the hardware key (use is just plug and play). The initial patches for U2F added it as a new authentication method and were dropped in favour of the current implementation where it is mostly just another key type with an external signature provider. This is a less invasive change but means that the information required to do a more 'typical' negotiation supporting this plug-and-play use isn't available. However that degree of plug-and-play is desirable in some circumstances. Particularly those where the user may be logging in from different transient machines. The current method requires the user to carry around the security key as well as the 'private key' on a USB stick so that both can be accessed. Not fatal by any means, but not ideal compared to a more typical webauthn flow. (onto the questions) Firstly, would the following or some combination thereof be possible or is there an obvious impediment. Secondly, if it proved possible are the maintainers open to a patch providing it? 1. Update the SSH ecdsa-sk public key type to contain the key_handle and other relevant details (it doesn't contain sensitive information or accessible key material so this is safe to do) 2. Add a method to send a list of understood *-sk" publickeys from authorized_keys to the client An appropriate method to implement #2 without reverting to the more invasive alternate-auth-method would seem to be via SSH extensions (RFC8308). If both the client and the server signal their support for the extension a list of known *-sk keys could be sent after a user is selected. This would then let the client select a key without needing the private key file. This should also prevent any incompatibilities between clients with and without support. They can use the external file the same as they do now. Comments?
Damien Miller
2020-Jul-21 04:47 UTC
Automatic FIDO2 key negotiation (request for comments)
On Mon, 20 Jul 2020, Jordan J wrote:> At present whenever non-resident keys are used the key_handle required > to use the token must be given by selecting the ssh 'private key' file > generated by ssh-keygen during negotiation. > > In the more common webauthn context this key_handle would be stored on > the server and then transmitted to the client during authentication. > The client then checks connected tokens for one that reports it > understands that key_handle and can sign on its behalf. Compared to > SSH this approach means there are no external files required to use > the hardware key (use is just plug and play). > > The initial patches for U2F added it as a new authentication method > and were dropped in favour of the current implementation where it is > mostly just another key type with an external signature provider. This > is a less invasive change but means that the information required to > do a more 'typical' negotiation supporting this plug-and-play use > isn't available.Right, this was an deliberate decision. Another motivating factor was being able to use existing non-OpenSSH SSH tooling and workflows with only small changes.> However that degree of plug-and-play is desirable in some > circumstances. Particularly those where the user may be logging in > from different transient machines. The current method requires the > user to carry around the security key as well as the 'private key' on > a USB stick so that both can be accessed. Not fatal by any means, but > not ideal compared to a more typical webauthn flow. > > (onto the questions) > > Firstly, would the following or some combination thereof be possible > or is there an obvious impediment. Secondly, if it proved possible are > the maintainers open to a patch providing it? > > 1. Update the SSH ecdsa-sk public key type to contain the key_handle > and other relevant details (it doesn't contain sensitive information > or accessible key material so this is safe to do) > 2. Add a method to send a list of understood *-sk" publickeys from > authorized_keys to the clientI'm not keen on making the public keys contain the key handle. IMO being able to offer some protection of the key handle on disk by setting a password on the key is valuable and we'd lose that if everything were public by default.> An appropriate method to implement #2 without reverting to the more > invasive alternate-auth-method would seem to be via SSH extensions > (RFC8308). If both the client and the server signal their support for > the extension a list of known *-sk keys could be sent after a user is > selected. This would then let the client select a key without needing > the private key file. This should also prevent any incompatibilities > between clients with and without support. They can use the external > file the same as they do now.If you do this, then you don't need step #1 at all: the server could send the key handles registered for a user at the start of userauth and the client could proceed to match them against their available hardware authenticators and return a signature using one. -d
> Right, this was an deliberate decision. Another motivating factor > was being able to use existing non-OpenSSH SSH tooling and workflows > with only small changes.Hopefully with extensions this can keep that benefit!> I'm not keen on making the public keys contain the key handle. IMO > being able to offer some protection of the key handle on disk by > setting a password on the key is valuable and we'd lose that if > everything were public by default. > [snip] > If you do this, then you don't need step #1 at all: the server > could send the key handles registered for a user at the start > of userauth and the client could proceed to match them against their > available hardware authenticators and return a signature using one.I was thinking putting the key_handle in the public key is potentially an easy way to inform the server of the key handles using the existing add authorized key flow; but I can understand the desire to be able to password it. As the private key contains the public key as well as the key handle, is there any reason we couldn't allow people to upload the (not passworded) private key file to authorized_keys as a way of specifying both? It's useless without the hardware key anyway. That also provides a way for the user to choose if they want to avail of the feature by which key file they upload and do so on a per-key basis if they choose. It's a very subtle way of enabling a feature though that people probably wouldn't intuit so it'd need to be clearly documented - but that shouldn't be an issue. I'm trying to avoid something that would add new configuration files if it's not necessary, but a seperate file for a list of key handles the user wants to advertise is also an option of course.
James Bottomley
2020-Jul-26 16:34 UTC
Automatic FIDO2 key negotiation (request for comments)
On Tue, 2020-07-21 at 14:47 +1000, Damien Miller wrote:> On Mon, 20 Jul 2020, Jordan J wrote:[...]> > Firstly, would the following or some combination thereof be > > possible or is there an obvious impediment. Secondly, if it proved > > possible are the maintainers open to a patch providing it? > > > > 1. Update the SSH ecdsa-sk public key type to contain the > > key_handle and other relevant details (it doesn't contain sensitive > > information or accessible key material so this is safe to do) > > 2. Add a method to send a list of understood *-sk" publickeys from > > authorized_keys to the client > > I'm not keen on making the public keys contain the key handle. IMO > being able to offer some protection of the key handle on disk by > setting a password on the key is valuable and we'd lose that if > everything were public by default.Your worry is that webauthn isn't true two factor because it's only based on a thing you possess rather than both a thing you know and a thing you possess? I agree, I've always thought the ability to steal someone's token was a big flaw in the scheme. However, it is trivially fixable: if you encrypt the fido key handle with a passphrase before sending it to the remote then even if I steal your token, I still can't use it to access your account because when the remote presents the encrypted key handle I don't know the passphrase to decrypt it. This double encryption scheme should work for openssh public keys containing the key handle as well. The only drawback is that to change the passphrase you now have to change every public key in every account you possess. James
Possibly Parallel Threads
- Automatic FIDO2 key negotiation (request for comments)
- Agent protocol changes related to U2F/FIDO2 keys
- Incomplete attestation data for FIDO2 SKs?
- [Bug 3748] New: "webauthn-sk-ecdsa-sha2-nistp256@openssh.com" signature type not supported from ssh agent
- U2F support in OpenSSH HEAD