FinishRegistrationSteps.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 static com.yubico.internal.util.ExceptionUtil.assertTrue;
28
import static com.yubico.internal.util.ExceptionUtil.wrapAndLog;
29
30
import com.upokecenter.cbor.CBORObject;
31
import com.yubico.internal.util.CertificateParser;
32
import com.yubico.internal.util.OptionalUtil;
33
import com.yubico.webauthn.attestation.AttestationTrustSource;
34
import com.yubico.webauthn.attestation.AttestationTrustSource.TrustRootsResult;
35
import com.yubico.webauthn.data.AttestationObject;
36
import com.yubico.webauthn.data.AttestationType;
37
import com.yubico.webauthn.data.AuthenticatorAttestationResponse;
38
import com.yubico.webauthn.data.AuthenticatorSelectionCriteria;
39
import com.yubico.webauthn.data.ByteArray;
40
import com.yubico.webauthn.data.ClientRegistrationExtensionOutputs;
41
import com.yubico.webauthn.data.CollectedClientData;
42
import com.yubico.webauthn.data.Extensions;
43
import com.yubico.webauthn.data.PublicKeyCredential;
44
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions;
45
import com.yubico.webauthn.data.PublicKeyCredentialParameters;
46
import com.yubico.webauthn.data.UserVerificationRequirement;
47
import java.io.IOException;
48
import java.security.InvalidAlgorithmParameterException;
49
import java.security.NoSuchAlgorithmException;
50
import java.security.cert.CertPath;
51
import java.security.cert.CertPathValidator;
52
import java.security.cert.CertPathValidatorException;
53
import java.security.cert.CertificateException;
54
import java.security.cert.CertificateFactory;
55
import java.security.cert.PKIXCertPathValidatorResult;
56
import java.security.cert.PKIXParameters;
57
import java.security.cert.PKIXReason;
58
import java.security.cert.TrustAnchor;
59
import java.security.cert.X509Certificate;
60
import java.security.spec.InvalidKeySpecException;
61
import java.sql.Date;
62
import java.time.Clock;
63
import java.util.List;
64
import java.util.Optional;
65
import java.util.Set;
66
import java.util.stream.Collectors;
67
import lombok.AllArgsConstructor;
68
import lombok.Value;
69
import lombok.extern.slf4j.Slf4j;
70
71
@Slf4j
72
@AllArgsConstructor
73
final class FinishRegistrationSteps {
74
75
  private static final String CLIENT_DATA_TYPE = "webauthn.create";
76
  private static final ByteArray ZERO_AAGUID =
77
      new ByteArray(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
78
79
  private final PublicKeyCredentialCreationOptions request;
80
  private final PublicKeyCredential<
81
          AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs>
82
      response;
83
  private final Optional<ByteArray> callerTokenBindingId;
84
  private final Set<String> origins;
85
  private final String rpId;
86
  private final boolean allowUntrustedAttestation;
87
  private final Optional<AttestationTrustSource> attestationTrustSource;
88
  private final CredentialRepositoryV2<?> credentialRepositoryV2;
89
  private final Clock clock;
90
  private final boolean allowOriginPort;
91
  private final boolean allowOriginSubdomain;
92
  private final boolean isConditionalCreate;
93
94
  static FinishRegistrationSteps fromV1(RelyingParty rp, FinishRegistrationOptions options) {
95 1 1. fromV1 : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps::fromV1 → KILLED
    return new FinishRegistrationSteps(
96
        options.getRequest(),
97
        options.getResponse(),
98
        options.getCallerTokenBindingId(),
99
        rp.getOrigins(),
100
        rp.getIdentity().getId(),
101
        rp.isAllowUntrustedAttestation(),
102
        rp.getAttestationTrustSource(),
103
        new CredentialRepositoryV1ToV2Adapter(rp.getCredentialRepository()),
104
        rp.getClock(),
105
        rp.isAllowOriginPort(),
106
        rp.isAllowOriginSubdomain(),
107
        options.isConditionalCreate());
108
  }
109
110
  FinishRegistrationSteps(RelyingPartyV2<?> rp, FinishRegistrationOptions options) {
111
    this(
112
        options.getRequest(),
113
        options.getResponse(),
114
        options.getCallerTokenBindingId(),
115
        rp.getOrigins(),
116
        rp.getIdentity().getId(),
117
        rp.isAllowUntrustedAttestation(),
118
        rp.getAttestationTrustSource(),
119
        rp.getCredentialRepository(),
120
        rp.getClock(),
121
        rp.isAllowOriginPort(),
122
        rp.isAllowOriginSubdomain(),
123
        options.isConditionalCreate());
124
  }
125
126
  public Step6 begin() {
127 1 1. begin : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps::begin → KILLED
    return new Step6();
128
  }
129
130
  public RegistrationResult run() {
131 1 1. run : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps::run → KILLED
    return begin().run();
132
  }
133
134
  interface Step<Next extends Step<?>> {
135
    Next nextStep();
136
137
    void validate();
138
139
    default Optional<RegistrationResult> result() {
140
      return Optional.empty();
141
    }
142
143
    default Next next() {
144 1 1. next : removed call to com/yubico/webauthn/FinishRegistrationSteps$Step::validate → KILLED
      validate();
145 1 1. next : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step::next → KILLED
      return nextStep();
146
    }
147
148
    default RegistrationResult run() {
149 1 1. run : negated conditional → KILLED
      if (result().isPresent()) {
150 1 1. run : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step::run → KILLED
        return result().get();
151
      } else {
152 1 1. run : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step::run → KILLED
        return next().run();
153
      }
154
    }
155
  }
156
157
  // Steps 1 through 4 are to create the request and run the client-side part
158
159
  // Step 5 is integrated into step 6 here
160
161
  @Value
162
  class Step6 implements Step<Step7> {
163
    @Override
164
    public void validate() {
165 2 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED
2. validate : negated conditional → KILLED
      assertTrue(clientData() != null, "Client data must not be null.");
166
    }
167
168
    @Override
169
    public Step7 nextStep() {
170 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step6::nextStep → KILLED
      return new Step7(clientData());
171
    }
172
173
    public CollectedClientData clientData() {
174 1 1. clientData : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step6::clientData → KILLED
      return response.getResponse().getClientData();
175
    }
176
  }
177
178
  @Value
179
  class Step7 implements Step<Step8> {
180
    private final CollectedClientData clientData;
181
182
    @Override
183
    public void validate() {
184 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
185
          CLIENT_DATA_TYPE.equals(clientData.getType()),
186
          "The \"type\" in the client data must be exactly \"%s\", was: %s",
187
          CLIENT_DATA_TYPE,
188
          clientData.getType());
189
    }
190
191
    @Override
192
    public Step8 nextStep() {
193 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step7::nextStep → KILLED
      return new Step8(clientData);
194
    }
195
  }
196
197
  @Value
198
  class Step8 implements Step<Step9> {
199
    private final CollectedClientData clientData;
200
201
    @Override
202
    public void validate() {
203 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(request.getChallenge().equals(clientData.getChallenge()), "Incorrect challenge.");
204
    }
205
206
    @Override
207
    public Step9 nextStep() {
208 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step8::nextStep → KILLED
      return new Step9(clientData);
209
    }
210
  }
211
212
  @Value
213
  class Step9 implements Step<Step10> {
214
    private final CollectedClientData clientData;
215
216
    @Override
217
    public void validate() {
218
      final String responseOrigin = clientData.getOrigin();
219 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
220
          OriginMatcher.isAllowed(responseOrigin, origins, allowOriginPort, allowOriginSubdomain),
221
          "Incorrect origin, please see the RelyingParty.origins setting: %s",
222
          responseOrigin);
223
    }
224
225
    @Override
226
    public Step10 nextStep() {
227 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step9::nextStep → KILLED
      return new Step10(clientData);
228
    }
229
  }
230
231
  @Value
232
  class Step10 implements Step<Step11> {
233
    private final CollectedClientData clientData;
234
235
    @Override
236
    public void validate() {
237
      TokenBindingValidator.validate(clientData.getTokenBinding(), callerTokenBindingId);
238
    }
239
240
    @Override
241
    public Step11 nextStep() {
242 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step10::nextStep → KILLED
      return new Step11();
243
    }
244
  }
245
246
  @Value
247
  class Step11 implements Step<Step12> {
248
    @Override
249
    public void validate() {
250 2 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED
2. validate : negated conditional → KILLED
      assertTrue(clientDataJsonHash().size() == 32, "Failed to compute hash of client data");
251
    }
252
253
    @Override
254
    public Step12 nextStep() {
255 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step11::nextStep → KILLED
      return new Step12(clientDataJsonHash());
256
    }
257
258
    public ByteArray clientDataJsonHash() {
259 1 1. clientDataJsonHash : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step11::clientDataJsonHash → KILLED
      return Crypto.sha256(response.getResponse().getClientDataJSON());
260
    }
261
  }
262
263
  @Value
264
  class Step12 implements Step<Step13> {
265
    private final ByteArray clientDataJsonHash;
266
267
    @Override
268
    public void validate() {
269 2 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED
2. validate : negated conditional → KILLED
      assertTrue(attestation() != null, "Malformed attestation object.");
270
    }
271
272
    @Override
273
    public Step13 nextStep() {
274 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step12::nextStep → KILLED
      return new Step13(clientDataJsonHash, attestation());
275
    }
276
277
    public AttestationObject attestation() {
278 1 1. attestation : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step12::attestation → KILLED
      return response.getResponse().getAttestation();
279
    }
280
  }
281
282
  @Value
283
  class Step13 implements Step<Step14> {
284
    private final ByteArray clientDataJsonHash;
285
    private final AttestationObject attestation;
286
287
    @Override
288
    public void validate() {
289 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
290
          Crypto.sha256(rpId)
291
              .equals(response.getResponse().getAttestation().getAuthenticatorData().getRpIdHash()),
292
          "Wrong RP ID hash.");
293
    }
294
295
    @Override
296
    public Step14 nextStep() {
297 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step13::nextStep → KILLED
      return new Step14(clientDataJsonHash, attestation);
298
    }
299
  }
300
301
  @Value
302
  class Step14 implements Step<Step15> {
303
    private final ByteArray clientDataJsonHash;
304
    private final AttestationObject attestation;
305
306
    @Override
307
    public void validate() {
308 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
309 2 1. validate : negated conditional → KILLED
2. validate : negated conditional → KILLED
          isConditionalCreate || response.getResponse().getParsedAuthenticatorData().getFlags().UP,
310
          "User Presence is required unless isConditionalCreate is true.");
311
    }
312
313
    @Override
314
    public Step15 nextStep() {
315 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step14::nextStep → KILLED
      return new Step15(clientDataJsonHash, attestation);
316
    }
317
  }
318
319
  @Value
320
  class Step15 implements Step<Step16> {
321
    private final ByteArray clientDataJsonHash;
322
    private final AttestationObject attestation;
323
324
    @Override
325
    public void validate() {
326
      if (request
327
              .getAuthenticatorSelection()
328
              .flatMap(AuthenticatorSelectionCriteria::getUserVerification)
329 1 1. validate : negated conditional → KILLED
              .orElse(UserVerificationRequirement.PREFERRED)
330
          == UserVerificationRequirement.REQUIRED) {
331 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
        assertTrue(
332
            response.getResponse().getParsedAuthenticatorData().getFlags().UV,
333
            "User Verification is required.");
334
      }
335
    }
336
337
    @Override
338
    public Step16 nextStep() {
339 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step15::nextStep → KILLED
      return new Step16(clientDataJsonHash, attestation);
340
    }
341
  }
342
343
  @Value
344
  class Step16 implements Step<Step17> {
345
    private final ByteArray clientDataJsonHash;
346
    private final AttestationObject attestation;
347
348
    @Override
349
    public void validate() {
350
      final ByteArray publicKeyCose =
351
          response
352
              .getResponse()
353
              .getAttestation()
354
              .getAuthenticatorData()
355
              .getAttestedCredentialData()
356
              .get()
357
              .getCredentialPublicKey();
358
      CBORObject publicKeyCbor = CBORObject.DecodeFromBytes(publicKeyCose.getBytes());
359
      final int alg = publicKeyCbor.get(CBORObject.FromObject(3)).AsInt32();
360 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
361
          request.getPubKeyCredParams().stream()
362 2 1. lambda$validate$0 : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step16::lambda$validate$0 → KILLED
2. lambda$validate$0 : negated conditional → KILLED
              .anyMatch(pkcparam -> pkcparam.getAlg().getId() == alg),
363
          "Unrequested credential key algorithm: got %d, expected one of: %s",
364
          alg,
365
          request.getPubKeyCredParams().stream()
366
              .map(PublicKeyCredentialParameters::getAlg)
367
              .collect(Collectors.toList()));
368
      try {
369
        WebAuthnCodecs.importCosePublicKey(publicKeyCose);
370
      } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) {
371
        throw wrapAndLog(log, "Failed to parse credential public key", e);
372
      }
373
    }
374
375
    @Override
376
    public Step17 nextStep() {
377 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step16::nextStep → KILLED
      return new Step17(clientDataJsonHash, attestation);
378
    }
379
  }
380
381
  @Value
382
  class Step17 implements Step<Step18> {
383
    private final ByteArray clientDataJsonHash;
384
    private final AttestationObject attestation;
385
386
    @Override
387
    public void validate() {
388 1 1. validate : removed call to com/yubico/webauthn/data/Extensions$CredentialProtection::validateExtensionOutput → KILLED
      Extensions.CredentialProtection.validateExtensionOutput(request, response);
389
    }
390
391
    @Override
392
    public Step18 nextStep() {
393 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step17::nextStep → KILLED
      return new Step18(clientDataJsonHash, attestation);
394
    }
395
  }
396
397
  @Value
398
  class Step18 implements Step<Step19> {
399
    private final ByteArray clientDataJsonHash;
400
    private final AttestationObject attestation;
401
402
    @Override
403
    public void validate() {}
404
405
    @Override
406
    public Step19 nextStep() {
407 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step18::nextStep → KILLED
      return new Step19(clientDataJsonHash, attestation, attestationStatementVerifier());
408
    }
409
410
    public String format() {
411 1 1. format : replaced return value with "" for com/yubico/webauthn/FinishRegistrationSteps$Step18::format → KILLED
      return attestation.getFormat();
412
    }
413
414
    public Optional<AttestationStatementVerifier> attestationStatementVerifier() {
415
      switch (format()) {
416
        case "fido-u2f":
417 1 1. attestationStatementVerifier : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED
          return Optional.of(new FidoU2fAttestationStatementVerifier());
418
        case "none":
419 1 1. attestationStatementVerifier : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED
          return Optional.of(new NoneAttestationStatementVerifier());
420
        case "packed":
421 1 1. attestationStatementVerifier : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED
          return Optional.of(new PackedAttestationStatementVerifier());
422
        case "android-safetynet":
423 1 1. attestationStatementVerifier : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED
          return Optional.of(new AndroidSafetynetAttestationStatementVerifier());
424
        case "apple":
425 1 1. attestationStatementVerifier : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED
          return Optional.of(new AppleAttestationStatementVerifier());
426
        case "tpm":
427 1 1. attestationStatementVerifier : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED
          return Optional.of(new TpmAttestationStatementVerifier());
428
        default:
429
          return Optional.empty();
430
      }
431
    }
432
  }
433
434
  @Value
435
  class Step19 implements Step<Step20> {
436
    private final ByteArray clientDataJsonHash;
437
    private final AttestationObject attestation;
438
    private final Optional<AttestationStatementVerifier> attestationStatementVerifier;
439
440
    @Override
441
    public void validate() {
442 1 1. validate : removed call to java/util/Optional::ifPresent → KILLED
      attestationStatementVerifier.ifPresent(
443
          verifier -> {
444 1 1. lambda$validate$0 : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
            assertTrue(
445
                verifier.verifyAttestationSignature(attestation, clientDataJsonHash),
446
                "Invalid attestation signature.");
447
          });
448
449 2 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED
2. validate : negated conditional → KILLED
      assertTrue(attestationType() != null, "Failed to determine attestation type");
450
    }
451
452
    @Override
453
    public Step20 nextStep() {
454 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::nextStep → KILLED
      return new Step20(attestation, attestationType(), attestationTrustPath());
455
    }
456
457
    public AttestationType attestationType() {
458
      try {
459 1 1. attestationType : negated conditional → KILLED
        if (attestationStatementVerifier.isPresent()) {
460 1 1. attestationType : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationType → KILLED
          return attestationStatementVerifier.get().getAttestationType(attestation);
461
        } else {
462 1 1. attestationType : negated conditional → SURVIVED
          switch (attestation.getFormat()) {
463
            case "android-key":
464
              // TODO delete this once android-key attestation verification is implemented
465 1 1. attestationType : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationType → KILLED
              return AttestationType.BASIC;
466
            default:
467 1 1. attestationType : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationType → KILLED
              return AttestationType.UNKNOWN;
468
          }
469
        }
470
      } catch (IOException | CertificateException e) {
471
        throw new IllegalArgumentException("Failed to resolve attestation type.", e);
472
      }
473
    }
474
475
    public Optional<List<X509Certificate>> attestationTrustPath() {
476 1 1. attestationTrustPath : negated conditional → KILLED
      if (attestationStatementVerifier.isPresent()) {
477
        AttestationStatementVerifier verifier = attestationStatementVerifier.get();
478 1 1. attestationTrustPath : negated conditional → KILLED
        if (verifier instanceof X5cAttestationStatementVerifier) {
479
          try {
480 1 1. attestationTrustPath : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationTrustPath → KILLED
            return ((X5cAttestationStatementVerifier) verifier)
481
                .getAttestationTrustPath(attestation);
482
          } catch (CertificateException e) {
483
            throw new IllegalArgumentException("Failed to resolve attestation trust path.", e);
484
          }
485
        } else {
486
          return Optional.empty();
487
        }
488
      } else {
489
        return Optional.empty();
490
      }
491
    }
492
  }
493
494
  @Value
495
  class Step20 implements Step<Step21> {
496
    private final AttestationObject attestation;
497
    private final AttestationType attestationType;
498
    private final Optional<List<X509Certificate>> attestationTrustPath;
499
500
    private final Optional<AttestationTrustSource.TrustRootsResult> trustRoots;
501
502
    public Step20(
503
        AttestationObject attestation,
504
        AttestationType attestationType,
505
        Optional<List<X509Certificate>> attestationTrustPath) {
506
      this.attestation = attestation;
507
      this.attestationType = attestationType;
508
      this.attestationTrustPath = attestationTrustPath;
509
      this.trustRoots = findTrustRoots();
510
    }
511
512
    @Override
513
    public void validate() {}
514
515
    @Override
516
    public Step21 nextStep() {
517 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step20::nextStep → KILLED
      return new Step21(attestation, attestationType, attestationTrustPath, trustRoots);
518
    }
519
520
    private Optional<AttestationTrustSource.TrustRootsResult> findTrustRoots() {
521 1 1. findTrustRoots : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step20::findTrustRoots → KILLED
      return attestationTrustSource.flatMap(
522
          attestationTrustSource ->
523 1 1. lambda$findTrustRoots$3 : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$3 → KILLED
              attestationTrustPath.map(
524
                  atp ->
525 1 1. lambda$findTrustRoots$2 : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$2 → KILLED
                      attestationTrustSource.findTrustRoots(
526
                          atp,
527
                          OptionalUtil.orElseOptional(
528
                              Optional.of(
529
                                      attestation
530
                                          .getAuthenticatorData()
531
                                          .getAttestedCredentialData()
532
                                          .get()
533
                                          .getAaguid())
534 2 1. lambda$findTrustRoots$0 : negated conditional → KILLED
2. lambda$findTrustRoots$0 : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$0 → KILLED
                                  .filter(aaguid -> !aaguid.equals(ZERO_AAGUID)),
535
                              () -> {
536 1 1. lambda$findTrustRoots$1 : negated conditional → KILLED
                                if (!atp.isEmpty()) {
537 1 1. lambda$findTrustRoots$1 : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$1 → KILLED
                                  return CertificateParser.parseFidoAaguidExtension(atp.get(0))
538
                                      .map(ByteArray::new);
539
                                } else {
540
                                  return Optional.empty();
541
                                }
542
                              }))));
543
    }
544
  }
545
546
  @Value
547
  class Step21 implements Step<Step22> {
548
    private final AttestationObject attestation;
549
    private final AttestationType attestationType;
550
    private final Optional<List<X509Certificate>> attestationTrustPath;
551
    private final Optional<AttestationTrustSource.TrustRootsResult> trustRoots;
552
553
    private final boolean attestationTrusted;
554
555
    public Step21(
556
        AttestationObject attestation,
557
        AttestationType attestationType,
558
        Optional<List<X509Certificate>> attestationTrustPath,
559
        Optional<AttestationTrustSource.TrustRootsResult> trustRoots) {
560
      this.attestation = attestation;
561
      this.attestationType = attestationType;
562
      this.attestationTrustPath = attestationTrustPath;
563
      this.trustRoots = trustRoots;
564
565
      this.attestationTrusted = attestationTrusted();
566
    }
567
568
    @Override
569
    public void validate() {
570 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
571 2 1. validate : negated conditional → KILLED
2. validate : negated conditional → KILLED
          allowUntrustedAttestation || attestationTrusted,
572
          "Failed to derive trust for attestation key.");
573
    }
574
575
    @Override
576
    public Step22 nextStep() {
577 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step21::nextStep → KILLED
      return new Step22(attestationType, attestationTrusted, attestationTrustPath);
578
    }
579
580
    public boolean attestationTrusted() {
581 2 1. attestationTrusted : negated conditional → KILLED
2. attestationTrusted : negated conditional → KILLED
      if (attestationTrustPath.isPresent() && attestationTrustSource.isPresent()) {
582
        try {
583 2 1. attestationTrusted : negated conditional → KILLED
2. attestationTrusted : negated conditional → KILLED
          if (!trustRoots.isPresent() || trustRoots.get().getTrustRoots().isEmpty()) {
584 1 1. attestationTrusted : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED
            return false;
585
586
          } else {
587
            final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
588
            final CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
589
            final CertPath certPath = certFactory.generateCertPath(attestationTrustPath.get());
590
            final PKIXParameters pathParams =
591
                new PKIXParameters(
592
                    trustRoots.get().getTrustRoots().stream()
593 1 1. lambda$attestationTrusted$0 : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step21::lambda$attestationTrusted$0 → KILLED
                        .map(rootCert -> new TrustAnchor(rootCert, null))
594
                        .collect(Collectors.toSet()));
595 1 1. attestationTrusted : removed call to java/security/cert/PKIXParameters::setDate → KILLED
            pathParams.setDate(Date.from(clock.instant()));
596 1 1. attestationTrusted : removed call to java/security/cert/PKIXParameters::setRevocationEnabled → KILLED
            pathParams.setRevocationEnabled(trustRoots.get().isEnableRevocationChecking());
597 1 1. attestationTrusted : removed call to java/security/cert/PKIXParameters::setPolicyQualifiersRejected → SURVIVED
            pathParams.setPolicyQualifiersRejected(
598 1 1. attestationTrusted : negated conditional → SURVIVED
                !trustRoots.get().getPolicyTreeValidator().isPresent());
599 1 1. attestationTrusted : removed call to java/util/Optional::ifPresent → KILLED
            trustRoots.get().getCertStore().ifPresent(pathParams::addCertStore);
600
            final PKIXCertPathValidatorResult result =
601
                (PKIXCertPathValidatorResult) cpv.validate(certPath, pathParams);
602 2 1. attestationTrusted : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED
2. attestationTrusted : replaced boolean return with false for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED
            return trustRoots
603
                .get()
604
                .getPolicyTreeValidator()
605
                .map(
606
                    policyNodePredicate -> {
607 1 1. lambda$attestationTrusted$1 : negated conditional → KILLED
                      if (policyNodePredicate.test(result.getPolicyTree())) {
608 1 1. lambda$attestationTrusted$1 : replaced Boolean return with False for com/yubico/webauthn/FinishRegistrationSteps$Step21::lambda$attestationTrusted$1 → KILLED
                        return true;
609
                      } else {
610
                        log.info(
611
                            "Failed to derive trust in attestation statement: Certificate path policy tree does not satisfy policy tree validator. Attestation object: {}",
612
                            response.getResponse().getAttestationObject());
613 1 1. lambda$attestationTrusted$1 : replaced Boolean return with True for com/yubico/webauthn/FinishRegistrationSteps$Step21::lambda$attestationTrusted$1 → KILLED
                        return false;
614
                      }
615
                    })
616
                .orElse(true);
617
          }
618
619
        } catch (CertPathValidatorException e) {
620
          log.info(
621
              "Failed to derive trust in attestation statement: {} at cert index {}: {}. Attestation object: {}",
622
              e.getReason(),
623
              e.getIndex(),
624
              e.getMessage(),
625
              response.getResponse().getAttestationObject());
626 1 1. attestationTrusted : negated conditional → SURVIVED
          if (PKIXReason.INVALID_POLICY.equals(e.getReason())) {
627
            log.info(
628
                "You may need to set the policyTreeValidator property on the {} returned by your {}.",
629
                TrustRootsResult.class.getSimpleName(),
630
                AttestationTrustSource.class.getSimpleName());
631
          }
632 1 1. attestationTrusted : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → SURVIVED
          return false;
633
634
        } catch (CertificateException e) {
635
          log.warn(
636
              "Failed to build attestation certificate path. Attestation object: {}",
637
              response.getResponse().getAttestationObject(),
638
              e);
639 1 1. attestationTrusted : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → NO_COVERAGE
          return false;
640
641
        } catch (NoSuchAlgorithmException e) {
642
          throw new RuntimeException(
643
              "Failed to check attestation trust path. A JCA provider is likely missing in the runtime environment.",
644
              e);
645
646
        } catch (InvalidAlgorithmParameterException e) {
647
          throw new RuntimeException(
648
              "Failed to initialize attestation trust path validator. This is likely a bug, please file a bug report.",
649
              e);
650
        }
651
      } else {
652 1 1. attestationTrusted : replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED
        return false;
653
      }
654
    }
655
  }
656
657
  @Value
658
  class Step22 implements Step<Finished> {
659
    private final AttestationType attestationType;
660
    private final boolean attestationTrusted;
661
    private final Optional<List<X509Certificate>> attestationTrustPath;
662
663
    @Override
664
    public void validate() {
665 1 1. validate : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED
      assertTrue(
666 1 1. validate : negated conditional → KILLED
          !credentialRepositoryV2.credentialIdExists(response.getId()),
667
          "Credential ID is already registered: %s",
668
          response.getId());
669
    }
670
671
    @Override
672
    public Finished nextStep() {
673 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step22::nextStep → KILLED
      return new Finished(attestationType, attestationTrusted, attestationTrustPath);
674
    }
675
  }
676
677
  // Step 23 will be performed externally by library user
678
  // Nothing to do for step 24
679
680
  @Value
681
  class Finished implements Step<Finished> {
682
    private final AttestationType attestationType;
683
    private final boolean attestationTrusted;
684
    private final Optional<List<X509Certificate>> attestationTrustPath;
685
686
    @Override
687
    public void validate() {
688
      /* No-op */
689
    }
690
691
    @Override
692
    public Finished nextStep() {
693 1 1. nextStep : replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Finished::nextStep → NO_COVERAGE
      return this;
694
    }
695
696
    @Override
697
    public Optional<RegistrationResult> result() {
698 1 1. result : replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Finished::result → KILLED
      return Optional.of(
699
          new RegistrationResult(
700
              response, attestationTrusted, attestationType, attestationTrustPath));
701
    }
702
  }
703
}

Mutations

95

1.1
Location : fromV1
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps::fromV1 → KILLED

127

1.1
Location : begin
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps::begin → KILLED

131

1.1
Location : run
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps::run → KILLED

144

1.1
Location : next
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
removed call to com/yubico/webauthn/FinishRegistrationSteps$Step::validate → KILLED

145

1.1
Location : next
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step::next → KILLED

149

1.1
Location : run
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

150

1.1
Location : run
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step::run → KILLED

152

1.1
Location : run
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step::run → KILLED

165

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

2.2
Location : validate
Killed by : none
removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED

170

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step6::nextStep → KILLED

174

1.1
Location : clientData
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step6::clientData → KILLED

184

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

193

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step7::nextStep → KILLED

203

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

208

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step8::nextStep → KILLED

219

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

227

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step9::nextStep → KILLED

242

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step10::nextStep → KILLED

250

1.1
Location : validate
Killed by : none
removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED

2.2
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

255

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step11::nextStep → KILLED

259

1.1
Location : clientDataJsonHash
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step11::clientDataJsonHash → KILLED

269

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

2.2
Location : validate
Killed by : none
removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED

274

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step12::nextStep → KILLED

278

1.1
Location : attestation
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step12::attestation → KILLED

289

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

297

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step13::nextStep → KILLED

308

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

309

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

2.2
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

315

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step14::nextStep → KILLED

329

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

331

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

339

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step15::nextStep → KILLED

360

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

362

1.1
Location : lambda$validate$0
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step16::lambda$validate$0 → KILLED

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

377

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step16::nextStep → KILLED

388

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
removed call to com/yubico/webauthn/data/Extensions$CredentialProtection::validateExtensionOutput → KILLED

393

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step17::nextStep → KILLED

407

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step18::nextStep → KILLED

411

1.1
Location : format
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with "" for com/yubico/webauthn/FinishRegistrationSteps$Step18::format → KILLED

417

1.1
Location : attestationStatementVerifier
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED

419

1.1
Location : attestationStatementVerifier
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED

421

1.1
Location : attestationStatementVerifier
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED

423

1.1
Location : attestationStatementVerifier
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED

425

1.1
Location : attestationStatementVerifier
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED

427

1.1
Location : attestationStatementVerifier
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step18::attestationStatementVerifier → KILLED

442

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

444

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

449

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

2.2
Location : validate
Killed by : none
removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → SURVIVED

454

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::nextStep → KILLED

459

1.1
Location : attestationType
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

460

1.1
Location : attestationType
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationType → KILLED

462

1.1
Location : attestationType
Killed by : none
negated conditional → SURVIVED

465

1.1
Location : attestationType
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationType → KILLED

467

1.1
Location : attestationType
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationType → KILLED

476

1.1
Location : attestationTrustPath
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

478

1.1
Location : attestationTrustPath
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

480

1.1
Location : attestationTrustPath
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step19::attestationTrustPath → KILLED

517

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step20::nextStep → KILLED

521

1.1
Location : findTrustRoots
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step20::findTrustRoots → KILLED

523

1.1
Location : lambda$findTrustRoots$3
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$3 → KILLED

525

1.1
Location : lambda$findTrustRoots$2
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$2 → KILLED

534

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

2.2
Location : lambda$findTrustRoots$0
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$0 → KILLED

536

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

537

1.1
Location : lambda$findTrustRoots$1
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Step20::lambda$findTrustRoots$1 → KILLED

570

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

571

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

2.2
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

577

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step21::nextStep → KILLED

581

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

2.2
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

583

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

2.2
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

584

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED

593

1.1
Location : lambda$attestationTrusted$0
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step21::lambda$attestationTrusted$0 → KILLED

595

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
removed call to java/security/cert/PKIXParameters::setDate → KILLED

596

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
removed call to java/security/cert/PKIXParameters::setRevocationEnabled → KILLED

597

1.1
Location : attestationTrusted
Killed by : none
removed call to java/security/cert/PKIXParameters::setPolicyQualifiersRejected → SURVIVED

598

1.1
Location : attestationTrusted
Killed by : none
negated conditional → SURVIVED

599

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

602

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED

2.2
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with false for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED

607

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

608

1.1
Location : lambda$attestationTrusted$1
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced Boolean return with False for com/yubico/webauthn/FinishRegistrationSteps$Step21::lambda$attestationTrusted$1 → KILLED

613

1.1
Location : lambda$attestationTrusted$1
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced Boolean return with True for com/yubico/webauthn/FinishRegistrationSteps$Step21::lambda$attestationTrusted$1 → KILLED

626

1.1
Location : attestationTrusted
Killed by : none
negated conditional → SURVIVED

632

1.1
Location : attestationTrusted
Killed by : none
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → SURVIVED

639

1.1
Location : attestationTrusted
Killed by : none
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → NO_COVERAGE

652

1.1
Location : attestationTrusted
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced boolean return with true for com/yubico/webauthn/FinishRegistrationSteps$Step21::attestationTrusted → KILLED

665

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

666

1.1
Location : validate
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
negated conditional → KILLED

673

1.1
Location : nextStep
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Step22::nextStep → KILLED

693

1.1
Location : nextStep
Killed by : none
replaced return value with null for com/yubico/webauthn/FinishRegistrationSteps$Finished::nextStep → NO_COVERAGE

698

1.1
Location : result
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with Optional.empty for com/yubico/webauthn/FinishRegistrationSteps$Finished::result → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0