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

Clean up RP operations #1222

Merged
merged 4 commits into from Jun 12, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 35 additions & 32 deletions index.bs
Expand Up @@ -3580,6 +3580,9 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR
{{AuthenticationExtensionsClientOutputs}} structure |clientExtensionResults|, as part of a [=registration ceremony=], a
[=[RP]=] MUST proceed as follows:

1. Let |options| be the {{PublicKeyCredentialCreationOptions}} that was passed
as the <code>{{CredentialCreationOptions/publicKey}}</code> option in the {{CredentialsContainer/create()}} call.

1. Let |JSONtext| be the result of
running [=UTF-8 decode=] on the value of <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code>.

Expand All @@ -3594,14 +3597,14 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR

1. Verify that the value of <code>|C|.{{CollectedClientData/type}}</code> is `webauthn.create`.

1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> matches the challenge that was sent to the
authenticator in the {{CredentialsContainer/create()}} call.
1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> equals
the base64url encoding of <code>|options|.{{PublicKeyCredentialCreationOptions/challenge}}</code>.

1. Verify that the value of <code>|C|.{{CollectedClientData/origin}}</code> matches the [=[RP]=]'s [=origin=].

1. Verify that the value of <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/status}}</code> matches the state of [=Token Binding=] for the TLS connection over which the [=assertion=] was obtained. If [=Token Binding=] was used on that TLS connection, also verify that <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/id}}</code> matches the [=base64url encoding=] of the [=Token Binding ID=] for the connection.

1. Compute the hash of <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code> using SHA-256.
1. Let |hash| be the result of computing a hash over <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code> using SHA-256.

1. Perform CBOR decoding on the {{AuthenticatorAttestationResponse/attestationObject}} field of the
{{AuthenticatorAttestationResponse}} structure to obtain the attestation statement format |fmt|, the [=authenticator data=]
Expand All @@ -3616,12 +3619,11 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR

1. Verify that the values of the [=client extension outputs=] in |clientExtensionResults| and the [=authenticator extension
outputs=] in the <code>[=authdataextensions|extensions=]</code> in |authData| are as expected, considering the [=client
extension input=] values that were given as the {{PublicKeyCredentialCreationOptions/extensions}} option in the
{{CredentialsContainer/create()}} call.
extension input=] values that were given in <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>.
In particular, any [=extension identifier=] values in the |clientExtensionResults| and
the <code>[=authdataextensions|extensions=]</code> in |authData|
MUST be also be present as [=extension identifier=] values in
the {{PublicKeyCredentialCreationOptions/extensions}} member of |options|,
MUST also be present as [=extension identifier=] values in
<code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>,
i.e., no extensions are present that were not requested.
In the general case, the meaning of "are as expected" is specific to the [=[RP]=] and which extensions are in use.

Expand All @@ -3634,8 +3636,7 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR
is maintained in the IANA registry of the same name [[!WebAuthn-Registries]].

1. Verify that |attStmt| is a correct [=attestation statement=], conveying a valid [=attestation signature=], by using the
[=attestation statement format=] |fmt|'s [=verification procedure=] given |attStmt|, |authData| and the [=hash of the serialized
client data=] computed in step 7.
[=attestation statement format=] |fmt|'s [=verification procedure=] given |attStmt|, |authData| and |hash|.

Note: Each [=attestation statement format=] specifies its own [=verification procedure=]. See [[#sctn-defined-attestation-formats]] for
the initially-defined formats, and [[!WebAuthn-Registries]] for the up-to-date list.
Expand All @@ -3645,12 +3646,12 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR
example, the FIDO Metadata Service [[FIDOMetadataService]] provides one way to obtain such information, using the
<code>[=aaguid=]</code> in the <code>[=attestedCredentialData=]</code> in |authData|.

1. Assess the attestation trustworthiness using the outputs of the [=verification procedure=] in step 14, as follows:
1. Assess the attestation trustworthiness using the outputs of the [=verification procedure=] in step 15, as follows:
- If [=None|no attestation=] was provided, verify that [=None=] attestation is acceptable under [=[RP]=] policy.
- If [=self attestation=] was used, verify that [=self attestation=] is acceptable under [=[RP]=] policy.
- If [=ECDAA=] was used, verify that the [=identifier of the ECDAA-Issuer public key=],
returned as the [=attestation trust path=] from the [=verification procedure=],
is included in the set of acceptable trust anchors obtained in step 15.
is included in the set of acceptable trust anchors obtained in step 16.
- Otherwise, use the X.509 certificates returned as the [=attestation trust path=] from the [=verification procedure=]
to verify that the attestation public key correctly chains up to an acceptable root certificate.

Expand All @@ -3659,13 +3660,12 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR
fail this [=registration ceremony=], or it MAY decide to accept the registration, e.g. while deleting the older registration.

1. If the attestation statement |attStmt| verified successfully and is found to be trustworthy, then register the new
credential with the account that was denoted in the
{{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)/options}}.{{PublicKeyCredentialCreationOptions/user}} passed to
{{CredentialsContainer/create()}}, by associating it with the <code>[=credentialId=]</code> and
credential with the account that was denoted in <code>|options|.{{PublicKeyCredentialCreationOptions/user}}</code>,
by associating it with the <code>[=credentialId=]</code> and
<code>[=credentialPublicKey=]</code> in the <code>[=attestedCredentialData=]</code> in |authData|, as appropriate for the
[=[RP]=]'s system.

1. If the attestation statement |attStmt| successfully verified but is not trustworthy per step 16 above, the [=[RP]=] SHOULD fail
1. If the attestation statement |attStmt| successfully verified but is not trustworthy per step 17 above, the [=[RP]=] SHOULD fail
the [=registration ceremony=].

NOTE: However, if permitted by policy, the [=[RP]=] MAY register the [=credential ID=] and credential public key but treat the
Expand All @@ -3674,7 +3674,7 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR
See [[FIDOSecRef]] and [[UAFProtocol]] for a more detailed discussion.

Verification of [=attestation objects=] requires that the [=[RP]=] has a trusted method of determining acceptable trust anchors
in step 15 above. Also, if certificates are being used, the [=[RP]=] MUST have access to certificate status information for the
in step 16 above. Also, if certificates are being used, the [=[RP]=] MUST have access to certificate status information for the
intermediate CA certificates. The [=[RP]=] MUST also be able to build the attestation certificate chain if the client did not
provide this chain in the attestation information.

Expand All @@ -3684,9 +3684,12 @@ provide this chain in the attestation information.
When verifying a given {{PublicKeyCredential}} structure (|credential|) and an {{AuthenticationExtensionsClientOutputs}} structure
|clientExtensionResults|, as part of an [=authentication ceremony=], the [=[RP]=] MUST proceed as follows:

1. If the {{PublicKeyCredentialRequestOptions/allowCredentials}} option was given when this [=authentication ceremony=] was
initiated, verify that <code>|credential|.{{Credential/id}}</code> identifies one of the [=public key credentials=] that were
listed in {{PublicKeyCredentialRequestOptions/allowCredentials}}.
1. Let |options| be the {{PublicKeyCredentialRequestOptions}} that was passed
as the <code>{{CredentialCreationOptions/publicKey}}</code> option in the {{CredentialsContainer/get()}} call.

1. If <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> [=list/is not empty=],
verify that <code>|credential|.{{Credential/id}}</code> identifies one of the [=public key credentials=]
listed in <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>.

1. Identify the user being authenticated and verify that this user is the owner of the [=public key credential source=]
|credentialSource| identified by <code>|credential|.{{Credential/id}}</code>:
Expand All @@ -3702,8 +3705,9 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an {
present, and that the user identified by this value is the owner of |credentialSource|.
</dl>

1. Using |credential|'s {{Credential/id}} attribute (or the corresponding {{PublicKeyCredential/rawId}}, if
[=base64url encoding=] is inappropriate for your use case), look up the corresponding credential public key.
1. Using <code>|credential|.{{Credential/id}}</code> (or <code>|credential|.{{PublicKeyCredential/rawId}}</code>, if
[=base64url encoding=] is inappropriate for your use case), look up the corresponding [=credential public key=]
and let |credentialPublicKey| be that [=credential public key=].

1. Let |cData|, |authData| and |sig| denote the value of |credential|'s {{PublicKeyCredential/response}}'s
{{AuthenticatorResponse/clientDataJSON}}, {{AuthenticatorAssertionResponse/authenticatorData}}, and
Expand All @@ -3722,8 +3726,8 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an {

1. Verify that the value of <code>|C|.{{CollectedClientData/type}}</code> is the string `webauthn.get`.

1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> matches the challenge that was sent to the
authenticator in the {{PublicKeyCredentialRequestOptions}} passed to the {{CredentialsContainer/get()}} call.
1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> equals
the base64url encoding of <code>|options|.{{PublicKeyCredentialRequestOptions/challenge}}</code>.

1. Verify that the value of <code>|C|.{{CollectedClientData/origin}}</code> matches the [=[RP]=]'s [=origin=].

Expand All @@ -3738,12 +3742,11 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an {

1. Verify that the values of the [=client extension outputs=] in |clientExtensionResults| and the [=authenticator extension
outputs=] in the <code>[=authdataextensions|extensions=]</code> in |authData| are as expected, considering the [=client
extension input=] values that were given as the {{PublicKeyCredentialRequestOptions/extensions}} option in the
{{CredentialsContainer/get()}} call.
extension input=] values that were given in <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>.
In particular, any [=extension identifier=] values in the |clientExtensionResults| and
the <code>[=authdataextensions|extensions=]</code> in |authData|
MUST be also be present as [=extension identifier=] values in
the {{PublicKeyCredentialCreationOptions/extensions}} member of |options|,
MUST also be present as [=extension identifier=] values in
the <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>,
i.e., no extensions are present that were not requested.
In the general case, the meaning of "are as expected" is specific to the [=[RP]=] and which extensions are in use.

Expand All @@ -3752,24 +3755,24 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an {

1. Let |hash| be the result of computing a hash over the |cData| using SHA-256.

1. Using the credential public key looked up in step 3, verify that |sig| is a valid signature over the binary concatenation of
1. Using |credentialPublicKey|, verify that |sig| is a valid signature over the binary concatenation of
|authData| and |hash|.

Note: This verification step is compatible with signatures generated by FIDO U2F authenticators. See
[[#sctn-fido-u2f-sig-format-compat]].

1. If the [=signature counter=] value |authData|.<code>[=signCount=]</code> is nonzero or the value stored
in conjunction with |credential|'s {{Credential/id}} attribute
in conjunction with <code>|credential|.{{Credential/id}}</code>
is nonzero, then run the following sub-step:
- If the [=signature counter=] value |authData|.<code>[=signCount=]</code> is
<dl class="switch">
<dt>greater than the [=signature counter=] value stored in conjunction
with |credential|'s {{Credential/id}} attribute.</dt>
with <code>|credential|.{{Credential/id}}</code>.</dt>
<dd>Update the stored [=signature counter=] value, associated with
|credential|'s {{Credential/id}} attribute, to be the value of
<code>|credential|.{{Credential/id}}</code>, to be the value of
|authData|.<code>[=signCount=]</code>.</dd>
<dt>less than or equal to the [=signature counter=] value stored in conjunction
with |credential|'s {{Credential/id}} attribute.</dt>
with <code>|credential|.{{Credential/id}}</code>.</dt>
<dd>This is a signal that
the authenticator may be cloned, i.e. at least
two copies of the [=credential private key=] may exist and are
Expand Down