Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add recovery extension #1425

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft

Add recovery extension #1425

wants to merge 5 commits into from

Conversation

emlun
Copy link
Member

@emlun emlun commented May 27, 2020

This is an attempt at solving #931 through Yubico's proposed recovery extension, as proposed in https://github.com/Yubico/webauthn-recovery-extension . Formal proofs of the security of the key generation scheme are currently awaiting peer review.

For interoperability between authenticator vendors, this would also need some additions to CTAP. A proposal for that is also included in the link above, but is outside the scope of WebAuthnn.

It might be more suitable to extract the details of the key generation algorithm to an external reference, but I don't currently know where to start in that case. Either way, I think it's useful to get some review from this working group for starters.


Preview | Diff

@emlun emlun added type:technical subtype:extensions subtype:DeviceLossAccountRecovery stat:puntable Issue or PR that is candidate to move to a later milestone labels May 27, 2020
@emlun emlun self-assigned this May 27, 2020
@equalsJeffH
Copy link
Contributor

equalsJeffH commented May 27, 2020

on 2020-05-27 call: leaving this un-triaged for now. Folks should review it. co-chairs feel it will need support of all RPs, UA vendors, authnr vendors. Proponents are not expecting it to be in L2 (update: I had miss-stated it as L3 earlier).

@emlun
Copy link
Member Author

emlun commented May 27, 2020

Proponents are not expecting it to be in L3.

L2, if I may. :)

(Not expecting this to make L2, probably more suited to L3)

@agl
Copy link
Contributor

agl commented May 30, 2020

Comments from narrow to wider:

AAGUID transmission

Doesn't seem necessary to leak this to RPs? RP learn and, if they demand, can judge attestation for recovery authenticators when a recovery is attempted. It seems that the motivation is just to follow the existing structure?

Algorithm transition

I don't believe that the group tricks for establishing the recovery authenticator's public key are needed. I think all you need is to asymmetrically encrypt a seed to the recovery authenticator and thus only scalarmults are needed. It does mean that the primary authenticator transiently has the recovery private key but, in this context, the primary authenticator is trusted — it's getting enrolled as an authenticator after all!

Having said that, while I've not worked though it in detail, I've seen this trick used for Bitcoin stuff before and I'm happy that it's sound, so it's not a big deal really. But, this does mean that it's possible to implement this pattern without groups, i.e. a post-quantum transition is possible.

But there's no algorithm negotiation, i.e. the RP should be able to say what algorithms it can support for generate.

UX

UX seems complex? Do you envision selling pre-setup packs of authenticators? As Shane points out, they could just be clones in that case (although with different security properties).

Otherwise, the UX of pairing two authenticators, making sure that the user knows which is primary and which is backup, listing backup devices (how are they named?), letting the user manage this etc, seems daunting. And, of course, RPs would have a bunch more stuff to manage.

@emlun
Copy link
Member Author

emlun commented Jun 1, 2020

AAGUID transmission

Doesn't seem necessary to leak this to RPs? RP learn and, if they demand, can judge attestation for recovery authenticators when a recovery is attempted. It seems that the motivation is just to follow the existing structure?

Indeed it's not strictly necessary, but if we don't have it the user will have no warning before the RP rejects the backup authenticator after they've already lost the primary authenticator and potentially have no other way to access their account. Transmitting the AAGUID early (although unsigned) allows the RP to fail faster and prevent the user from inadvertently getting locked out.

Algorithm transition

I don't believe that the group tricks for establishing the recovery authenticator's public key are needed. I think all you need is to asymmetrically encrypt a seed to the recovery authenticator and thus only scalarmults are needed. It does mean that the primary authenticator transiently has the recovery private key but, in this context, the primary authenticator is trusted — it's getting enrolled as an authenticator after all!

Good points; this was also asked here and replied to here. We want to as much as possible avoid sharing private keys, but maybe it's not too big a deal if it's a single-use key like we have here (the shared key isn't actually imported and used long-term).

[...] this does mean that [...] a post-quantum transition is possible.

Good observation, that should indeed work. As long as all information that needs to be passed between authenticators can be embedded into a credential ID, this can even be done without any change to RPs' code.

But there's no algorithm negotiation, i.e. the RP should be able to say what algorithms it can support for generate.

This is in part because the key generation scheme is opaque to the RP - the primary authenticator only needs to supply some kind of COSE public key for the backup credential. So it's not a matter of the RP supporting different algorithms (other than the COSE pubkey algs already used), but maybe the RP should have a say in which are acceptable. In that case we might need to make the algorithm identification a bit more sophisticated and/or standardized than the single byte we have now.

UX

UX seems complex? Do you envision selling pre-setup packs of authenticators? As Shane points out, they could just be clones in that case (although with different security properties).

At this point we don't, but it's something we could consider. Our first step would rather be implementing support for this in YubiKey Manager.

We have no plans to offer authenticators with cloned keys. That doesn't play well with signature counters, and it also doesn't solve the problem of having to manually re-register everywhere (since the backup must then also be replaced, as you can't associate a new backup with it).

Otherwise, the UX of pairing two authenticators, making sure that the user knows which is primary and which is backup, listing backup devices (how are they named?), letting the user manage this etc, seems daunting. And, of course, RPs would have a bunch more stuff to manage.

I'm confident the setup process can be made pretty straightforward in YubiKey Manager, for example. Naming is a good point, though. We've thought about it but decided it gets a bit too complicated for now, but it's probably worth reconsidering. I guess the backup names would have to be stored in the primary authenticator and delivered to the RP along with the public keys.

@agl
Copy link
Contributor

agl commented Jun 2, 2020

Transmitting the AAGUID early (although unsigned) allows the RP to fail faster and prevent the user from inadvertently getting locked out.

I don't believe that we would want to transmit AAGUIDs in a non-enterprise context.

This is in part because the key generation scheme is opaque to the RP - the primary authenticator only needs to supply some kind of COSE public key for the backup credential.

But the COSE key supplied is always ES256, right? I.e. there's no sequence of COSE algorithm IDs to permit a transition of that, and RPs have to be involved in verifying the recovery signature.

@dainnilsson
Copy link

Anouther point on the usage of "clone" Authenticators: That approach introduces some security issues that we've explicitly attempted to eliminate with this proposal.

If you have a single Authenticator, how can you be sure that there isn't a clone of it somewhere that you don't know about? Maybe it originally came as part of a "2-pack", but one Authenticator was re-packaged individually for you (the other held on to by an adversary). Or, since we envision the Backup Authenticator being stored in a "secure location" and not used day-to-day, how can you discover if someone still manages to steal it? We wanted to make it impossible to covertly use a "spare key" to access your accounts.

This is why we A) make it explicit to the user when a backup credential is registered, and B) disable the "lost" credential when recovery is performed.

@agl
Copy link
Contributor

agl commented Jun 3, 2020

If you have a single Authenticator, how can you be sure that there isn't a clone of it somewhere that you don't know about?

Supply-chain issues exist whether or not deliberately cloned sets are a thing, of course. Although you could argue that they are easier if the clones are already manufactured.

But you note a couple of meaningful security advantages of this approach. On the other side is that clones don't require any work on the RP side and are immediately compatible with all current WebAuthn-using sites. Those are weighty advantages. (Although this is probably beside the point here.)

@ve7jtb
Copy link
Contributor

ve7jtb commented Jun 3, 2020

Cloning can work for non resident credentials.

For resident/Discoverable ones it gets tricky especially if you want to support more than one credential per RPID on the authenticator.

If it is the manufacture that clones them the user needs to buy two new ones and re register at all the sites or they wont have a backup.

I personally think consumers should register two keys at Google, Apple , and Microsoft then just use federation. But I understand that is not a popular opinion.

Trying to do individual account recovery across hundreds of RP is a nightmare no matter what we do.

@emlun
Copy link
Member Author

emlun commented Jun 4, 2020

I don't believe that we would want to transmit AAGUIDs in a non-enterprise context.

I suggested in yesterday's WG call that we could include a parameter AttestationConveyancePreference attestation in the extension input, and for example have the authenticator emit the AAGUID only if that is set to direct; @agl seemed to agree with this idea. For the record: unlike regular registration responses, where the the authenticator data isn't signed if none attestation is used, the response here is an assertion response, so the client cannot modify the authenticator data after the fact.

Another option that was brought up was to put the AAGUID in the CollectedClientData instead, so the client has control of it. In that case we would need to remove the AAGUID from the authenticator data.

Since the all-zero AAGUID is already defined as a special value, I prefer adding the attestation parameter and having the authenticator set the AAGUID to zero if attestation is not set to direct. This way, the client controls what attestation argument is sent to the authenticator, and we can still reuse the AttestedCredentialData structure (although the name becomes a misnomer in this case) with the same semantics as usual, which reduces implementation complexity for RPs.

@emlun
Copy link
Member Author

emlun commented Jun 5, 2020

I've now added an attestation parameter to the extension input for enabling/disabling AAGUIDs, and also rewritten the authenticator inputs/outputs as CDDL instead of WebIDL. I didn't add any algorithm negotiation parameters yet, as I think that needs a bit more discussion first.

@emlun emlun mentioned this pull request Jun 10, 2020
@nadalin nadalin requested review from agl, akshayku and ve7jtb June 10, 2020 19:29
@nadalin nadalin added this to the L3-WD-01 milestone Jun 10, 2020
@emlun emlun changed the title Add Yubico's proposed recovery extension Add recovery extension Jul 8, 2020
@emlun emlun removed the stat:puntable Issue or PR that is candidate to move to a later milestone label Sep 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants