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

Describe how authenticators unique and find credential sources. #623

Merged
merged 19 commits into from
Feb 6, 2018

Conversation

jyasskin
Copy link
Member

@jyasskin jyasskin commented Oct 10, 2017

This PR builds on #620. Just look at the last commit (50d8d1b) to see what's new here. @leshi, @rlin1, @akshayku, you were cc'ed on #602 (comment), which this patch implements.

This happens to fix a maybe-bug where the authenticator didn't check that a
decrypted credential ID came from the right RP.

It's also much more precise about the distinction between a credential
descriptor and a credential or credential source.

This still only improves #578, but it makes it clearer where we'll put that fix.


Preview (#authenticato…) (#op-make-cred) (#op-get-asser…) | Diff

@jyasskin jyasskin self-assigned this Oct 10, 2017
@rlin1
Copy link
Contributor

rlin1 commented Oct 11, 2017

I think we should use the term Credential for the authentication key pair, i.e. the thing that gets created by authenticatorMakeCredential.
And likewise we should continue calling the thing assertion that is sent to the RP and then verified by the RP.

Copy link
Contributor

@rlin1 rlin1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are currently using the term credential for the authentication kay pair and assertion for the one-time data sent to and then verified by the RP.

Re-defining credential to refer to the assertion is a BIG change. That would have to cover much more than what is currently covered.

index.bs Outdated
@@ -324,13 +325,60 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S
:: A user agent implementing, in conjunction with the underlying platform, the [=Web Authentication API=] and algorithms
given in this specification, and handling communication between [=authenticators=] and [=[RPS]=].

: <dfn>Credential ID</dfn>
:: A probabilistically-unique [=byte sequence=] identifying a [=public key credential source=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the way we use credential in the spec today suggests that credential actually refers to the authentication key pair and not the authentication assertion.
authenticatorMakeCredential makes a credential i.e. the key pair.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when ever we mean the assertion we use the term assertion (not credential)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Credential ID is already defined in the spec at this point. This addition can be deleted at this point.

index.bs Outdated

A [=public key credential=] is created by the [=authenticatorGetAssertion=] operation using a [=public key credential
source=] created by a previous [=authenticatorMakeCredential=] call. The [=[RP]=] verifies it using the [=credential public
key=] returned from that [=authenticatorMakeCredential=] call via {{PublicKeyCredential/[[Create]]()}}.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is confusing: when I call Credential.create I would expect to get a credential back - not a credential source.

index.bs Outdated
@@ -940,7 +977,7 @@ When this method is invoked, the user agent MUST execute the following algorithm
2. Let |value| be a new {{PublicKeyCredential}} associated with |global| whose fields are:

: {{PublicKeyCredential/[[identifier]]}}
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of the credential ID
:: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of the [=credential ID=]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we use credential source to refer to the public key/private key, the credential ID should be a credential source ID.

index.bs Outdated

On successful completion of this operation, the authenticator returns the [=attestation object=] to the client.


### The <dfn>authenticatorGetAssertion</dfn> operation ### {#op-get-assertion}
<h4 id="op-get-assertion" algorithm> The <dfn>authenticatorGetAssertion</dfn> operation</h4>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be renamed to authenticatorGetCredential (if we stick to the redefinition of credential)

index.bs Outdated
: |hash|
:: The [=hash of the serialized client data=], provided by the client.
: |allowCredentialDescriptorList|
:: An optional list of {{PublicKeyCredentialDescriptor}}s describing credentials acceptable to the [=[RP]=] (possibly filtered
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would have to be renamed to PublicKeyCrdentialSourceDescriptor describing credential sources acceptable...

index.bs Outdated
- |selectedCredential|.[=public key credential source/id=]
- |authenticatorData|
- |signature|
- |selectedCredential|.[=public key credential source/userHandle=]

If the authenticator cannot find any credential corresponding to the specified [=[RP]=] that matches the specified criteria, it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would have to be renamed to credential source corresponding ...

index.bs Outdated
@@ -1845,7 +1943,7 @@ credential. It has the following format:
</tr>
<tr>
<td>L</td>
<td>Credential ID</td>
<td>[=Credential ID=]</td>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would have to be renamed to CredentialSource ID

index.bs Outdated
@@ -3483,10 +3581,10 @@ credential.

9. If an assertion was successfully generated and returned,
- The script sends the assertion to the server.
- The server examines the assertion, extracts the credential ID, looks up the registered
- The server examines the assertion, extracts the [=credential ID=], looks up the registered
credential public key it is database, and verifies the assertion's authentication signature.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would have to be rephrased to ... and verifies the credential's signature

@jyasskin
Copy link
Member Author

I've replied to @rlin1's comments in #620 (comment), since they're really about that change.

@selfissued selfissued added this to the WD-07 milestone Oct 12, 2017
@nadalin
Copy link
Contributor

nadalin commented Oct 17, 2017

@akshayku @leshi Please review before 10/18

This also redefines "Public Key Credential" to be the thing presented to the RP,
as a willful violation of RFC4949.

Credential ID is defined to explicitly include the possibility that it's the
encrypted Credential Source.
This happens to fix a maybe-bug where the authenticator didn't check that a
decrypted credential ID came from the right RP.

It's also much more precise about the distinction between a credential
descriptor and a credential or credential source.
Copy link
Contributor

@selfissued selfissued left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks OK to me.

Copy link
Contributor

@equalsJeffH equalsJeffH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I wonder about this being too prescriptive for authenticators and their implementers. One aspect is that I would venture to guess that such implementers do not commonly use WebIDL and thus wonder whether stipulating algorithms in detail via WebIDL is appropriate for that audience.

Another aspect is wondering whether/how this matches-up with the CTAP spec -- tho it does not have to be an exact match: we are ostensibly being purposely hand-wavy wrt authenticator implementations here in the webauthn spec, e.g., to give platform authnr implementers wiggle-room (i.e., those folks not necessarily depending directly on CTAP).

That said, the additions made here to the authenticatorMakeCredential and authenticatorGetAssertion operations seem correct.

Tho, I have a comment below wrt placement of the formal definition of the proposed credentials map and the credential id lookup algorithm.

index.bs Outdated
1. If |credSource|.[=public key credential source/id=] is |credentialId|, return |credSource|.
1. Return `null`.

</div>
Copy link
Contributor

@equalsJeffH equalsJeffH Oct 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we keep all the gory formal definitions and algorithmic stuff down in subsections below this introductory prose.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I continue to wish to move this algorithm to it's own section. I did not do that as a part of the major merge-from-master catchup, but will do now if there's no objections.

@equalsJeffH
Copy link
Contributor

Reviewed: #623 (review)

@equalsJeffH
Copy link
Contributor

bump: @jyasskin: #623 (review)

@equalsJeffH
Copy link
Contributor

getting input from folks who are involved in platform authenticator APIs (i.e., not only CTAP) would be good here: #623 (review)

cc: @emlun @akshayku @jcjones @leshi @rlin1

Copy link
Member

@emlun emlun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall to me, but I agree with @equalsJeffH on moving the definition of the lookup algorithm.

index.bs Outdated
1. If |credSource|.[=public key credential source/id=] is |credentialId|, return |credSource|.
1. Return `null`.

</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

@nadalin nadalin removed the request for review from akshayku December 13, 2017 18:21
@equalsJeffH
Copy link
Contributor

Am still working on merge-from-master. the portions in "6.2.2. The authenticatorGetAssertion operation" are tricky. more news on the morrow...

@equalsJeffH
Copy link
Contributor

This is ready for re-review. I merged-from-master and believe it is appropriately faithful to @jyasskin's original PR modulo master having evolved since then.

@equalsJeffH equalsJeffH dismissed their stale review January 30, 2018 23:19

my issues with this have been addressed.

index.bs Outdated
|rpId|.
1. If |credentialOptions| is now empty, return an error code equivalent to "{{NotAllowedError}}" and terminate the operation.

1. If |allowCredentialDescriptorList| was not supplied, set it to a list of all credentials stored for |rpId| (as determined by
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like steps 2-6 and steps 7-9 do the same thing, no? In that case, we should delete steps 7-9 and change |allowCredentialDescriptorList| to |credentialOptions| in step 10.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, how embarrassing, me thinks ur correct.

index.bs Outdated
the [=authenticator=] if it has its own output capability, or by the user agent otherwise. The prompt SHOULD display the
|rpId| and any additional displayable data associated with |selectedCredential|, if possible.

If |requireUserVerification| is `true`, the method of obtaining [=user consent=] MUST include [=user verification=].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requireUserVerification parameter is now unused. Is this intentional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, thx.

index.bs Outdated

If |requireUserVerification| is `true`, the method of obtaining [=user consent=] MUST include [=user verification=].

If |requireUserPresence| is `true`, the method of obtaining [=user consent=] MUST include a [=test of user presence=].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requireUserPresence parameter is now unused. Is this intentional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, thx.

index.bs Outdated
- The [=user handle=] associated with |selectedCredential|, if available.
Return to the user agent:
- |selectedCredential|.[=public key credential source/id=], if either a list of credentials of length 2 or greater was
supplied by the client, or no such list was supplied.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If my above comment about allowCredentialDescriptorList is correct, we should reference allowCredentialDescriptorList (which is then untouched at this point) here and in the Note: below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, thx.

- |authenticatorData|
- |signature|
- |selectedCredential|.[=public key credential source/userHandle=]
Copy link
Member

@emlun emlun Jan 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CTAP stores the user handle only for client-side-resident private key credentials, so it seems misleading to imply that it must always be returned (unless we point out at the definition site that the userHandle field is nullable). See also the client's getAssertion method.

index.bs Outdated
:: The [=Relying Party Identifier=], for the [=[RP]=] this [=public key credential source=] is associated with.

: <dfn>userHandle</dfn>
:: The [=user handle=] associated when this [=public key credential source=] was created.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to point out that this field is nullable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok.

Copy link
Contributor

@equalsJeffH equalsJeffH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's one change I wish to make now that the major merge-from-master catchup is done.

index.bs Outdated
1. If |credSource|.[=public key credential source/id=] is |credentialId|, return |credSource|.
1. Return `null`.

</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I continue to wish to move this algorithm to it's own section. I did not do that as a part of the major merge-from-master catchup, but will do now if there's no objections.

Copy link
Contributor

@selfissued selfissued left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me now. It's clearly an improvement over the existing text.

@equalsJeffH equalsJeffH assigned equalsJeffH and unassigned akshayku Jan 31, 2018
@equalsJeffH
Copy link
Contributor

@emlun's comments are addressed I think in 48de8b2

@equalsJeffH
Copy link
Contributor

I'm more confident @emlun's comments are addressed now given the further commits.

Copy link
Member

@emlun emlun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @equalsJeffH, this looks good to me except one last thing... :)

index.bs Outdated
@@ -2351,7 +2396,7 @@ It takes the following input parameters:
: |allowCredentialDescriptorList|
:: An optional [=list=] of {{PublicKeyCredentialDescriptor}}s describing credentials acceptable to the [=[RP]=] (possibly filtered
by the client), if any.
: |requireUserPresence|
: <var ignore>requireUserPresence</var>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This <var> is now defined and ignored in two places... :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I remove the ignore here, i get the annoying "only used once" warning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove just one, yes, but not if you remove both this one and #623 (comment) .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i was gonna try removing it from both next but was running out door to go sit in traffic....u r of course correct, fixed now in
14335b1

index.bs Outdated

If |requireUserVerification| is `true`, the method of obtaining [=user consent=] MUST include [=user verification=].

If |requireUserPresence| is `true`, the method of obtaining [=user consent=] MUST include a [=test of user presence=].
If <var ignore>requireUserPresence</var> is `true`, the method of obtaining [=user consent=] MUST include a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This <var> is now defined and ignored in two places... :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@equalsJeffH
Copy link
Contributor

just pushed new commit dc50b3f that moves the op-lookup-credsource-by-credid alg to new subsection.

Copy link
Member

@emlun emlun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@equalsJeffH
Copy link
Contributor

Given the approvals, I'll merge this later today 5-Feb-2018 in the afternoon PT if there's no objections. thx.

@equalsJeffH equalsJeffH merged commit 4f1a3ba into w3c:master Feb 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants