RelyingParty.java

1
// Copyright (c) 2018, Yubico AB
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
//
7
// 1. Redistributions of source code must retain the above copyright notice, this
8
//    list of conditions and the following disclaimer.
9
//
10
// 2. Redistributions in binary form must reproduce the above copyright notice,
11
//    this list of conditions and the following disclaimer in the documentation
12
//    and/or other materials provided with the distribution.
13
//
14
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25
package com.yubico.webauthn;
26
27
import com.yubico.internal.util.CollectionUtil;
28
import com.yubico.internal.util.OptionalUtil;
29
import com.yubico.webauthn.attestation.AttestationTrustSource;
30
import com.yubico.webauthn.data.AssertionExtensionInputs;
31
import com.yubico.webauthn.data.AttestationConveyancePreference;
32
import com.yubico.webauthn.data.AuthenticatorData;
33
import com.yubico.webauthn.data.ByteArray;
34
import com.yubico.webauthn.data.CollectedClientData;
35
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions;
36
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions.PublicKeyCredentialCreationOptionsBuilder;
37
import com.yubico.webauthn.data.PublicKeyCredentialParameters;
38
import com.yubico.webauthn.data.PublicKeyCredentialRequestOptions;
39
import com.yubico.webauthn.data.PublicKeyCredentialRequestOptions.PublicKeyCredentialRequestOptionsBuilder;
40
import com.yubico.webauthn.data.RegistrationExtensionInputs;
41
import com.yubico.webauthn.data.RelyingPartyIdentity;
42
import com.yubico.webauthn.exception.AssertionFailedException;
43
import com.yubico.webauthn.exception.InvalidSignatureCountException;
44
import com.yubico.webauthn.exception.RegistrationFailedException;
45
import com.yubico.webauthn.extension.appid.AppId;
46
import java.net.MalformedURLException;
47
import java.net.URL;
48
import java.security.KeyFactory;
49
import java.security.NoSuchAlgorithmException;
50
import java.security.SecureRandom;
51
import java.security.Signature;
52
import java.time.Clock;
53
import java.util.ArrayList;
54
import java.util.Arrays;
55
import java.util.Collections;
56
import java.util.List;
57
import java.util.Optional;
58
import java.util.Set;
59
import java.util.stream.Collectors;
60
import lombok.Builder;
61
import lombok.NonNull;
62
import lombok.Value;
63
import lombok.extern.slf4j.Slf4j;
64
65
/**
66
 * Encapsulates the four basic Web Authentication operations - start/finish registration,
67
 * start/finish authentication - along with overall operational settings for them.
68
 *
69
 * <p>This class has no mutable state. An instance of this class may therefore be thought of as a
70
 * container for specialized versions (function closures) of these four operations rather than a
71
 * stateful object.
72
 */
73
@Slf4j
74
@Builder(toBuilder = true)
75
@Value
76
public class RelyingParty {
77
78
  private static final SecureRandom random = new SecureRandom();
79
80
  /**
81
   * The {@link RelyingPartyIdentity} that will be set as the {@link
82
   * PublicKeyCredentialCreationOptions#getRp() rp} parameter when initiating registration
83
   * operations, and which {@link AuthenticatorData#getRpIdHash()} will be compared against. This is
84
   * a required parameter.
85
   *
86
   * <p>A successful registration or authentication operation requires {@link
87
   * AuthenticatorData#getRpIdHash()} to exactly equal the SHA-256 hash of this member's {@link
88
   * RelyingPartyIdentity#getId() id} member. Alternatively, it may instead equal the SHA-256 hash
89
   * of {@link #getAppId() appId} if the latter is present.
90
   *
91
   * @see #startRegistration(StartRegistrationOptions)
92
   * @see PublicKeyCredentialCreationOptions
93
   */
94
  @NonNull private final RelyingPartyIdentity identity;
95
96
  /**
97
   * The allowed origins that returned authenticator responses will be compared against.
98
   *
99
   * <p>The default is the set containing only the string <code>
100
   * "https://" + {@link #getIdentity()}.getId()</code>.
101
   *
102
   * <p>If {@link RelyingPartyBuilder#allowOriginPort(boolean) allowOriginPort} and {@link
103
   * RelyingPartyBuilder#allowOriginSubdomain(boolean) allowOriginSubdomain} are both <code>false
104
   * </code> (the default), then a successful registration or authentication operation requires
105
   * {@link CollectedClientData#getOrigin()} to exactly equal one of these values.
106
   *
107
   * <p>If {@link RelyingPartyBuilder#allowOriginPort(boolean) allowOriginPort} is <code>true</code>
108
   * , then the above rule is relaxed to allow any port number in {@link
109
   * CollectedClientData#getOrigin()}, regardless of any port specified.
110
   *
111
   * <p>If {@link RelyingPartyBuilder#allowOriginSubdomain(boolean) allowOriginSubdomain} is <code>
112
   * true</code>, then the above rule is relaxed to allow any subdomain, of any depth, of any of
113
   * these values.
114
   *
115
   * <p>For either of the above relaxations to take effect, both the allowed origin and the client
116
   * data origin must be valid URLs. Origins that are not valid URLs are matched only by exact
117
   * string equality.
118
   *
119
   * @see #getIdentity()
120
   */
121
  @NonNull private final Set<String> origins;
122
123
  /**
124
   * An abstract database which can look up credentials, usernames and user handles from usernames,
125
   * user handles and credential IDs. This is a required parameter.
126
   *
127
   * <p>This is used to look up:
128
   *
129
   * <ul>
130
   *   <li>the user handle for a user logging in via user name
131
   *   <li>the user name for a user logging in via user handle
132
   *   <li>the credential IDs to include in {@link
133
   *       PublicKeyCredentialCreationOptions#getExcludeCredentials()}
134
   *   <li>the credential IDs to include in {@link
135
   *       PublicKeyCredentialRequestOptions#getAllowCredentials()}
136
   *   <li>that the correct user owns the credential when verifying an assertion
137
   *   <li>the public key to use to verify an assertion
138
   *   <li>the stored signature counter when verifying an assertion
139
   * </ul>
140
   */
141
  @NonNull private final CredentialRepository credentialRepository;
142
143
  /**
144
   * The extension input to set for the <code>appid</code> and <code>appidExclude</code> extensions.
145
   *
146
   * <p>You do not need this extension if you have not previously supported U2F. Its purpose is to
147
   * make already-registered U2F credentials forward-compatible with the WebAuthn API. It is not
148
   * needed for new registrations, even of U2F authenticators.
149
   *
150
   * <p>If this member is set, {@link #startAssertion(StartAssertionOptions) startAssertion} will
151
   * automatically set the <code>appid</code> extension input, and {@link
152
   * #finishAssertion(FinishAssertionOptions) finishAssertion} will adjust its verification logic to
153
   * also accept this AppID as an alternative to the RP ID. Likewise, {@link
154
   * #startRegistration(StartRegistrationOptions)} startRegistration} will automatically set the
155
   * <code>appidExclude</code> extension input.
156
   *
157
   * <p>By default, this is not set.
158
   *
159
   * @see AssertionExtensionInputs#getAppid()
160
   * @see RegistrationExtensionInputs#getAppidExclude()
161
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
162
   *     FIDO AppID Extension (appid)</a>
163
   * @see <a
164
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-exclude-extension">§10.2.
165
   *     FIDO AppID Exclusion Extension (appidExclude)</a>
166
   */
167
  @NonNull private final Optional<AppId> appId;
168
169
  /**
170
   * The argument for the {@link PublicKeyCredentialCreationOptions#getAttestation() attestation}
171
   * parameter in registration operations.
172
   *
173
   * <p>Unless your application has a concrete policy for authenticator attestation, it is
174
   * recommended to leave this parameter undefined.
175
   *
176
   * <p>If you set this, you may want to explicitly set {@link
177
   * RelyingPartyBuilder#allowUntrustedAttestation(boolean) allowUntrustedAttestation} and {@link
178
   * RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource) attestationTrustSource} too.
179
   *
180
   * <p>By default, this is not set.
181
   *
182
   * @see PublicKeyCredentialCreationOptions#getAttestation()
183
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
184
   *     Attestation</a>
185
   */
186
  @NonNull private final Optional<AttestationConveyancePreference> attestationConveyancePreference;
187
188
  /**
189
   * An {@link AttestationTrustSource} instance to use for looking up trust roots for authenticator
190
   * attestation. This matters only if {@link #getAttestationConveyancePreference()} is non-empty
191
   * and not set to {@link AttestationConveyancePreference#NONE}.
192
   *
193
   * <p>By default, this is not set.
194
   *
195
   * @see PublicKeyCredentialCreationOptions#getAttestation()
196
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
197
   *     Attestation</a>
198
   */
199
  @NonNull private final Optional<AttestationTrustSource> attestationTrustSource;
200
201
  /**
202
   * The argument for the {@link PublicKeyCredentialCreationOptions#getPubKeyCredParams()
203
   * pubKeyCredParams} parameter in registration operations.
204
   *
205
   * <p>This is a list of acceptable public key algorithms and their parameters, ordered from most
206
   * to least preferred.
207
   *
208
   * <p>The default is the following list, in order:
209
   *
210
   * <ol>
211
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#ES256 ES256}
212
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#EdDSA EdDSA}
213
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#ES384 ES384}
214
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#ES512 ES512}
215
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#RS256 RS256}
216
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#RS384 RS384}
217
   *   <li>{@link com.yubico.webauthn.data.PublicKeyCredentialParameters#RS512 RS512}
218
   * </ol>
219
   *
220
   * @since 0.2.0
221
   * @see PublicKeyCredentialCreationOptions#getAttestation()
222
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
223
   *     Attestation</a>
224
   */
225
  @Builder.Default @NonNull
226
  private final List<PublicKeyCredentialParameters> preferredPubkeyParams =
227
      Collections.unmodifiableList(
228
          Arrays.asList(
229
              PublicKeyCredentialParameters.ES256,
230
              PublicKeyCredentialParameters.EdDSA,
231
              PublicKeyCredentialParameters.ES384,
232
              PublicKeyCredentialParameters.ES512,
233
              PublicKeyCredentialParameters.RS256,
234
              PublicKeyCredentialParameters.RS384,
235
              PublicKeyCredentialParameters.RS512));
236
237
  /**
238
   * If <code>true</code>, the origin matching rule is relaxed to allow any port number.
239
   *
240
   * <p>The default is <code>false</code>.
241
   *
242
   * <p>Examples with <code>
243
   * origins: ["https://example.org", "https://accounts.example.org", "https://acme.com:8443"]
244
   * </code>
245
   *
246
   * <ul>
247
   *   <li>
248
   *       <p><code>allowOriginPort: false</code>
249
   *       <p>Accepted:
250
   *       <ul>
251
   *         <li><code>https://example.org</code>
252
   *         <li><code>https://accounts.example.org</code>
253
   *         <li><code>https://acme.com:8443</code>
254
   *       </ul>
255
   *       <p>Rejected:
256
   *       <ul>
257
   *         <li><code>https://example.org:8443</code>
258
   *         <li><code>https://shop.example.org</code>
259
   *         <li><code>https://acme.com</code>
260
   *         <li><code>https://acme.com:9000</code>
261
   *       </ul>
262
   *   <li>
263
   *       <p><code>allowOriginPort: true</code>
264
   *       <p>Accepted:
265
   *       <ul>
266
   *         <li><code>https://example.org</code>
267
   *         <li><code>https://example.org:8443</code>
268
   *         <li><code>https://accounts.example.org</code>
269
   *         <li><code>https://acme.com</code>
270
   *         <li><code>https://acme.com:8443</code>
271
   *         <li><code>https://acme.com:9000</code>
272
   *       </ul>
273
   *       <p>Rejected:
274
   *       <ul>
275
   *         <li><code>https://shop.example.org</code>
276
   *       </ul>
277
   * </ul>
278
   */
279
  @Builder.Default private final boolean allowOriginPort = false;
280
281
  /**
282
   * If <code>true</code>, the origin matching rule is relaxed to allow any subdomain, of any depth,
283
   * of the values of {@link RelyingPartyBuilder#origins(Set) origins}.
284
   *
285
   * <p>Please see <a
286
   * href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#sctn-code-injection">Security
287
   * Considerations: Code injection attacks</a> for discussion of the risks in setting this to
288
   * <code>true</code>.
289
   *
290
   * <p>The default is <code>false</code>.
291
   *
292
   * <p>Examples with <code>origins: ["https://example.org", "https://acme.com:8443"]</code>
293
   *
294
   * <ul>
295
   *   <li>
296
   *       <p><code>allowOriginSubdomain: false</code>
297
   *       <p>Accepted:
298
   *       <ul>
299
   *         <li><code>https://example.org</code>
300
   *         <li><code>https://acme.com:8443</code>
301
   *       </ul>
302
   *       <p>Rejected:
303
   *       <ul>
304
   *         <li><code>https://example.org:8443</code>
305
   *         <li><code>https://accounts.example.org</code>
306
   *         <li><code>https://acme.com</code>
307
   *         <li><code>https://eu.shop.acme.com:8443</code>
308
   *       </ul>
309
   *   <li>
310
   *       <p><code>allowOriginSubdomain: true</code>
311
   *       <p>Accepted:
312
   *       <ul>
313
   *         <li><code>https://example.org</code>
314
   *         <li><code>https://accounts.example.org</code>
315
   *         <li><code>https://acme.com:8443</code>
316
   *         <li><code>https://eu.shop.acme.com:8443</code>
317
   *       </ul>
318
   *       <p>Rejected:
319
   *       <ul>
320
   *         <li><code>https://example.org:8443</code>
321
   *         <li><code>https://acme.com</code>
322
   *       </ul>
323
   * </ul>
324
   *
325
   * @see <a href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#sctn-code-injection">§13.4.8.
326
   *     Code injection attacks</a>
327
   */
328
  @Builder.Default private final boolean allowOriginSubdomain = false;
329
330
  /**
331
   * If <code>false</code>, {@link #finishRegistration(FinishRegistrationOptions)
332
   * finishRegistration} will only allow registrations where the attestation signature can be linked
333
   * to a trusted attestation root. This excludes none attestation, and self attestation unless the
334
   * self attestation key is explicitly trusted.
335
   *
336
   * <p>Regardless of the value of this option, invalid attestation statements of supported formats
337
   * will always be rejected. For example, a "packed" attestation statement with an invalid
338
   * signature will be rejected even if this option is set to <code>true</code>.
339
   *
340
   * <p>The default is <code>true</code>.
341
   */
342
  @Builder.Default private final boolean allowUntrustedAttestation = true;
343
344
  /**
345
   * If <code>true</code>, {@link #finishAssertion(FinishAssertionOptions) finishAssertion} will
346
   * succeed only if the {@link AuthenticatorData#getSignatureCounter() signature counter value} in
347
   * the response is strictly greater than the {@link RegisteredCredential#getSignatureCount()
348
   * stored signature counter value}, or if both counters are exactly zero.
349
   *
350
   * <p>The default is <code>true</code>.
351
   */
352
  @Builder.Default private final boolean validateSignatureCounter = true;
353
354
  /**
355
   * A {@link Clock} which will be used to tell the current time while verifying attestation
356
   * certificate chains.
357
   *
358
   * <p>This is intended primarily for testing, and relevant only if {@link
359
   * RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource)} is set.
360
   *
361
   * <p>The default is <code>Clock.systemUTC()</code>.
362
   */
363
  @Builder.Default @NonNull private final Clock clock = Clock.systemUTC();
364
365
  @Builder
366
  private RelyingParty(
367 1 1. <init> : negated conditional → KILLED
      @NonNull RelyingPartyIdentity identity,
368
      Set<String> origins,
369 1 1. <init> : negated conditional → KILLED
      @NonNull CredentialRepository credentialRepository,
370 1 1. <init> : negated conditional → KILLED
      @NonNull Optional<AppId> appId,
371 1 1. <init> : negated conditional → KILLED
      @NonNull Optional<AttestationConveyancePreference> attestationConveyancePreference,
372 1 1. <init> : negated conditional → KILLED
      @NonNull Optional<AttestationTrustSource> attestationTrustSource,
373
      List<PublicKeyCredentialParameters> preferredPubkeyParams,
374
      boolean allowOriginPort,
375
      boolean allowOriginSubdomain,
376
      boolean allowUntrustedAttestation,
377
      boolean validateSignatureCounter,
378
      Clock clock) {
379
    this.identity = identity;
380
    this.origins =
381 1 1. <init> : negated conditional → KILLED
        origins != null
382
            ? CollectionUtil.immutableSet(origins)
383
            : Collections.singleton("https://" + identity.getId());
384
385
    for (String origin : this.origins) {
386
      try {
387
        new URL(origin);
388
      } catch (MalformedURLException e) {
389
        log.warn(
390
            "Allowed origin is not a valid URL, it will match only by exact string equality: {}",
391
            origin);
392
      }
393
    }
394
395
    this.credentialRepository = credentialRepository;
396
    this.appId = appId;
397
    this.attestationConveyancePreference = attestationConveyancePreference;
398
    this.attestationTrustSource = attestationTrustSource;
399
    this.preferredPubkeyParams = filterAvailableAlgorithms(preferredPubkeyParams);
400
    this.allowOriginPort = allowOriginPort;
401
    this.allowOriginSubdomain = allowOriginSubdomain;
402
    this.allowUntrustedAttestation = allowUntrustedAttestation;
403
    this.validateSignatureCounter = validateSignatureCounter;
404
    this.clock = clock;
405
  }
406
407
  private static ByteArray generateChallenge() {
408
    byte[] bytes = new byte[32];
409 1 1. generateChallenge : removed call to java/security/SecureRandom::nextBytes → KILLED
    random.nextBytes(bytes);
410 1 1. generateChallenge : replaced return value with null for com/yubico/webauthn/RelyingParty::generateChallenge → KILLED
    return new ByteArray(bytes);
411
  }
412
413
  /**
414
   * Filter <code>pubKeyCredParams</code> to only contain algorithms with a {@link KeyFactory} and a
415
   * {@link Signature} available, and log a warning for every unsupported algorithm.
416
   *
417
   * @return a new {@link List} containing only the algorithms supported in the current JCA context.
418
   */
419
  static List<PublicKeyCredentialParameters> filterAvailableAlgorithms(
420
      List<PublicKeyCredentialParameters> pubKeyCredParams) {
421 1 1. filterAvailableAlgorithms : replaced return value with Collections.emptyList for com/yubico/webauthn/RelyingParty::filterAvailableAlgorithms → KILLED
    return Collections.unmodifiableList(
422
        pubKeyCredParams.stream()
423
            .filter(
424
                param -> {
425
                  try {
426
                    switch (param.getAlg()) {
427
                      case EdDSA:
428
                        KeyFactory.getInstance("EdDSA");
429
                        break;
430
431
                      case ES256:
432
                      case ES384:
433
                      case ES512:
434
                        KeyFactory.getInstance("EC");
435
                        break;
436
437
                      case RS256:
438
                      case RS384:
439
                      case RS512:
440
                      case RS1:
441
                        KeyFactory.getInstance("RSA");
442
                        break;
443
444
                      default:
445
                        log.warn(
446
                            "Unknown algorithm: {}. Please file a bug report.", param.getAlg());
447
                    }
448
                  } catch (NoSuchAlgorithmException e) {
449
                    log.warn(
450
                        "Unsupported algorithm in RelyingParty.preferredPubkeyParams: {}. No KeyFactory available; registrations with this key algorithm will fail. You may need to add a dependency and load a provider using java.security.Security.addProvider().",
451
                        param.getAlg());
452 1 1. lambda$filterAvailableAlgorithms$0 : replaced boolean return with true for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → KILLED
                    return false;
453
                  }
454
455
                  final String signatureAlgName;
456
                  try {
457
                    signatureAlgName = WebAuthnCodecs.getJavaAlgorithmName(param.getAlg());
458
                  } catch (IllegalArgumentException e) {
459
                    log.warn("Unknown algorithm: {}. Please file a bug report.", param.getAlg());
460 1 1. lambda$filterAvailableAlgorithms$0 : replaced boolean return with true for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → NO_COVERAGE
                    return false;
461
                  }
462
463
                  try {
464
                    Signature.getInstance(signatureAlgName);
465
                  } catch (NoSuchAlgorithmException e) {
466
                    log.warn(
467
                        "Unsupported algorithm in RelyingParty.preferredPubkeyParams: {}. No Signature available; registrations with this key algorithm will fail. You may need to add a dependency and load a provider using java.security.Security.addProvider().",
468
                        param.getAlg());
469 1 1. lambda$filterAvailableAlgorithms$0 : replaced boolean return with true for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → NO_COVERAGE
                    return false;
470
                  }
471
472 1 1. lambda$filterAvailableAlgorithms$0 : replaced boolean return with false for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → KILLED
                  return true;
473
                })
474
            .collect(Collectors.toList()));
475
  }
476
477
  public PublicKeyCredentialCreationOptions startRegistration(
478
      StartRegistrationOptions startRegistrationOptions) {
479
    PublicKeyCredentialCreationOptionsBuilder builder =
480
        PublicKeyCredentialCreationOptions.builder()
481
            .rp(identity)
482
            .user(startRegistrationOptions.getUser())
483
            .challenge(generateChallenge())
484
            .pubKeyCredParams(preferredPubkeyParams)
485
            .excludeCredentials(
486
                credentialRepository.getCredentialIdsForUsername(
487
                    startRegistrationOptions.getUser().getName()))
488
            .authenticatorSelection(startRegistrationOptions.getAuthenticatorSelection())
489
            .extensions(
490
                startRegistrationOptions
491
                    .getExtensions()
492
                    .merge(
493
                        RegistrationExtensionInputs.builder()
494
                            .appidExclude(appId)
495
                            .credProps()
496
                            .build()))
497
            .timeout(startRegistrationOptions.getTimeout())
498
            .hints(startRegistrationOptions.getHints());
499 1 1. startRegistration : removed call to java/util/Optional::ifPresent → KILLED
    attestationConveyancePreference.ifPresent(builder::attestation);
500 1 1. startRegistration : replaced return value with null for com/yubico/webauthn/RelyingParty::startRegistration → KILLED
    return builder.build();
501
  }
502
503
  public RegistrationResult finishRegistration(FinishRegistrationOptions finishRegistrationOptions)
504
      throws RegistrationFailedException {
505
    try {
506 1 1. finishRegistration : replaced return value with null for com/yubico/webauthn/RelyingParty::finishRegistration → KILLED
      return _finishRegistration(finishRegistrationOptions).run();
507
    } catch (IllegalArgumentException e) {
508
      throw new RegistrationFailedException(e);
509
    }
510
  }
511
512
  /**
513
   * This method is NOT part of the public API.
514
   *
515
   * <p>This method is called internally by {@link #finishRegistration(FinishRegistrationOptions)}.
516
   * It is a separate method to facilitate testing; users should call {@link
517
   * #finishRegistration(FinishRegistrationOptions)} instead of this method.
518
   */
519
  FinishRegistrationSteps _finishRegistration(FinishRegistrationOptions options) {
520 1 1. _finishRegistration : replaced return value with null for com/yubico/webauthn/RelyingParty::_finishRegistration → KILLED
    return FinishRegistrationSteps.fromV1(this, options);
521
  }
522
523
  public AssertionRequest startAssertion(StartAssertionOptions startAssertionOptions) {
524
    PublicKeyCredentialRequestOptionsBuilder pkcro =
525
        PublicKeyCredentialRequestOptions.builder()
526
            .challenge(generateChallenge())
527
            .rpId(identity.getId())
528
            .allowCredentials(
529
                OptionalUtil.orElseOptional(
530
                        startAssertionOptions.getUsername(),
531
                        () ->
532 1 1. lambda$startAssertion$1 : replaced return value with Optional.empty for com/yubico/webauthn/RelyingParty::lambda$startAssertion$1 → KILLED
                            startAssertionOptions
533
                                .getUserHandle()
534
                                .flatMap(credentialRepository::getUsernameForUserHandle))
535
                    .map(
536
                        un ->
537 1 1. lambda$startAssertion$2 : replaced return value with Collections.emptyList for com/yubico/webauthn/RelyingParty::lambda$startAssertion$2 → KILLED
                            new ArrayList<>(credentialRepository.getCredentialIdsForUsername(un))))
538
            .extensions(
539
                startAssertionOptions
540
                    .getExtensions()
541
                    .merge(startAssertionOptions.getExtensions().toBuilder().appid(appId).build()))
542
            .timeout(startAssertionOptions.getTimeout())
543
            .hints(startAssertionOptions.getHints());
544
545 1 1. startAssertion : removed call to java/util/Optional::ifPresent → KILLED
    startAssertionOptions.getUserVerification().ifPresent(pkcro::userVerification);
546
547 1 1. startAssertion : replaced return value with null for com/yubico/webauthn/RelyingParty::startAssertion → KILLED
    return AssertionRequest.builder()
548
        .publicKeyCredentialRequestOptions(pkcro.build())
549
        .username(startAssertionOptions.getUsername())
550
        .userHandle(startAssertionOptions.getUserHandle())
551
        .build();
552
  }
553
554
  /**
555
   * @throws InvalidSignatureCountException if {@link
556
   *     RelyingPartyBuilder#validateSignatureCounter(boolean) validateSignatureCounter} is <code>
557
   *     true</code>, the {@link AuthenticatorData#getSignatureCounter() signature count} in the
558
   *     response is less than or equal to the {@link RegisteredCredential#getSignatureCount()
559
   *     stored signature count}, and at least one of the signature count values is nonzero.
560
   * @throws AssertionFailedException if validation fails for any other reason.
561
   */
562
  public AssertionResult finishAssertion(FinishAssertionOptions finishAssertionOptions)
563
      throws AssertionFailedException {
564
    try {
565 1 1. finishAssertion : replaced return value with null for com/yubico/webauthn/RelyingParty::finishAssertion → KILLED
      return _finishAssertion(finishAssertionOptions).run();
566
    } catch (IllegalArgumentException e) {
567
      throw new AssertionFailedException(e);
568
    }
569
  }
570
571
  /**
572
   * This method is NOT part of the public API.
573
   *
574
   * <p>This method is called internally by {@link #finishAssertion(FinishAssertionOptions)}. It is
575
   * a separate method to facilitate testing; users should call {@link
576
   * #finishAssertion(FinishAssertionOptions)} instead of this method.
577
   */
578
  FinishAssertionSteps<RegisteredCredential> _finishAssertion(FinishAssertionOptions options) {
579 1 1. _finishAssertion : replaced return value with null for com/yubico/webauthn/RelyingParty::_finishAssertion → KILLED
    return FinishAssertionSteps.fromV1(this, options);
580
  }
581
582
  public static RelyingPartyBuilder.MandatoryStages builder() {
583 1 1. builder : replaced return value with null for com/yubico/webauthn/RelyingParty::builder → KILLED
    return new RelyingPartyBuilder.MandatoryStages();
584
  }
585
586
  public static class RelyingPartyBuilder {
587
    private @NonNull Optional<AppId> appId = Optional.empty();
588
    private @NonNull Optional<AttestationConveyancePreference> attestationConveyancePreference =
589
        Optional.empty();
590
    private @NonNull Optional<AttestationTrustSource> attestationTrustSource = Optional.empty();
591
592
    /**
593
     * The allowed origins that returned authenticator responses will be compared against.
594
     *
595
     * <p>The default is the set containing only the string <code>
596
     * "https://" + {@link #getIdentity()}.getId()</code>.
597
     *
598
     * <p>If {@link RelyingPartyBuilder#allowOriginPort(boolean) allowOriginPort} and {@link
599
     * RelyingPartyBuilder#allowOriginSubdomain(boolean) allowOriginSubdomain} are both <code>false
600
     * </code> (the default), then a successful registration or authentication operation requires
601
     * {@link CollectedClientData#getOrigin()} to exactly equal one of these values.
602
     *
603
     * <p>If {@link RelyingPartyBuilder#allowOriginPort(boolean) allowOriginPort} is <code>true
604
     * </code> , then the above rule is relaxed to allow any port number in {@link
605
     * CollectedClientData#getOrigin()}, regardless of any port specified.
606
     *
607
     * <p>If {@link RelyingPartyBuilder#allowOriginSubdomain(boolean) allowOriginSubdomain} is
608
     * <code>true</code>, then the above rule is relaxed to allow any subdomain, of any depth, of
609
     * any of these values.
610
     *
611
     * <p>For either of the above relaxations to take effect, both the allowed origin and the client
612
     * data origin must be valid URLs. Origins that are not valid URLs are matched only by exact
613
     * string equality.
614
     *
615
     * @since 0.6.0
616
     * @see #getIdentity()
617
     * @see #origins(Optional)
618
     */
619 1 1. origins : negated conditional → KILLED
    public RelyingPartyBuilder origins(@NonNull Set<String> origins) {
620
      this.origins = origins;
621 1 1. origins : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::origins → KILLED
      return this;
622
    }
623
624
    /**
625
     * The allowed origins that returned authenticator responses will be compared against.
626
     *
627
     * <p>If set to empty, this setting reverts to the default value.
628
     *
629
     * <p>The default is the set containing only the string <code>
630
     * "https://" + {@link #getIdentity()}.getId()</code>.
631
     *
632
     * <p>If {@link RelyingPartyBuilder#allowOriginPort(boolean) allowOriginPort} and {@link
633
     * RelyingPartyBuilder#allowOriginSubdomain(boolean) allowOriginSubdomain} are both <code>false
634
     * </code> (the default), then a successful registration or authentication operation requires
635
     * {@link CollectedClientData#getOrigin()} to exactly equal one of these values.
636
     *
637
     * <p>If {@link RelyingPartyBuilder#allowOriginPort(boolean) allowOriginPort} is <code>true
638
     * </code> , then the above rule is relaxed to allow any port number in {@link
639
     * CollectedClientData#getOrigin()}, regardless of any port specified.
640
     *
641
     * <p>If {@link RelyingPartyBuilder#allowOriginSubdomain(boolean) allowOriginSubdomain} is
642
     * <code>true</code>, then the above rule is relaxed to allow any subdomain, of any depth, of
643
     * any of these values.
644
     *
645
     * <p>For either of the above relaxations to take effect, both the allowed origin and the client
646
     * data origin must be valid URLs. Origins that are not valid URLs are matched only by exact
647
     * string equality.
648
     *
649
     * @since 2.7.0
650
     * @see #getIdentity()
651
     * @see #origins(Set)
652
     */
653 1 1. origins : negated conditional → KILLED
    public RelyingPartyBuilder origins(@NonNull Optional<Set<String>> origins) {
654
      this.origins = origins.orElse(null);
655 1 1. origins : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::origins → KILLED
      return this;
656
    }
657
658
    public static class MandatoryStages {
659
      private final RelyingPartyBuilder builder = new RelyingPartyBuilder();
660
661
      /**
662
       * {@link RelyingPartyBuilder#identity(RelyingPartyIdentity) identity} is a required
663
       * parameter.
664
       *
665
       * @see RelyingPartyBuilder#identity(RelyingPartyIdentity)
666
       */
667
      public Step2 identity(RelyingPartyIdentity identity) {
668
        builder.identity(identity);
669 1 1. identity : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder$MandatoryStages::identity → KILLED
        return new Step2();
670
      }
671
672
      public class Step2 {
673
        /**
674
         * {@link RelyingPartyBuilder#credentialRepository(CredentialRepository)
675
         * credentialRepository} is a required parameter.
676
         *
677
         * @see RelyingPartyBuilder#credentialRepository(CredentialRepository)
678
         * @see #credentialRepositoryV2(CredentialRepositoryV2)
679
         */
680
        public RelyingPartyBuilder credentialRepository(CredentialRepository credentialRepository) {
681 1 1. credentialRepository : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder$MandatoryStages$Step2::credentialRepository → KILLED
          return builder.credentialRepository(credentialRepository);
682
        }
683
684
        /**
685
         * {@link RelyingPartyBuilder#credentialRepository(CredentialRepository)
686
         * credentialRepository} is a required parameter. This setter differs from {@link
687
         * #credentialRepository(CredentialRepository)} in that it takes an instance of {@link
688
         * CredentialRepositoryV2} and converts the builder's return type to {@link RelyingPartyV2}.
689
         * {@link CredentialRepositoryV2} does not require the application to support usernames,
690
         * unless {@link RelyingPartyV2.RelyingPartyV2Builder#usernameRepository(UsernameRepository)
691
         * usernameRepository} is also set in a subsequent builder step.
692
         *
693
         * @see #credentialRepository(CredentialRepository)
694
         * @deprecated EXPERIMENTAL: This is an experimental feature. It is likely to change or be
695
         *     deleted before reaching a mature release.
696
         */
697
        @Deprecated
698
        public <C extends CredentialRecord>
699
            RelyingPartyV2.RelyingPartyV2Builder<C> credentialRepositoryV2(
700
                CredentialRepositoryV2<C> credentialRepository) {
701 1 1. credentialRepositoryV2 : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder$MandatoryStages$Step2::credentialRepositoryV2 → KILLED
          return RelyingPartyV2.builder(builder.identity, credentialRepository);
702
        }
703
      }
704
    }
705
706
    /**
707
     * The extension input to set for the <code>appid</code> and <code>appidExclude</code>
708
     * extensions.
709
     *
710
     * <p>You do not need this extension if you have not previously supported U2F. Its purpose is to
711
     * make already-registered U2F credentials forward-compatible with the WebAuthn API. It is not
712
     * needed for new registrations, even of U2F authenticators.
713
     *
714
     * <p>If this member is set, {@link #startAssertion(StartAssertionOptions) startAssertion} will
715
     * automatically set the <code>appid</code> extension input, and {@link
716
     * #finishAssertion(FinishAssertionOptions) finishAssertion} will adjust its verification logic
717
     * to also accept this AppID as an alternative to the RP ID. Likewise, {@link
718
     * #startRegistration(StartRegistrationOptions)} startRegistration} will automatically set the
719
     * <code>appidExclude</code> extension input.
720
     *
721
     * <p>By default, this is not set.
722
     *
723
     * @see AssertionExtensionInputs#getAppid()
724
     * @see RegistrationExtensionInputs#getAppidExclude()
725
     * @see <a
726
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
727
     *     FIDO AppID Extension (appid)</a>
728
     * @see <a
729
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-exclude-extension">§10.2.
730
     *     FIDO AppID Exclusion Extension (appidExclude)</a>
731
     */
732 1 1. appId : negated conditional → KILLED
    public RelyingPartyBuilder appId(@NonNull Optional<AppId> appId) {
733
      this.appId = appId;
734 1 1. appId : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::appId → KILLED
      return this;
735
    }
736
737
    /**
738
     * The extension input to set for the <code>appid</code> and <code>appidExclude</code>
739
     * extensions.
740
     *
741
     * <p>You do not need this extension if you have not previously supported U2F. Its purpose is to
742
     * make already-registered U2F credentials forward-compatible with the WebAuthn API. It is not
743
     * needed for new registrations, even of U2F authenticators.
744
     *
745
     * <p>If this member is set, {@link #startAssertion(StartAssertionOptions) startAssertion} will
746
     * automatically set the <code>appid</code> extension input, and {@link
747
     * #finishAssertion(FinishAssertionOptions) finishAssertion} will adjust its verification logic
748
     * to also accept this AppID as an alternative to the RP ID. Likewise, {@link
749
     * #startRegistration(StartRegistrationOptions)} startRegistration} will automatically set the
750
     * <code>appidExclude</code> extension input.
751
     *
752
     * <p>By default, this is not set.
753
     *
754
     * @see AssertionExtensionInputs#getAppid()
755
     * @see RegistrationExtensionInputs#getAppidExclude()
756
     * @see <a
757
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
758
     *     FIDO AppID Extension (appid)</a>
759
     * @see <a
760
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-exclude-extension">§10.2.
761
     *     FIDO AppID Exclusion Extension (appidExclude)</a>
762
     */
763 1 1. appId : negated conditional → KILLED
    public RelyingPartyBuilder appId(@NonNull AppId appId) {
764 1 1. appId : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::appId → KILLED
      return this.appId(Optional.of(appId));
765
    }
766
767
    /**
768
     * The argument for the {@link PublicKeyCredentialCreationOptions#getAttestation() attestation}
769
     * parameter in registration operations.
770
     *
771
     * <p>Unless your application has a concrete policy for authenticator attestation, it is
772
     * recommended to leave this parameter undefined.
773
     *
774
     * <p>If you set this, you may want to explicitly set {@link
775
     * RelyingPartyBuilder#allowUntrustedAttestation(boolean) allowUntrustedAttestation} and {@link
776
     * RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource) attestationTrustSource}
777
     * too.
778
     *
779
     * <p>By default, this is not set.
780
     *
781
     * @see PublicKeyCredentialCreationOptions#getAttestation()
782
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
783
     *     Attestation</a>
784
     */
785
    public RelyingPartyBuilder attestationConveyancePreference(
786 1 1. attestationConveyancePreference : negated conditional → KILLED
        @NonNull Optional<AttestationConveyancePreference> attestationConveyancePreference) {
787
      this.attestationConveyancePreference = attestationConveyancePreference;
788 1 1. attestationConveyancePreference : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationConveyancePreference → KILLED
      return this;
789
    }
790
791
    /**
792
     * The argument for the {@link PublicKeyCredentialCreationOptions#getAttestation() attestation}
793
     * parameter in registration operations.
794
     *
795
     * <p>Unless your application has a concrete policy for authenticator attestation, it is
796
     * recommended to leave this parameter undefined.
797
     *
798
     * <p>If you set this, you may want to explicitly set {@link
799
     * RelyingPartyBuilder#allowUntrustedAttestation(boolean) allowUntrustedAttestation} and {@link
800
     * RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource) attestationTrustSource}
801
     * too.
802
     *
803
     * <p>By default, this is not set.
804
     *
805
     * @see PublicKeyCredentialCreationOptions#getAttestation()
806
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
807
     *     Attestation</a>
808
     */
809
    public RelyingPartyBuilder attestationConveyancePreference(
810 1 1. attestationConveyancePreference : negated conditional → KILLED
        @NonNull AttestationConveyancePreference attestationConveyancePreference) {
811 1 1. attestationConveyancePreference : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationConveyancePreference → KILLED
      return this.attestationConveyancePreference(Optional.of(attestationConveyancePreference));
812
    }
813
814
    /**
815
     * An {@link AttestationTrustSource} instance to use for looking up trust roots for
816
     * authenticator attestation. This matters only if {@link #getAttestationConveyancePreference()}
817
     * is non-empty and not set to {@link AttestationConveyancePreference#NONE}.
818
     *
819
     * <p>By default, this is not set.
820
     *
821
     * @see PublicKeyCredentialCreationOptions#getAttestation()
822
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
823
     *     Attestation</a>
824
     */
825
    public RelyingPartyBuilder attestationTrustSource(
826 1 1. attestationTrustSource : negated conditional → KILLED
        @NonNull Optional<AttestationTrustSource> attestationTrustSource) {
827
      this.attestationTrustSource = attestationTrustSource;
828 1 1. attestationTrustSource : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationTrustSource → KILLED
      return this;
829
    }
830
831
    /**
832
     * An {@link AttestationTrustSource} instance to use for looking up trust roots for
833
     * authenticator attestation. This matters only if {@link #getAttestationConveyancePreference()}
834
     * is non-empty and not set to {@link AttestationConveyancePreference#NONE}.
835
     *
836
     * <p>By default, this is not set.
837
     *
838
     * @see PublicKeyCredentialCreationOptions#getAttestation()
839
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation">§6.4.
840
     *     Attestation</a>
841
     */
842
    public RelyingPartyBuilder attestationTrustSource(
843 1 1. attestationTrustSource : negated conditional → KILLED
        @NonNull AttestationTrustSource attestationTrustSource) {
844 1 1. attestationTrustSource : replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationTrustSource → KILLED
      return this.attestationTrustSource(Optional.of(attestationTrustSource));
845
    }
846
  }
847
}

Mutations

367

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

369

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

370

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

371

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

372

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

381

1.1
Location : <init>
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

409

1.1
Location : generateChallenge
Killed by : com.yubico.webauthn.RelyingPartyTest.filtersAlgorithmsToThoseAvailable(com.yubico.webauthn.RelyingPartyTest)
removed call to java/security/SecureRandom::nextBytes → KILLED

410

1.1
Location : generateChallenge
Killed by : com.yubico.webauthn.RelyingPartyTest.defaultSettingsDontFilterEs256OrRs256(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty::generateChallenge → KILLED

421

1.1
Location : filterAvailableAlgorithms
Killed by : com.yubico.webauthn.RelyingPartyTest.logsWarningIfAlgorithmNotAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with Collections.emptyList for com/yubico/webauthn/RelyingParty::filterAvailableAlgorithms → KILLED

452

1.1
Location : lambda$filterAvailableAlgorithms$0
Killed by : com.yubico.webauthn.RelyingPartyTest.logsWarningIfAlgorithmNotAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced boolean return with true for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → KILLED

460

1.1
Location : lambda$filterAvailableAlgorithms$0
Killed by : none
replaced boolean return with true for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → NO_COVERAGE

469

1.1
Location : lambda$filterAvailableAlgorithms$0
Killed by : none
replaced boolean return with true for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → NO_COVERAGE

472

1.1
Location : lambda$filterAvailableAlgorithms$0
Killed by : com.yubico.webauthn.RelyingPartyTest.defaultSettingsLogWarningIfSomeAlgorithmNotAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced boolean return with false for com/yubico/webauthn/RelyingParty::lambda$filterAvailableAlgorithms$0 → KILLED

499

1.1
Location : startRegistration
Killed by : com.yubico.webauthn.RelyingPartyTest.filtersAlgorithmsToThoseAvailable(com.yubico.webauthn.RelyingPartyTest)
removed call to java/util/Optional::ifPresent → KILLED

500

1.1
Location : startRegistration
Killed by : com.yubico.webauthn.RelyingPartyTest.defaultSettingsDontFilterEs256OrRs256(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty::startRegistration → KILLED

506

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

520

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

532

1.1
Location : lambda$startAssertion$1
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with Optional.empty for com/yubico/webauthn/RelyingParty::lambda$startAssertion$1 → KILLED

537

1.1
Location : lambda$startAssertion$2
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with Collections.emptyList for com/yubico/webauthn/RelyingParty::lambda$startAssertion$2 → KILLED

545

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

547

1.1
Location : startAssertion
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty::startAssertion → KILLED

565

1.1
Location : finishAssertion
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty::finishAssertion → KILLED

579

1.1
Location : _finishAssertion
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty::_finishAssertion → KILLED

583

1.1
Location : builder
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty::builder → KILLED

619

1.1
Location : origins
Killed by : com.yubico.webauthn.RelyingPartyTest.testOriginsWithEmptySet(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

621

1.1
Location : origins
Killed by : com.yubico.webauthn.RelyingPartyTest.testOriginsWithEmptySet(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::origins → KILLED

653

1.1
Location : origins
Killed by : com.yubico.webauthn.RelyingPartyTest.testOriginsWithOptionalSet(com.yubico.webauthn.RelyingPartyTest)
negated conditional → KILLED

655

1.1
Location : origins
Killed by : com.yubico.webauthn.RelyingPartyTest.testOriginsWithOptionalSet(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::origins → KILLED

669

1.1
Location : identity
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder$MandatoryStages::identity → KILLED

681

1.1
Location : credentialRepository
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder$MandatoryStages$Step2::credentialRepository → KILLED

701

1.1
Location : credentialRepositoryV2
Killed by : com.yubico.webauthn.RelyingPartyTest.testOriginsWithOptionalSet(com.yubico.webauthn.RelyingPartyTest)
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder$MandatoryStages$Step2::credentialRepositoryV2 → KILLED

732

1.1
Location : appId
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

734

1.1
Location : appId
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::appId → KILLED

763

1.1
Location : appId
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

764

1.1
Location : appId
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::appId → KILLED

786

1.1
Location : attestationConveyancePreference
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

788

1.1
Location : attestationConveyancePreference
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationConveyancePreference → KILLED

810

1.1
Location : attestationConveyancePreference
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

811

1.1
Location : attestationConveyancePreference
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationConveyancePreference → KILLED

826

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

828

1.1
Location : attestationTrustSource
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationTrustSource → KILLED

843

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

844

1.1
Location : attestationTrustSource
Killed by : com.yubico.webauthn.RelyingPartyRegistrationSpec
replaced return value with null for com/yubico/webauthn/RelyingParty$RelyingPartyBuilder::attestationTrustSource → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0