Skip to content

Commit 2eb5c18

Browse files
committed
Revert "Revert new experimental interfaces and classes"
This reverts commit 0cbba57.
1 parent 0cbba57 commit 2eb5c18

22 files changed

+11095
-282
lines changed

NEWS

+31
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,37 @@ New features:
2929
instead of an ordinary WebAuthn response. See the JavaDoc for details.
3030
** NOTE: Experimental features may receive breaking changes without a major
3131
version increase.
32+
* (Experimental) Added a new suite of interfaces, starting with
33+
`CredentialRepositoryV2`. `RelyingParty` can now be configured with a
34+
`CredentialRepositoryV2` instance instead of a `CredentialRepository`
35+
instance. This changes the result of the `RelyingParty` builder to
36+
`RelyingPartyV2`. `CredentialRepositoryV2` and `RelyingPartyV2` enable a suite
37+
of new features:
38+
** `CredentialRepositoryV2` does not assume that the application has usernames,
39+
instead username support is modular. In addition to the
40+
`CredentialRepositoryV2`, `RelyingPartyV2` can be optionally configured with
41+
a `UsernameRepository` as well. If a `UsernameRepository` is not set, then
42+
`RelyingPartyV2.startAssertion(StartAssertionOptions)` will fail at runtime
43+
if `StartAssertionOptions.username` is set.
44+
** `CredentialRepositoryV2` uses a new interface `CredentialRecord` to
45+
represent registered credentials, instead of the concrete
46+
`RegisteredCredential` class (although `RegisteredCredential` also
47+
implements `CredentialRecord`). This provides implementations greater
48+
flexibility while also automating the type conversion to
49+
`PublicKeyCredentialDescriptor` needed in `startRegistration()` and
50+
`startAssertion()`.
51+
** `RelyingPartyV2.finishAssertion()` returns a new type `AssertionResultV2`
52+
with a new method `getCredential()`, which returns the `CredentialRecord`
53+
that was verified. The return type of `getCredential()` is generic and
54+
preserves the concrete type of `CredentialRecord` returned by the
55+
`CredentialRepositoryV2` implementation.
56+
** NOTE: Experimental features may receive breaking changes without a major
57+
version increase.
58+
* (Experimental) Added property `RegisteredCredential.transports`.
59+
** NOTE: Experimental features may receive breaking changes without a major
60+
version increase.
61+
** NOTE: Experimental features may receive breaking changes without a major
62+
version increase.
3263

3364
`webauthn-server-attestation`:
3465

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// Copyright (c) 2018, Yubico AB
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are met:
6+
//
7+
// 1. Redistributions of source code must retain the above copyright notice, this
8+
// list of conditions and the following disclaimer.
9+
//
10+
// 2. Redistributions in binary form must reproduce the above copyright notice,
11+
// this list of conditions and the following disclaimer in the documentation
12+
// and/or other materials provided with the distribution.
13+
//
14+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
package com.yubico.webauthn;
26+
27+
import com.fasterxml.jackson.annotation.JsonCreator;
28+
import com.fasterxml.jackson.annotation.JsonIgnore;
29+
import com.fasterxml.jackson.annotation.JsonProperty;
30+
import com.yubico.webauthn.data.AuthenticatorAssertionExtensionOutputs;
31+
import com.yubico.webauthn.data.AuthenticatorAssertionResponse;
32+
import com.yubico.webauthn.data.AuthenticatorAttachment;
33+
import com.yubico.webauthn.data.AuthenticatorData;
34+
import com.yubico.webauthn.data.AuthenticatorDataFlags;
35+
import com.yubico.webauthn.data.AuthenticatorResponse;
36+
import com.yubico.webauthn.data.ByteArray;
37+
import com.yubico.webauthn.data.ClientAssertionExtensionOutputs;
38+
import com.yubico.webauthn.data.PublicKeyCredential;
39+
import java.util.Optional;
40+
import lombok.AccessLevel;
41+
import lombok.Getter;
42+
import lombok.NonNull;
43+
import lombok.Value;
44+
45+
/**
46+
* The result of a call to {@link RelyingPartyV2#finishAssertion(FinishAssertionOptions)}.
47+
*
48+
* @deprecated EXPERIMENTAL: This is an experimental feature. It is likely to change or be deleted
49+
* before reaching a mature release.
50+
*/
51+
@Deprecated
52+
@Value
53+
public class AssertionResultV2<C extends CredentialRecord> {
54+
55+
/** <code>true</code> if the assertion was verified successfully. */
56+
private final boolean success;
57+
58+
@JsonProperty
59+
@Getter(AccessLevel.NONE)
60+
private final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
61+
credentialResponse;
62+
63+
/**
64+
* The {@link CredentialRecord} that was returned by {@link
65+
* CredentialRepositoryV2#lookup(ByteArray, ByteArray)} and whose public key was used to
66+
* successfully verify the assertion signature.
67+
*
68+
* <p>NOTE: The {@link CredentialRecord#getSignatureCount() signature count}, {@link
69+
* CredentialRecord#isBackupEligible() backup eligibility} and {@link
70+
* CredentialRecord#isBackedUp() backup state} properties in this object will reflect the state
71+
* <i>before</i> the assertion operation, not the new state. When updating your database state,
72+
* use the signature counter and backup state from {@link #getSignatureCount()}, {@link
73+
* #isBackupEligible()} and {@link #isBackedUp()} instead.
74+
*
75+
* @deprecated EXPERIMENTAL: This is an experimental feature. It is likely to change or be deleted
76+
* before reaching a mature release.
77+
*/
78+
@Deprecated private final C credential;
79+
80+
/**
81+
* <code>true</code> if and only if at least one of the following is true:
82+
*
83+
* <ul>
84+
* <li>The {@link AuthenticatorData#getSignatureCounter() signature counter value} in the
85+
* assertion was strictly greater than {@link CredentialRecord#getSignatureCount() the
86+
* stored one}.
87+
* <li>The {@link AuthenticatorData#getSignatureCounter() signature counter value} in the
88+
* assertion and {@link CredentialRecord#getSignatureCount() the stored one} were both zero.
89+
* </ul>
90+
*
91+
* @see <a
92+
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-data">§6.1.
93+
* Authenticator Data</a>
94+
* @see AuthenticatorData#getSignatureCounter()
95+
* @see CredentialRecord#getSignatureCount()
96+
* @see RelyingParty.RelyingPartyBuilder#validateSignatureCounter(boolean)
97+
*/
98+
private final boolean signatureCounterValid;
99+
100+
@JsonCreator
101+
AssertionResultV2(
102+
@JsonProperty("success") boolean success,
103+
@NonNull @JsonProperty("credentialResponse")
104+
PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
105+
credentialResponse,
106+
@NonNull @JsonProperty("credential") C credential,
107+
@JsonProperty("signatureCounterValid") boolean signatureCounterValid) {
108+
this.success = success;
109+
this.credentialResponse = credentialResponse;
110+
this.credential = credential;
111+
this.signatureCounterValid = signatureCounterValid;
112+
}
113+
114+
/**
115+
* Check whether the <a href="https://www.w3.org/TR/webauthn/#user-verification">user
116+
* verification</a> as performed during the authentication ceremony.
117+
*
118+
* <p>This flag is also available via <code>
119+
* {@link PublicKeyCredential}.{@link PublicKeyCredential#getResponse() getResponse()}.{@link AuthenticatorResponse#getParsedAuthenticatorData() getParsedAuthenticatorData()}.{@link AuthenticatorData#getFlags() getFlags()}.{@link AuthenticatorDataFlags#UV UV}
120+
* </code>.
121+
*
122+
* @return <code>true</code> if and only if the authenticator claims to have performed user
123+
* verification during the authentication ceremony.
124+
* @see <a href="https://www.w3.org/TR/webauthn/#user-verification">User Verification</a>
125+
* @see <a href="https://w3c.github.io/webauthn/#authdata-flags-uv">UV flag in §6.1. Authenticator
126+
* Data</a>
127+
*/
128+
@JsonIgnore
129+
public boolean isUserVerified() {
130+
return credentialResponse.getResponse().getParsedAuthenticatorData().getFlags().UV;
131+
}
132+
133+
/**
134+
* Check whether the asserted credential is <a
135+
* href="https://w3c.github.io/webauthn/#backup-eligible">backup eligible</a>, using the <a
136+
* href="https://w3c.github.io/webauthn/#authdata-flags-be">BE flag</a> in the authenticator data.
137+
*
138+
* <p>You SHOULD store this value in your representation of the corresponding {@link
139+
* CredentialRecord} if no value is stored yet. {@link CredentialRepository} implementations
140+
* SHOULD set this value when reconstructing that {@link CredentialRecord}.
141+
*
142+
* @return <code>true</code> if and only if the created credential is backup eligible. NOTE that
143+
* this is only a hint and not a guarantee, unless backed by a trusted authenticator
144+
* attestation.
145+
* @see <a href="https://w3c.github.io/webauthn/#backup-eligible">Backup Eligible in §4.
146+
* Terminology</a>
147+
* @see <a href="https://w3c.github.io/webauthn/#authdata-flags-be">BE flag in §6.1. Authenticator
148+
* Data</a>
149+
* @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as
150+
* the standard matures.
151+
*/
152+
@Deprecated
153+
@JsonIgnore
154+
public boolean isBackupEligible() {
155+
return credentialResponse.getResponse().getParsedAuthenticatorData().getFlags().BE;
156+
}
157+
158+
/**
159+
* Get the current <a href="https://w3c.github.io/webauthn/#backup-state">backup state</a> of the
160+
* asserted credential, using the <a href="https://w3c.github.io/webauthn/#authdata-flags-bs">BS
161+
* flag</a> in the authenticator data.
162+
*
163+
* <p>You SHOULD update this value in your representation of a {@link CredentialRecord}. {@link
164+
* CredentialRepository} implementations SHOULD set this value when reconstructing that {@link
165+
* CredentialRecord}.
166+
*
167+
* @return <code>true</code> if and only if the created credential is believed to currently be
168+
* backed up. NOTE that this is only a hint and not a guarantee, unless backed by a trusted
169+
* authenticator attestation.
170+
* @see <a href="https://w3c.github.io/webauthn/#backup-state">Backup State in §4. Terminology</a>
171+
* @see <a href="https://w3c.github.io/webauthn/#authdata-flags-bs">BS flag in §6.1. Authenticator
172+
* Data</a>
173+
* @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as
174+
* the standard matures.
175+
*/
176+
@Deprecated
177+
@JsonIgnore
178+
public boolean isBackedUp() {
179+
return credentialResponse.getResponse().getParsedAuthenticatorData().getFlags().BS;
180+
}
181+
182+
/**
183+
* The <a href="https://w3c.github.io/webauthn/#authenticator-attachment-modality">authenticator
184+
* attachment modality</a> in effect at the time the asserted credential was used.
185+
*
186+
* @see PublicKeyCredential#getAuthenticatorAttachment()
187+
* @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as
188+
* the standard matures.
189+
*/
190+
@Deprecated
191+
@JsonIgnore
192+
public Optional<AuthenticatorAttachment> getAuthenticatorAttachment() {
193+
return credentialResponse.getAuthenticatorAttachment();
194+
}
195+
196+
/**
197+
* The new <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#signcount">signature
198+
* count</a> of the credential used for the assertion.
199+
*
200+
* <p>You should update this value in your database.
201+
*
202+
* @see AuthenticatorData#getSignatureCounter()
203+
*/
204+
@JsonIgnore
205+
public long getSignatureCount() {
206+
return credentialResponse.getResponse().getParsedAuthenticatorData().getSignatureCounter();
207+
}
208+
209+
/**
210+
* The <a
211+
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-extension-output">client
212+
* extension outputs</a>, if any.
213+
*
214+
* <p>This is present if and only if at least one extension output is present in the return value.
215+
*
216+
* @see <a
217+
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-client-extension-processing">§9.4.
218+
* Client Extension Processing</a>
219+
* @see ClientAssertionExtensionOutputs
220+
* @see #getAuthenticatorExtensionOutputs() ()
221+
*/
222+
@JsonIgnore
223+
public Optional<ClientAssertionExtensionOutputs> getClientExtensionOutputs() {
224+
return Optional.of(credentialResponse.getClientExtensionResults())
225+
.filter(ceo -> !ceo.getExtensionIds().isEmpty());
226+
}
227+
228+
/**
229+
* The <a
230+
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#authenticator-extension-output">authenticator
231+
* extension outputs</a>, if any.
232+
*
233+
* <p>This is present if and only if at least one extension output is present in the return value.
234+
*
235+
* @see <a
236+
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-extension-processing">§9.5.
237+
* Authenticator Extension Processing</a>
238+
* @see AuthenticatorAssertionExtensionOutputs
239+
* @see #getClientExtensionOutputs()
240+
*/
241+
@JsonIgnore
242+
public Optional<AuthenticatorAssertionExtensionOutputs> getAuthenticatorExtensionOutputs() {
243+
return AuthenticatorAssertionExtensionOutputs.fromAuthenticatorData(
244+
credentialResponse.getResponse().getParsedAuthenticatorData());
245+
}
246+
}

0 commit comments

Comments
 (0)