Extensions.java

1
package com.yubico.webauthn.data;
2
3
import com.fasterxml.jackson.annotation.JsonCreator;
4
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5
import com.fasterxml.jackson.annotation.JsonProperty;
6
import com.fasterxml.jackson.annotation.JsonValue;
7
import com.upokecenter.cbor.CBORObject;
8
import com.upokecenter.cbor.CBORType;
9
import com.yubico.internal.util.ExceptionUtil;
10
import com.yubico.webauthn.FinishRegistrationOptions;
11
import com.yubico.webauthn.RelyingParty;
12
import com.yubico.webauthn.StartAssertionOptions;
13
import com.yubico.webauthn.StartRegistrationOptions;
14
import com.yubico.webauthn.extension.uvm.KeyProtectionType;
15
import com.yubico.webauthn.extension.uvm.MatcherProtectionType;
16
import com.yubico.webauthn.extension.uvm.UserVerificationMethod;
17
import java.util.Arrays;
18
import java.util.List;
19
import java.util.Optional;
20
import java.util.Set;
21
import java.util.stream.Collectors;
22
import java.util.stream.Stream;
23
import lombok.AllArgsConstructor;
24
import lombok.Builder;
25
import lombok.NonNull;
26
import lombok.Value;
27
import lombok.experimental.UtilityClass;
28
import lombok.extern.slf4j.Slf4j;
29
30
/** Definitions for WebAuthn extensions. */
31
@Slf4j
32
@UtilityClass
33
public class Extensions {
34
35
  /**
36
   * Definitions for the FIDO AppID Extension (<code>appid</code>).
37
   *
38
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
39
   *     FIDO AppID Extension (appid)</a>
40
   */
41
  public static class Appid {
42
    static final String EXTENSION_ID = "appid";
43
  }
44
45
  /**
46
   * Definitions for the 10.2. FIDO AppID Exclusion Extension (<code>appidExclude</code>).
47
   *
48
   * @see <a
49
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-exclude-extension">10.2.
50
   *     FIDO AppID Exclusion Extension (appidExclude)</a>
51
   */
52
  public static class AppidExclude {
53
    static final String EXTENSION_ID = "appidExclude";
54
  }
55
56
  /**
57
   * Definitions for the Credential Properties Extension (<code>credProps</code>).
58
   *
59
   * @see <a
60
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-credential-properties-extension">§10.4.
61
   *     Credential Properties Extension (credProps)</a>
62
   */
63
  public static class CredentialProperties {
64
    static final String EXTENSION_ID = "credProps";
65
66
    /**
67
     * Extension outputs for the Credential Properties Extension (<code>credProps</code>).
68
     *
69
     * @see <a
70
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-credential-properties-extension">§10.4.
71
     *     Credential Properties Extension (credProps)</a>
72
     */
73
    @Value
74
    @Builder
75
    @JsonIgnoreProperties(ignoreUnknown = true)
76
    public static class CredentialPropertiesOutput {
77
      @JsonProperty("rk")
78
      private final Boolean rk;
79
80
      @JsonCreator
81
      private CredentialPropertiesOutput(@JsonProperty("rk") Boolean rk) {
82
        this.rk = rk;
83
      }
84
85
      /**
86
       * This OPTIONAL property, known abstractly as the <b>resident key credential property</b>
87
       * (i.e., <b>client-side discoverable credential property</b>), is a Boolean value indicating
88
       * whether the {@link PublicKeyCredential} returned as a result of a registration ceremony is
89
       * a <i>client-side discoverable credential</i> (passkey).
90
       *
91
       * <p>If this is <code>true</code>, the credential is a <i>discoverable credential</i>
92
       * (passkey).
93
       *
94
       * <p>If this is <code>false</code>, the credential is a <i>server-side credential</i>.
95
       *
96
       * <p>If this is not present, it is not known whether the credential is a discoverable
97
       * credential or a server-side credential.
98
       *
99
       * @see <a
100
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-credentialpropertiesoutput-rk">§10.4.
101
       *     Credential Properties Extension (credProps)</a>
102
       * @see <a
103
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-credential">Client-side
104
       *     discoverable Credential</a>
105
       * @see <a
106
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#server-side-credential">Server-side
107
       *     Credential</a>
108
       * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
109
       *     href="https://passkeys.dev">passkeys.dev</a> reference
110
       */
111
      public Optional<Boolean> getRk() {
112 1 1. getRk : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProperties$CredentialPropertiesOutput::getRk → KILLED
        return Optional.ofNullable(rk);
113
      }
114
    }
115
  }
116
117
  /**
118
   * Definitions for the Credential Protection (<code>credProtect</code>) extension.
119
   *
120
   * @see <a
121
   *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
122
   *     §12.1. Credential Protection (credProtect)</a>
123
   */
124
  public static class CredentialProtection {
125
    static final String EXTENSION_ID = "credProtect";
126
127
    /**
128
     * Policy values for the Credential Protection (<code>credProtect</code>) extension.
129
     *
130
     * <p>Available values:
131
     *
132
     * <ul>
133
     *   <li>{@link #UV_OPTIONAL}
134
     *   <li>{@link #UV_OPTIONAL_WITH_CREDENTIAL_ID_LIST}
135
     *   <li>{@link #UV_REQUIRED}
136
     * </ul>
137
     *
138
     * @see <a
139
     *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
140
     *     §12.1. Credential Protection (credProtect)</a>
141
     * @see CredentialProtectionInput#prefer(CredentialProtectionPolicy)
142
     * @see CredentialProtectionInput#require(CredentialProtectionPolicy)
143
     */
144
    @AllArgsConstructor
145
    public enum CredentialProtectionPolicy {
146
      /**
147
       * In this configuration, performing some form of user verification is always OPTIONAL. This
148
       * is the default behaviour if the extension is not specified; note however that some browsers
149
       * may set a different default extension input if the extension is not explicitly specified.
150
       *
151
       * @see <a
152
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
153
       *     §12.1. Credential Protection (credProtect)</a>
154
       * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User
155
       *     Verification</a>
156
       */
157
      UV_OPTIONAL(0x01, "userVerificationOptional"),
158
159
      /**
160
       * In this configuration, performing some form of user verification is OPTIONAL when the
161
       * credential is used as the second authentication factor, and REQUIRED when the credential is
162
       * used as the first authentication factor.
163
       *
164
       * <p>In technical terms, user verification is REQUIRED when {@link
165
       * PublicKeyCredentialRequestOptions#getAllowCredentials() allowCredentials} is empty and
166
       * OPTIONAL when it is non-empty. {@link
167
       * PublicKeyCredentialRequestOptions#getAllowCredentials() allowCredentials} is non-empty when
168
       * {@link StartAssertionOptions.StartAssertionOptionsBuilder#username(String) username} or
169
       * {@link StartAssertionOptions.StartAssertionOptionsBuilder#userHandle(ByteArray) userHandle}
170
       * was set in the call to {@link RelyingParty#startAssertion(StartAssertionOptions)}, and is
171
       * empty when neither was set.
172
       *
173
       * @see <a
174
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
175
       *     §12.1. Credential Protection (credProtect)</a>
176
       * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User
177
       *     Verification</a>
178
       */
179
      UV_OPTIONAL_WITH_CREDENTIAL_ID_LIST(0x02, "userVerificationOptionalWithCredentialIDList"),
180
181
      /**
182
       * In this configuration, performing some form of user verification is always REQUIRED.
183
       *
184
       * @see <a
185
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
186
       *     §12.1. Credential Protection (credProtect)</a>
187
       * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User
188
       *     Verification</a>
189
       */
190
      UV_REQUIRED(0x03, "userVerificationRequired");
191
192
      final int cborValue;
193
194
      @JsonValue private final String jsValue;
195
196
      private static Optional<CredentialProtectionPolicy> fromCbor(int cborValue) {
197 1 1. fromCbor : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromCbor → KILLED
        return Arrays.stream(CredentialProtectionPolicy.values())
198 2 1. lambda$fromCbor$0 : replaced boolean return with true for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromCbor$0 → KILLED
2. lambda$fromCbor$0 : negated conditional → KILLED
            .filter(policy -> policy.cborValue == cborValue)
199
            .findAny();
200
      }
201
202
      private static Optional<CredentialProtectionPolicy> fromJs(String jsonValue) {
203 1 1. fromJs : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromJs → KILLED
        return Arrays.stream(CredentialProtectionPolicy.values())
204 2 1. lambda$fromJs$1 : replaced boolean return with false for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJs$1 → KILLED
2. lambda$fromJs$1 : replaced boolean return with true for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJs$1 → KILLED
            .filter(policy -> policy.jsValue.equals(jsonValue))
205
            .findAny();
206
      }
207
208
      @JsonCreator
209 1 1. fromJsonString : negated conditional → KILLED
      private static CredentialProtectionPolicy fromJsonString(@NonNull String value) {
210 1 1. fromJsonString : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromJsonString → KILLED
        return fromJs(value)
211
            .orElseThrow(
212
                () ->
213 1 1. lambda$fromJsonString$2 : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJsonString$2 → NO_COVERAGE
                    new IllegalArgumentException(
214
                        String.format(
215
                            "Unknown %s value: %s",
216
                            CredentialProtectionPolicy.class.getSimpleName(), value)));
217
      }
218
    }
219
220
    /**
221
     * Extension inputs for the Credential Protection (<code>credProtect</code>) extension.
222
     *
223
     * <p>Instances may be created using the {@link #prefer(CredentialProtectionPolicy)} and {@link
224
     * #require(CredentialProtectionPolicy)} factory functions.
225
     *
226
     * @see <a
227
     *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
228
     *     §12.1. Credential Protection (credProtect)</a>
229
     */
230
    @Value
231
    public static class CredentialProtectionInput {
232
      /**
233
       * The requested credential protection policy. This policy may or may not be satisfied; see
234
       * {@link #isEnforceCredentialProtectionPolicy()}.
235
       *
236
       * @see CredentialProtectionPolicy
237
       * @see #isEnforceCredentialProtectionPolicy()
238
       * @see <a
239
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
240
       *     §12.1. Credential Protection (credProtect)</a>
241
       */
242
      private final CredentialProtectionPolicy credentialProtectionPolicy;
243
244
      /**
245
       * If this is <code>true</code> and {@link #getCredentialProtectionPolicy()
246
       * credentialProtectionPolicy} is not {@link CredentialProtectionPolicy#UV_OPTIONAL}, {@link
247
       * RelyingParty#finishRegistration(FinishRegistrationOptions)} will validate that the policy
248
       * set in {@link #getCredentialProtectionPolicy()} was satisfied and the browser is requested
249
       * to fail the registration if the policy cannot be satisfied.
250
       *
251
       * <p>{@link CredentialProtectionInput#prefer(CredentialProtectionPolicy)} sets this to <code>
252
       * false</code>. {@link CredentialProtectionInput#require(CredentialProtectionPolicy)} sets
253
       * this to <code>true</code>.
254
       *
255
       * @see CredentialProtectionPolicy
256
       * @see #getCredentialProtectionPolicy()
257
       * @see <a
258
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
259
       *     §12.1. Credential Protection (credProtect)</a>
260
       */
261
      private final boolean enforceCredentialProtectionPolicy;
262
263
      @JsonCreator
264
      private CredentialProtectionInput(
265
          @JsonProperty("credentialProtectionPolicy")
266
              CredentialProtectionPolicy credentialProtectionPolicy,
267
          @JsonProperty("enforceCredentialProtectionPolicy")
268
              Boolean enforceCredentialProtectionPolicy) {
269
        this.credentialProtectionPolicy = credentialProtectionPolicy;
270 1 1. <init> : negated conditional → KILLED
        this.enforceCredentialProtectionPolicy =
271 1 1. <init> : negated conditional → KILLED
            enforceCredentialProtectionPolicy != null && enforceCredentialProtectionPolicy;
272
      }
273
274
      /**
275
       * Create a Credential Protection (<code>credProtect</code>) extension input that requests the
276
       * given policy when possible.
277
       *
278
       * <p>If the policy cannot be satisfied, the browser is requested to continue the registration
279
       * anyway. To determine what policy was applied, use {@link
280
       * AuthenticatorRegistrationExtensionOutputs#getCredProtect()} to inspect the extension
281
       * output. {@link RelyingParty#finishRegistration(FinishRegistrationOptions)} will not
282
       * validate what policy was applied.
283
       *
284
       * <p>Use {@link #require(CredentialProtectionPolicy)} instead to forbid the registration from
285
       * proceeding if the extension is not supported or the policy cannot be satisfied.
286
       *
287
       * @param policy the policy to request.
288
       * @return a <code>credProtect</code> extension input that requests the given policy when
289
       *     possible. The browser is requested to continue the registration even if this policy
290
       *     cannot be satisfied.
291
       * @see #require(CredentialProtectionPolicy)
292
       * @see <a
293
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
294
       *     §12.1. Credential Protection (credProtect)</a>
295
       */
296
      public static CredentialProtectionInput prefer(
297 1 1. prefer : negated conditional → KILLED
          @NonNull final CredentialProtectionPolicy policy) {
298 1 1. prefer : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionInput::prefer → KILLED
        return new CredentialProtectionInput(policy, false);
299
      }
300
301
      /**
302
       * Create a Credential Protection (<code>credProtect</code>) extension input that requires the
303
       * given policy.
304
       *
305
       * <p>If the policy is not {@link CredentialProtectionPolicy#UV_OPTIONAL} and cannot be
306
       * satisfied, the browser is requested to abort the registration instead of proceeding. {@link
307
       * RelyingParty#finishRegistration(FinishRegistrationOptions)} will validate that the policy
308
       * returned in the authenticator extension output equals this input policy, and throw an
309
       * exception otherwise. You can also use {@link
310
       * AuthenticatorRegistrationExtensionOutputs#getCredProtect()} to inspect the extension output
311
       * yourself.
312
       *
313
       * <p>Note that if the browser or authenticator does not support the extension, the
314
       * registration will fail. Use {@link #prefer(CredentialProtectionPolicy)} instead to allow
315
       * the registration to proceed if the extension is not supported or the policy cannot be
316
       * satisfied.
317
       *
318
       * @param policy the policy to require.
319
       * @return a <code>credProtect</code> extension input that requires the given policy. The
320
       *     browser is requested to abort the registration if this policy cannot be satisfied.
321
       * @see <a
322
       *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
323
       *     §12.1. Credential Protection (credProtect)</a>
324
       */
325
      public static CredentialProtectionInput require(
326 1 1. require : negated conditional → KILLED
          @NonNull final CredentialProtectionPolicy policy) {
327 1 1. require : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionInput::require → KILLED
        return new CredentialProtectionInput(policy, true);
328
      }
329
    }
330
331
    /**
332
     * Validate that the given response satisfies the <code>credProtect</code> extension policy set
333
     * in the request.
334
     *
335
     * <p>If the {@link
336
     * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput)
337
     * credProtect} extension is not set in the request, this has no effect.
338
     *
339
     * <p>If the {@link
340
     * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput)
341
     * credProtect} extension is set in the request with {@link
342
     * CredentialProtectionInput#isEnforceCredentialProtectionPolicy()
343
     * enforceCredentialProtectionPolicy} set to <code>false</code> or {@link
344
     * CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} set to
345
     * {@link CredentialProtectionPolicy#UV_OPTIONAL}, this has no effect.
346
     *
347
     * <p>If the {@link
348
     * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput)
349
     * credProtect} extension is set in the request with {@link
350
     * CredentialProtectionInput#isEnforceCredentialProtectionPolicy()
351
     * enforceCredentialProtectionPolicy} set to <code>true</code> and {@link
352
     * CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} is not
353
     * set to {@link CredentialProtectionPolicy#UV_OPTIONAL}, then this throws an {@link
354
     * IllegalArgumentException} if the <code>credProtect</code> authenticator extension output does
355
     * not equal the {@link CredentialProtectionInput#getCredentialProtectionPolicy()
356
     * credentialProtectionPolicy} set in the request.
357
     *
358
     * <p>This function is called automatically in {@link
359
     * RelyingParty#finishRegistration(FinishRegistrationOptions)}; you should not need to call it
360
     * yourself.
361
     *
362
     * @param request the arguments to start the registration ceremony.
363
     * @param response the response from the registration ceremony.
364
     * @throws IllegalArgumentException if the {@link
365
     *     RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput)
366
     *     credProtect} extension is set in the request with {@link
367
     *     CredentialProtectionInput#isEnforceCredentialProtectionPolicy()
368
     *     enforceCredentialProtectionPolicy} set to <code>true</code> and {@link
369
     *     CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} not
370
     *     set to {@link CredentialProtectionPolicy#UV_OPTIONAL}, and the <code>credProtect
371
     *     </code> authenticator extension output does not equal the {@link
372
     *     CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} set
373
     *     in the request.
374
     * @see <a
375
     *     href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2
376
     *     §12.1. Credential Protection (credProtect)</a>
377
     */
378
    public static void validateExtensionOutput(
379
        PublicKeyCredentialCreationOptions request,
380
        PublicKeyCredential<AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs>
381
            response) {
382
      request
383
          .getExtensions()
384
          .getCredProtect()
385 1 1. validateExtensionOutput : removed call to java/util/Optional::ifPresent → KILLED
          .ifPresent(
386
              credProtectInput -> {
387 1 1. lambda$validateExtensionOutput$0 : negated conditional → KILLED
                if (credProtectInput.isEnforceCredentialProtectionPolicy()
388 1 1. lambda$validateExtensionOutput$0 : negated conditional → KILLED
                    && credProtectInput.getCredentialProtectionPolicy()
389
                        != CredentialProtectionPolicy.UV_OPTIONAL) {
390
                  Optional<CredentialProtectionPolicy> outputPolicy =
391
                      response
392
                          .getResponse()
393
                          .getParsedAuthenticatorData()
394
                          .getExtensions()
395
                          .flatMap(CredentialProtection::parseAuthenticatorExtensionOutput);
396 1 1. lambda$validateExtensionOutput$0 : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
                  ExceptionUtil.assertTrue(
397
                      outputPolicy.equals(
398
                          Optional.of(credProtectInput.getCredentialProtectionPolicy())),
399
                      "Unsatisfied credProtect policy: required %s, got: %s",
400
                      credProtectInput.getCredentialProtectionPolicy(),
401
                      outputPolicy);
402
                }
403
              });
404
    }
405
406
    static Optional<CredentialProtectionPolicy> parseAuthenticatorExtensionOutput(CBORObject cbor) {
407 1 1. parseAuthenticatorExtensionOutput : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection::parseAuthenticatorExtensionOutput → KILLED
      return Optional.ofNullable(cbor.get(EXTENSION_ID))
408
          .map(
409
              cborObject ->
410 3 1. lambda$parseAuthenticatorExtensionOutput$1 : replaced Integer return value with 0 for com/yubico/webauthn/data/Extensions$CredentialProtection::lambda$parseAuthenticatorExtensionOutput$1 → KILLED
2. lambda$parseAuthenticatorExtensionOutput$1 : negated conditional → KILLED
3. lambda$parseAuthenticatorExtensionOutput$1 : negated conditional → KILLED
                  cborObject.isNumber() && cborObject.AsNumber().IsInteger()
411
                      ? cborObject.AsInt32()
412
                      : null)
413 1 1. lambda$parseAuthenticatorExtensionOutput$2 : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection::lambda$parseAuthenticatorExtensionOutput$2 → KILLED
          .flatMap(CredentialProtectionPolicy::fromCbor);
414
    }
415
  }
416
417
  /**
418
   * Definitions for the Large blob storage extension (<code>largeBlob</code>).
419
   *
420
   * @see <a
421
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
422
   *     Large blob storage extension (largeBlob)</a>
423
   */
424
  public static class LargeBlob {
425
    static final String EXTENSION_ID = "largeBlob";
426
427
    /**
428
     * Extension inputs for the Large blob storage extension (<code>largeBlob</code>) in
429
     * registration ceremonies.
430
     *
431
     * @see <a
432
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
433
     *     Large blob storage extension (largeBlob)</a>
434
     */
435
    @Value
436
    public static class LargeBlobRegistrationInput {
437
      /**
438
       * The Relying Party's preference of whether the created credential should support the <code>
439
       * largeBlob</code> extension.
440
       */
441
      @JsonProperty private final LargeBlobSupport support;
442
443
      @JsonCreator
444
      public LargeBlobRegistrationInput(
445
          /**
446
           * The Relying Party's preference of whether the created credential should support the
447
           * <code>
448
           * largeBlob</code> extension.
449
           *
450
           * <p>Currently the only valid values are {@link LargeBlobSupport#REQUIRED} and {@link
451
           * LargeBlobSupport#PREFERRED}, but custom values MAY be constructed in case more values
452
           * are added in future revisions of the extension.
453
           */
454
          @JsonProperty("support") LargeBlobSupport support) {
455
        this.support = support;
456
      }
457
458
      /**
459
       * The known valid arguments for the Large blob storage extension (<code>largeBlob</code>)
460
       * input in registration ceremonies.
461
       *
462
       * <p>Currently the only valid values are {@link LargeBlobSupport#REQUIRED} and {@link
463
       * LargeBlobSupport#PREFERRED}, but custom values MAY be constructed in case more values are
464
       * added in future revisions of the extension.
465
       *
466
       * @see #REQUIRED
467
       * @see #PREFERRED
468
       * @see <a
469
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
470
       *     Large blob storage extension (largeBlob)</a>
471
       */
472
      @Value
473
      public static class LargeBlobSupport {
474
        /**
475
         * The authenticator used for registration MUST support the <code>largeBlob</code>
476
         * extension.
477
         *
478
         * <p>Note: If the client does not support the <code>largeBlob</code> extension, this
479
         * requirement MAY be ignored.
480
         *
481
         * <p>Note: CTAP authenticators only support <code>largeBlob</code> in combination with
482
         * {@link AuthenticatorSelectionCriteria#getResidentKey()} set to <code>REQUIRED</code> in
483
         * {@link StartRegistrationOptions#getAuthenticatorSelection()}.
484
         *
485
         * @see <a
486
         *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
487
         *     Large blob storage extension (largeBlob)</a>
488
         */
489
        public static final LargeBlobSupport REQUIRED = new LargeBlobSupport("required");
490
491
        /**
492
         * If the authenticator used for registration supports the <code>largeBlob</code> extension,
493
         * it will be enabled for the created credential. If not supported, the credential will be
494
         * created without large blob support.
495
         *
496
         * <p>Note: CTAP authenticators only support <code>largeBlob</code> in combination with
497
         * {@link AuthenticatorSelectionCriteria#getResidentKey()} set to <code>REQUIRED</code> in
498
         * {@link StartRegistrationOptions#getAuthenticatorSelection()}.
499
         *
500
         * @see <a
501
         *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
502
         *     Large blob storage extension (largeBlob)</a>
503
         */
504
        public static final LargeBlobSupport PREFERRED = new LargeBlobSupport("preferred");
505
506
        /**
507
         * The underlying string value of this {@link LargeBlobSupport} value.
508
         *
509
         * @see #REQUIRED
510
         * @see #PREFERRED
511
         */
512
        @JsonValue private final String value;
513
514
        /**
515
         * Returns a new {@link Set} containing the {@link #REQUIRED} and {@link #PREFERRED} values.
516
         */
517
        public static Set<LargeBlobSupport> values() {
518 1 1. values : replaced return value with Collections.emptySet for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobRegistrationInput$LargeBlobSupport::values → KILLED
          return Stream.of(REQUIRED, PREFERRED).collect(Collectors.toSet());
519
        }
520
      }
521
    }
522
523
    /**
524
     * Extension inputs for the Large blob storage extension (<code>largeBlob</code>) in
525
     * authentication ceremonies.
526
     *
527
     * <p>Use the {@link #read()} and {@link #write(ByteArray)} factory functions to construct this
528
     * type.
529
     *
530
     * @see <a
531
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
532
     *     Large blob storage extension (largeBlob)</a>
533
     */
534
    @Value
535
    public static class LargeBlobAuthenticationInput {
536
      /**
537
       * If <code>true</code>, indicates that the Relying Party would like to fetch the
538
       * previously-written blob associated with the asserted credential.
539
       *
540
       * @see #read()
541
       * @see <a
542
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5.
543
       *     Large blob storage extension (largeBlob)</a>
544
       */
545
      @JsonProperty private final boolean read;
546
547
      /**
548
       * An opaque byte string that the Relying Party wishes to store with the existing credential.
549
       *
550
       * @see #write(ByteArray)
551
       * @see <a
552
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-write">§10.5.
553
       *     Large blob storage extension (largeBlob)</a>
554
       */
555
      @JsonProperty private final ByteArray write;
556
557
      @JsonCreator
558
      private LargeBlobAuthenticationInput(
559
          @JsonProperty("read") final Boolean read, @JsonProperty("write") final ByteArray write) {
560 3 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
3. <init> : negated conditional → KILLED
        if (read != null && read && write != null) {
561
          throw new IllegalArgumentException(
562
              "Parameters \"read\" and \"write\" of largeBlob extension must not both be present.");
563
        }
564
565 2 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
        this.read = read != null && read;
566
        this.write = write;
567
      }
568
569
      /**
570
       * Configure the Large blob storage extension (<code>largeBlob</code>) to fetch the
571
       * previously-written blob associated with the asserted credential.
572
       *
573
       * <p>Mutually exclusive with {@link #write(ByteArray)}.
574
       *
575
       * @see <a
576
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5.
577
       *     Large blob storage extension (largeBlob)</a>
578
       */
579
      public static LargeBlobAuthenticationInput read() {
580 1 1. read : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::read → KILLED
        return new LargeBlobAuthenticationInput(true, null);
581
      }
582
583
      /**
584
       * Configure the Large blob storage extension (<code>largeBlob</code>) to store the given byte
585
       * array with the existing credential.
586
       *
587
       * <p>Mutually exclusive with {@link #read()}.
588
       *
589
       * @see <a
590
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-write">§10.5.
591
       *     Large blob storage extension (largeBlob)</a>
592
       */
593 1 1. write : negated conditional → KILLED
      public static LargeBlobAuthenticationInput write(@NonNull final ByteArray write) {
594 1 1. write : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::write → SURVIVED
        return new LargeBlobAuthenticationInput(false, write);
595
      }
596
597
      /**
598
       * @return <code>true</code> if the <code>read</code> property is set to <code>true</code>,
599
       *     <code>false</code> otherwise.
600
       * @see #read()
601
       * @see <a
602
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5.
603
       *     Large blob storage extension (largeBlob)</a>
604
       */
605
      public boolean getRead() {
606 2 1. getRead : replaced boolean return with false for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getRead → KILLED
2. getRead : replaced boolean return with true for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getRead → KILLED
        return read;
607
      }
608
609
      /**
610
       * @return The value of the <code>write</code> property if configured, empty otherwise.
611
       * @see #write(ByteArray)
612
       * @see <a
613
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5.
614
       *     Large blob storage extension (largeBlob)</a>
615
       */
616
      public Optional<ByteArray> getWrite() {
617 1 1. getWrite : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getWrite → SURVIVED
        return Optional.ofNullable(write);
618
      }
619
    }
620
621
    /**
622
     * Extension outputs for the Large blob storage extension (<code>largeBlob</code>) in
623
     * registration ceremonies.
624
     *
625
     * <p>Use the {@link #supported(boolean)} factory function to construct this type.
626
     *
627
     * @see <a
628
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
629
     *     Large blob storage extension (largeBlob)</a>
630
     */
631
    @Value
632
    public static class LargeBlobRegistrationOutput {
633
      /**
634
       * <code>true</code> if, and only if, the created credential supports storing large blobs.
635
       *
636
       * @see <a
637
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargebloboutputs-supported">§10.5.
638
       *     Large blob storage extension (largeBlob)</a>
639
       * @see LargeBlobRegistrationInput#getSupport()
640
       */
641
      @JsonProperty private final boolean supported;
642
643
      @JsonCreator
644
      private LargeBlobRegistrationOutput(@JsonProperty("supported") boolean supported) {
645
        this.supported = supported;
646
      }
647
648
      /**
649
       * Create a Large blob storage extension output with the <code>supported</code> output set to
650
       * the given value.
651
       *
652
       * @see <a
653
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-authenticationextensionslargebloboutputs">
654
       *     dictionary AuthenticationExtensionsLargeBlobOutputs</a>
655
       */
656
      public static LargeBlobRegistrationOutput supported(boolean supported) {
657 1 1. supported : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobRegistrationOutput::supported → KILLED
        return new LargeBlobRegistrationOutput(supported);
658
      }
659
    }
660
661
    /**
662
     * Extension outputs for the Large blob storage extension (<code>largeBlob</code>) in
663
     * authentication ceremonies.
664
     *
665
     * @see <a
666
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
667
     *     Large blob storage extension (largeBlob)</a>
668
     */
669
    @Value
670
    public static class LargeBlobAuthenticationOutput {
671
      @JsonProperty private final ByteArray blob;
672
      @JsonProperty private final Boolean written;
673
674
      @JsonCreator
675
      private LargeBlobAuthenticationOutput(
676
          @JsonProperty("blob") ByteArray blob, @JsonProperty("written") Boolean written) {
677
        this.blob = blob;
678
        this.written = written;
679
      }
680
681
      /**
682
       * Create a Large blob storage extension output with the <code>blob</code> output set to the
683
       * given value.
684
       *
685
       * <p>This corresponds to the extension input {@link LargeBlobAuthenticationInput#read()
686
       * LargeBlobAuthenticationInput.read()}.
687
       *
688
       * @see <a
689
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-authenticationextensionslargebloboutputs">
690
       *     dictionary AuthenticationExtensionsLargeBlobOutputs</a>
691
       */
692
      public static LargeBlobAuthenticationOutput read(final ByteArray blob) {
693 1 1. read : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::read → KILLED
        return new LargeBlobAuthenticationOutput(blob, null);
694
      }
695
696
      /**
697
       * Create a Large blob storage extension output with the <code>written</code> output set to
698
       * the given value.
699
       *
700
       * <p>This corresponds to the extension input {@link
701
       * LargeBlobAuthenticationInput#write(ByteArray)
702
       * LargeBlobAuthenticationInput.write(ByteArray)}.
703
       *
704
       * @see <a
705
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-authenticationextensionslargebloboutputs">
706
       *     dictionary AuthenticationExtensionsLargeBlobOutputs</a>
707
       */
708
      public static LargeBlobAuthenticationOutput write(final boolean write) {
709 1 1. write : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::write → KILLED
        return new LargeBlobAuthenticationOutput(null, write);
710
      }
711
712
      /**
713
       * The opaque byte string that was associated with the credential identified by {@link
714
       * PublicKeyCredential#getId()}. Only valid if {@link LargeBlobAuthenticationInput#getRead()}
715
       * was <code>true</code>.
716
       *
717
       * @return A present {@link Optional} if {@link LargeBlobAuthenticationInput#getRead()} was
718
       *     <code>true</code> and the blob content was successfully read. Otherwise (if {@link
719
       *     LargeBlobAuthenticationInput#getRead()} was <code>false</code> or the content failed to
720
       *     be read) an empty {@link Optional}.
721
       * @see <a
722
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargebloboutputs-blob">§10.5.
723
       *     Large blob storage extension (largeBlob)</a>
724
       */
725
      public Optional<ByteArray> getBlob() {
726 1 1. getBlob : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::getBlob → KILLED
        return Optional.ofNullable(blob);
727
      }
728
729
      /**
730
       * A boolean that indicates that the contents of {@link
731
       * LargeBlob.LargeBlobAuthenticationInput#write(ByteArray)
732
       * LargeBlobAuthenticationInput#write(ByteArray)} were successfully stored on the
733
       * authenticator, associated with the specified credential.
734
       *
735
       * @return Empty if {@link LargeBlobAuthenticationInput#getWrite()} was not present. Otherwise
736
       *     <code>true</code> if and only if the value of {@link
737
       *     LargeBlobAuthenticationInput#getWrite()} was successfully stored by the authenticator.
738
       * @see <a
739
       *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargebloboutputs-written">§10.5.
740
       *     Large blob storage extension (largeBlob)</a>
741
       */
742
      public Optional<Boolean> getWritten() {
743 1 1. getWritten : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::getWritten → KILLED
        return Optional.ofNullable(written);
744
      }
745
    }
746
  }
747
748
  /**
749
   * Definitions for the User Verification Method (<code>uvm</code>) Extension.
750
   *
751
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3.
752
   *     User Verification Method Extension (uvm)</a>
753
   */
754
  public static class Uvm {
755
    static final String EXTENSION_ID = "uvm";
756
757
    /**
758
     * A <code>uvmEntry</code> as defined in <a
759
     * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3. User
760
     * Verification Method Extension (uvm)</a>.
761
     *
762
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3.
763
     *     User Verification Method Extension (uvm)</a>
764
     * @see UserVerificationMethod
765
     * @see KeyProtectionType
766
     * @see MatcherProtectionType
767
     */
768
    @Value
769
    public static class UvmEntry {
770
      private final UserVerificationMethod userVerificationMethod;
771
      private final KeyProtectionType keyProtectionType;
772
      private final MatcherProtectionType matcherProtectionType;
773
774
      public UvmEntry(
775
          @JsonProperty("userVerificationMethod") UserVerificationMethod userVerificationMethod,
776
          @JsonProperty("keyProtectionType") KeyProtectionType keyProtectionType,
777
          @JsonProperty("matcherProtectionType") MatcherProtectionType matcherProtectionType) {
778
        this.userVerificationMethod = userVerificationMethod;
779
        this.keyProtectionType = keyProtectionType;
780
        this.matcherProtectionType = matcherProtectionType;
781
      }
782
    }
783
784
    static Optional<List<UvmEntry>> parseAuthenticatorExtensionOutput(CBORObject cbor) {
785 1 1. parseAuthenticatorExtensionOutput : negated conditional → KILLED
      if (validateAuthenticatorExtensionOutput(cbor)) {
786 1 1. parseAuthenticatorExtensionOutput : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Uvm::parseAuthenticatorExtensionOutput → KILLED
        return Optional.of(
787
            cbor.get(EXTENSION_ID).getValues().stream()
788
                .map(
789
                    uvmEntry ->
790 1 1. lambda$parseAuthenticatorExtensionOutput$0 : replaced return value with null for com/yubico/webauthn/data/Extensions$Uvm::lambda$parseAuthenticatorExtensionOutput$0 → KILLED
                        new UvmEntry(
791
                            UserVerificationMethod.fromValue(uvmEntry.get(0).AsInt32Value()),
792
                            KeyProtectionType.fromValue(
793
                                uvmEntry.get(1).AsNumber().ToInt16IfExact()),
794
                            MatcherProtectionType.fromValue(
795
                                uvmEntry.get(2).AsNumber().ToInt16IfExact())))
796
                .collect(Collectors.toList()));
797
      } else {
798
        return Optional.empty();
799
      }
800
    }
801
802
    private static boolean validateAuthenticatorExtensionOutput(CBORObject extensions) {
803 1 1. validateAuthenticatorExtensionOutput : negated conditional → KILLED
      if (!extensions.ContainsKey(EXTENSION_ID)) {
804 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → KILLED
        return false;
805
      }
806
807
      CBORObject uvm = extensions.get(EXTENSION_ID);
808 1 1. validateAuthenticatorExtensionOutput : negated conditional → KILLED
      if (uvm.getType() != CBORType.Array) {
809
        log.debug(
810
            "Invalid CBOR type for \"{}\" extension output: expected array, was: {}",
811
            EXTENSION_ID,
812
            uvm.getType());
813 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE
        return false;
814
      }
815
816 4 1. validateAuthenticatorExtensionOutput : changed conditional boundary → SURVIVED
2. validateAuthenticatorExtensionOutput : changed conditional boundary → SURVIVED
3. validateAuthenticatorExtensionOutput : negated conditional → KILLED
4. validateAuthenticatorExtensionOutput : negated conditional → KILLED
      if (uvm.size() < 1 || uvm.size() > 3) {
817
        log.debug(
818
            "Invalid length \"{}\" extension output array: expected 1 to 3 (inclusive), was: {}",
819
            EXTENSION_ID,
820
            uvm.size());
821 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE
        return false;
822
      }
823
824
      for (CBORObject entry : uvm.getValues()) {
825 1 1. validateAuthenticatorExtensionOutput : negated conditional → KILLED
        if (entry.getType() != CBORType.Array) {
826
          log.debug("Invalid CBOR type for uvmEntry: expected array, was: {}", entry.getType());
827 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE
          return false;
828
        }
829
830 1 1. validateAuthenticatorExtensionOutput : negated conditional → KILLED
        if (entry.size() != 3) {
831
          log.debug("Invalid length for uvmEntry: expected 3, was: {}", entry.size());
832 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE
          return false;
833
        }
834
835
        for (CBORObject i : entry.getValues()) {
836 2 1. validateAuthenticatorExtensionOutput : negated conditional → KILLED
2. validateAuthenticatorExtensionOutput : negated conditional → KILLED
          if (!(i.isNumber() && i.AsNumber().IsInteger())) {
837
            log.debug("Invalid type for uvmEntry element: expected integer, was: {}", i.getType());
838 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE
            return false;
839
          }
840
        }
841
      }
842
843 1 1. validateAuthenticatorExtensionOutput : replaced boolean return with false for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → KILLED
      return true;
844
    }
845
  }
846
}

Mutations

112

1.1
Location : getRk
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProperties$CredentialPropertiesOutput::getRk → KILLED

197

1.1
Location : fromCbor
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromCbor → KILLED

198

1.1
Location : lambda$fromCbor$0
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced boolean return with true for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromCbor$0 → KILLED

2.2
Location : lambda$fromCbor$0
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

203

1.1
Location : fromJs
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromJs → KILLED

204

1.1
Location : lambda$fromJs$1
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced boolean return with false for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJs$1 → KILLED

2.2
Location : lambda$fromJs$1
Killed by : com.yubico.webauthn.data.JsonIoSpec
replaced boolean return with true for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJs$1 → KILLED

209

1.1
Location : fromJsonString
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

210

1.1
Location : fromJsonString
Killed by : com.yubico.webauthn.data.JsonIoSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromJsonString → KILLED

213

1.1
Location : lambda$fromJsonString$2
Killed by : none
replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJsonString$2 → NO_COVERAGE

270

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

271

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

297

1.1
Location : prefer
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

298

1.1
Location : prefer
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionInput::prefer → KILLED

326

1.1
Location : require
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

327

1.1
Location : require
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionInput::require → KILLED

385

1.1
Location : validateExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
removed call to java/util/Optional::ifPresent → KILLED

387

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

388

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

396

1.1
Location : lambda$validateExtensionOutput$0
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED

407

1.1
Location : parseAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection::parseAuthenticatorExtensionOutput → KILLED

410

1.1
Location : lambda$parseAuthenticatorExtensionOutput$1
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced Integer return value with 0 for com/yubico/webauthn/data/Extensions$CredentialProtection::lambda$parseAuthenticatorExtensionOutput$1 → KILLED

2.2
Location : lambda$parseAuthenticatorExtensionOutput$1
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
negated conditional → KILLED

3.3
Location : lambda$parseAuthenticatorExtensionOutput$1
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
negated conditional → KILLED

413

1.1
Location : lambda$parseAuthenticatorExtensionOutput$2
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection::lambda$parseAuthenticatorExtensionOutput$2 → KILLED

518

1.1
Location : values
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with Collections.emptySet for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobRegistrationInput$LargeBlobSupport::values → KILLED

560

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

2.2
Location : <init>
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

3.3
Location : <init>
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

565

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

2.2
Location : <init>
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

580

1.1
Location : read
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::read → KILLED

593

1.1
Location : write
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

594

1.1
Location : write
Killed by : none
replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::write → SURVIVED

606

1.1
Location : getRead
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced boolean return with false for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getRead → KILLED

2.2
Location : getRead
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced boolean return with true for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getRead → KILLED

617

1.1
Location : getWrite
Killed by : none
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getWrite → SURVIVED

657

1.1
Location : supported
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobRegistrationOutput::supported → KILLED

693

1.1
Location : read
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::read → KILLED

709

1.1
Location : write
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::write → KILLED

726

1.1
Location : getBlob
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::getBlob → KILLED

743

1.1
Location : getWritten
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::getWritten → KILLED

785

1.1
Location : parseAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

786

1.1
Location : parseAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Uvm::parseAuthenticatorExtensionOutput → KILLED

790

1.1
Location : lambda$parseAuthenticatorExtensionOutput$0
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with null for com/yubico/webauthn/data/Extensions$Uvm::lambda$parseAuthenticatorExtensionOutput$0 → KILLED

803

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

804

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → KILLED

808

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

813

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : none
replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE

816

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : validateAuthenticatorExtensionOutput
Killed by : none
changed conditional boundary → SURVIVED

3.3
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

4.4
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

821

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : none
replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE

825

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

827

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : none
replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE

830

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

832

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : none
replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE

836

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

2.2
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
negated conditional → KILLED

838

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : none
replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE

843

1.1
Location : validateAuthenticatorExtensionOutput
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with false for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0