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

Mutations

111

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

115

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

128

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

129

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

133

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

134

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

136

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

149

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

154

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

158

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

168

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

177

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

187

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

192

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

203

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

211

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

226

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

234

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

239

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

243

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

253

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

258

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

262

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

273

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

281

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

292

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

293

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

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

299

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

313

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

315

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

323

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

344

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

346

1.1
Location : lambda$validate$0
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
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.RelyingPartyRegistrationSpec
negated conditional → KILLED

361

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

372

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

377

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

391

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

395

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

401

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

403

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

405

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

407

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

409

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

411

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

426

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

428

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

433

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

438

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

443

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

444

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

446

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

449

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

451

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

460

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

462

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

464

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

501

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

505

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

507

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

509

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

518

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

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

520

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

521

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

554

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

555

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

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

561

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

565

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

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

567

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

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

568

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

577

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

579

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

580

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

581

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

582

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

583

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

586

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

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

591

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

592

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

597

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

610

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

616

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

623

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

636

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

649

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

657

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

677

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

682

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