AssertionResultV2.java

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 1 1. <init> : negated conditional → KILLED
      @NonNull @JsonProperty("credentialResponse")
104
          PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
105
              credentialResponse,
106 1 1. <init> : negated conditional → KILLED
      @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 2 1. isUserVerified : replaced boolean return with false for com/yubico/webauthn/AssertionResultV2::isUserVerified → KILLED
2. isUserVerified : replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::isUserVerified → KILLED
    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 2 1. isBackupEligible : replaced boolean return with false for com/yubico/webauthn/AssertionResultV2::isBackupEligible → KILLED
2. isBackupEligible : replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::isBackupEligible → KILLED
    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 2 1. isBackedUp : replaced boolean return with false for com/yubico/webauthn/AssertionResultV2::isBackedUp → KILLED
2. isBackedUp : replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::isBackedUp → KILLED
    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 1 1. getAuthenticatorAttachment : replaced return value with Optional.empty for com/yubico/webauthn/AssertionResultV2::getAuthenticatorAttachment → KILLED
    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 1 1. getSignatureCount : replaced long return with 0 for com/yubico/webauthn/AssertionResultV2::getSignatureCount → KILLED
    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 1 1. getClientExtensionOutputs : replaced return value with Optional.empty for com/yubico/webauthn/AssertionResultV2::getClientExtensionOutputs → KILLED
    return Optional.of(credentialResponse.getClientExtensionResults())
225 2 1. lambda$getClientExtensionOutputs$0 : replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::lambda$getClientExtensionOutputs$0 → SURVIVED
2. lambda$getClientExtensionOutputs$0 : negated conditional → KILLED
        .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 1 1. getAuthenticatorExtensionOutputs : replaced return value with Optional.empty for com/yubico/webauthn/AssertionResultV2::getAuthenticatorExtensionOutputs → KILLED
    return AuthenticatorAssertionExtensionOutputs.fromAuthenticatorData(
244
        credentialResponse.getResponse().getParsedAuthenticatorData());
245
  }
246
}

Mutations

103

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

106

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

130

1.1
Location : isUserVerified
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with false for com/yubico/webauthn/AssertionResultV2::isUserVerified → KILLED

2.2
Location : isUserVerified
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::isUserVerified → KILLED

155

1.1
Location : isBackupEligible
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with false for com/yubico/webauthn/AssertionResultV2::isBackupEligible → KILLED

2.2
Location : isBackupEligible
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::isBackupEligible → KILLED

179

1.1
Location : isBackedUp
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with false for com/yubico/webauthn/AssertionResultV2::isBackedUp → KILLED

2.2
Location : isBackedUp
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::isBackedUp → KILLED

193

1.1
Location : getAuthenticatorAttachment
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/AssertionResultV2::getAuthenticatorAttachment → KILLED

206

1.1
Location : getSignatureCount
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced long return with 0 for com/yubico/webauthn/AssertionResultV2::getSignatureCount → KILLED

224

1.1
Location : getClientExtensionOutputs
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/AssertionResultV2::getClientExtensionOutputs → KILLED

225

1.1
Location : lambda$getClientExtensionOutputs$0
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

2.2
Location : lambda$getClientExtensionOutputs$0
Killed by : none
replaced boolean return with true for com/yubico/webauthn/AssertionResultV2::lambda$getClientExtensionOutputs$0 → SURVIVED

243

1.1
Location : getAuthenticatorExtensionOutputs
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/AssertionResultV2::getAuthenticatorExtensionOutputs → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0