fixup getAssertion, polish algorithms#371
Conversation
| - Asynchronously invoke the [=authenticatorGetAssertion=] operation on this authenticator with |rpId|, | ||
| |clientDataHash|, |credentialList|, and |clientExtensions| as parameters. | ||
| - Add an entry to |issuedRequests|, corresponding to this request. | ||
| 1. [=list/For each=] credential |C| in <code>{{options}}.{{AssertionOptions/allowList}}</code> that is present on this |
There was a problem hiding this comment.
How can the client tell if a credential is on a particular authenticator? This is only possible in certain circumstances. Maybe we should flip this. Something like "For each credential in allowList, append to credentialList. Some clients may be able to determine, by client-specific methods, the presence or absence of credentials on certain authenticators. In this case, the client MAY skip appending those credentials which it knows to not be on the authenticator."
Thoughts?
There was a problem hiding this comment.
thx, yeah, i trimmed too much out of the prior step 8, have attempted to backfit things, pls review new commit(s).
| 1. If |credentialList| [=list/is empty=] then [=continue=]. | ||
|
|
||
| 1. [=In parallel=], [=list/for each=] credential |C| in |credentialList|: | ||
| 1. If |C| has a non-empty {{transports}} list, the client MAY, [=list/for each=] |transport| in {{transports}}, |
There was a problem hiding this comment.
This means that if a credential has say "USB, BTLE, NFC", then it will get invoked three times, once on each transport? This seems like overkill. We could instead say the client SHOULD select a transport from that list, and otherwise it can pick any one transport to contact the authenticator over.
There was a problem hiding this comment.
I have attempted to state this, assuming I understood what you meant by the "otherwise" clause. pls review new commit(s).
| 1. {{ScopedCredential/type}} whose value is the {{ScopedCredentialType}} representing this [=scoped | ||
| credential=]'s type. | ||
| 1. {{ScopedCredential/id}} whose value is a new {{ArrayBuffer}} containing the bytes of the crendential ID | ||
| returned from the successful [=authenticatorMakeCredential=] operation. |
There was a problem hiding this comment.
You mean authenticatorGetAssertion? This also returns a credential ID.
| :: A new {{ScopedCredential}} object whose fields are: | ||
| 1. {{ScopedCredential/type}} whose value is the {{ScopedCredentialType}} representing this [=scoped | ||
| credential=]'s type. | ||
| 1. {{ScopedCredential/id}} whose value is a new {{ArrayBuffer}} containing the bytes of the crendential ID |
|
Noticed that you converted a few authenticator functions to |
accident-when-resolving-conflicts :-/ thx.
k, thx.
Yeah, what I meant by..
..is the former, including fixing them in this branch and PR if they are not already fixed -- that ok ? |
|
Works for me. LMK when you think we should merge this branch (for the current changes it would be nice to get Jeffrey or JC to review as well). |
Agreed -- @jcjones is already in the reviewers list -- I tried to add @jyasskin but he does not appear in the drop-down menu, tho he is now listed as a wg member -- perhaps he lacks "write perms" to the repo and that is why? |
| challenge value (e.g., by using | ||
| <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setAttestationChallenge(byte%5B%5D)"> | ||
| setAttestationChallenge</a>), | ||
| setAttestationChallenge=]), |
There was a problem hiding this comment.
yeah -- bikeshed barfed on me, i will fix..
|
I'll finish my review of this this afternoon. |
|
note that I'm still pushing commits to this branch -- will signal when I'm done doing so (in the next day or two) |
|
I've gone in detail through the algorithm updates, comparing with my current implementation even - it looks really good, it's a lot clearer with the switch notation since all of that is operating in parallel. I don't see anything in this rev that cries out for changing. |
| them. By default, the RP ID for a WebAuthn operation is set to the [=current settings object=]'s | ||
| [=origin=]. This default can be overridden by the caller subject to certain restrictions, as specified in | ||
| them. By default, the RP ID for a WebAuthn operation is set to the [=relevant settings object=] of the {{WebAuthentication}} | ||
| object's [=origin=]. This default can be overridden by the caller subject to certain restrictions, as specified in |
There was a problem hiding this comment.
The RP ID is set to the relevant settings object? Or did you mean the RP ID is set to the origin specified by the WebAuthentication object's relevant settings object?
There was a problem hiding this comment.
I suspect you mean (relevant settings object of the Webauthentication object)'s origin, but I don't think most readers would put the parentheses there :)
There was a problem hiding this comment.
yes, the latter.
| return [=a promise rejected with=] a {{DOMException}} whose name is "{{NotAllowedError}}", and terminate this algorithm. | ||
| 1. Set |global| to this {{WebAuthentication}} object's [=global object|environment settings object's global object=]. | ||
|
|
||
| 1. Set |callerOrigin| to the [=relevant settings object=] of this {{WebAuthentication}} object's [=origin=]. If |callerOrigin| |
There was a problem hiding this comment.
See above. I think this should be "origin specified by the WebAuthentication object's relevant settings object".
There was a problem hiding this comment.
doh. thanks, done.
|
|
||
| - The <dfn>rpId</dfn> parameter explicitly specifies the RP ID that the credential should be associated with. If it is | ||
| omitted, the RP ID will be set to the [=current settings object=]'s [=origin=]. | ||
| omitted, the RP ID will be set to the [=relevant settings object=] of the {{WebAuthentication}} object's [=origin=]. |
There was a problem hiding this comment.
See previous comment on this construct.
|
|
||
| - The optional <dfn>rpId</dfn> parameter specifies the rpId claimed by the caller. If it is omitted, it will be assumed to | ||
| be equal to the [=current settings object=]'s [=origin=]. | ||
| be equal to the [=relevant settings object=] of the {{WebAuthentication}} object's [=origin=]. |
|
LGTM. @jcjones, would you also take a look and we can merge if you're happy with the changes? |
|
this PR was accidentally closed, reopening... |
|
@jcjones @vijaybh - pls note that commit c49cb0f attempts resolution of #277 and is presently only applied to |
jcjones
left a comment
There was a problem hiding this comment.
I don't see any blocking issues here, and it's a great cleanup. My comments are all style nits, feel free to address them or not as you see fit!
r=me
|
|
||
| 1. Let |promise| be [=a new promise=]. Return |promise| and start a timer for |adjustedTimeout| milliseconds. Then execute the | ||
| following steps [=in parallel=]. | ||
| following steps [=in parallel=]. The [=task source=] for these [=tasks=] is the [=dom manipulation task source=]. |
There was a problem hiding this comment.
It seems to mean to me that if the user has many types of authenticators available, this could starve the dom manipulation task thread pool. Probably not a big deal, but may be an implementation quirk to handle.
There was a problem hiding this comment.
ok. let's leave it as =dom manipulation task source=] for now -- most all users will likely have only one or maybe two authenticators (we are surmizing) -- and we can use a different task source or invent a new task source if needed as @bzbarsky noted in #277 (comment)
| :: The [=recognized algorithm name=] of the hash algorithm selected by the client for generating the | ||
| [=hash of the serialized client data=] | ||
| : {{tokenBinding}} | ||
| :: The [=Token Binding ID=] associated with |callerOrigin| (if any) |
There was a problem hiding this comment.
Is it clear what encoding should be done here if there's no token binding ID?
There was a problem hiding this comment.
tokenBinding is an optional member of the ClientData dictionary, so the implication here is it would not appear in the dictionary if a Token Binding ID is unanavailable, thus the (if any) qualification. Perhaps we can make that more clear.
There was a problem hiding this comment.
ok, I attempted modest clarification in 1c84e8b
| 1. [=set/Append=] |authenticator| to |issuedRequests|. | ||
|
|
||
| 1. Let |promise| be [=a new Promise=]. Return |promise| and start a timer for |adjustedTimeout| milliseconds. Then execute the | ||
| following steps [=in parallel=]. |
There was a problem hiding this comment.
Should this line end in a colon, then, since it's sort-of starting another block?
By that logic, maybe we should up the indentation level, too?
There was a problem hiding this comment.
hm. I am sympathetic, tho @jyasskin did not do such in makeCredential(), so I'm inclined to leave it as-is for now.
|
Oh, and since I just hit "submit" too early - the explicit global you've added in c49cb0f for ScopedCredentialInfo looks correct to me, in that we don't need to worry then about ScopedCredentialInfo outliving the WebAuthn call. I'm pretty sure it's right, based on my previous conversations about what to do there. |
|
@jcjones said:
Ok, if it's the correct global, then I wonder about the prose used to state its use, hence asking for @jyasskin & @bzbarsky input... :) |
|
LGTM. If we're wrong about the source of the global object, I figure that's a minor change on top of this much more substantive one. |
This initial set of commits applies @jyasskin's techniques from makeCredential() to getAssertion().
More commits to follow (to fix various [subtype:algorithms] issues I've signed up for), tho review of these initial commits is most welcome in the meantime.