AssertionExtensionInputs.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.data;
26
27
import com.fasterxml.jackson.annotation.JsonCreator;
28
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
29
import com.fasterxml.jackson.annotation.JsonProperty;
30
import com.yubico.webauthn.RelyingParty;
31
import com.yubico.webauthn.StartAssertionOptions;
32
import com.yubico.webauthn.extension.appid.AppId;
33
import java.util.HashSet;
34
import java.util.Optional;
35
import java.util.Set;
36
import lombok.Builder;
37
import lombok.NonNull;
38
import lombok.Value;
39
40
/**
41
 * Contains <a
42
 * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-extension-input">client
43
 * extension inputs</a> to a <code>navigator.credentials.get()</code> operation. All members are
44
 * optional.
45
 *
46
 * <p>The authenticator extension inputs are derived from these client extension inputs.
47
 *
48
 * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-extensions">§9. WebAuthn
49
 *     Extensions</a>
50
 */
51
@Value
52
@Builder(toBuilder = true)
53
@JsonIgnoreProperties(ignoreUnknown = true)
54
public class AssertionExtensionInputs implements ExtensionInputs {
55
56
  private final AppId appid;
57
  private final Extensions.LargeBlob.LargeBlobAuthenticationInput largeBlob;
58
  private final Boolean uvm;
59
60
  @JsonCreator
61
  private AssertionExtensionInputs(
62
      @JsonProperty("appid") AppId appid,
63
      @JsonProperty("largeBlob") Extensions.LargeBlob.LargeBlobAuthenticationInput largeBlob,
64
      @JsonProperty("uvm") Boolean uvm) {
65
    this.appid = appid;
66
    this.largeBlob = largeBlob;
67 2 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
    this.uvm = (uvm != null && uvm) ? true : null;
68
  }
69
70
  /**
71
   * Merge <code>other</code> into <code>this</code>. Non-null field values from <code>this</code>
72
   * take precedence.
73
   *
74
   * @return a new {@link AssertionExtensionInputs} instance with the settings from both <code>this
75
   *     </code> and <code>other</code>.
76
   */
77
  public AssertionExtensionInputs merge(AssertionExtensionInputs other) {
78 1 1. merge : replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs::merge → KILLED
    return new AssertionExtensionInputs(
79 1 1. merge : negated conditional → KILLED
        this.appid != null ? this.appid : other.appid,
80 1 1. merge : negated conditional → SURVIVED
        this.largeBlob != null ? this.largeBlob : other.largeBlob,
81 1 1. merge : negated conditional → SURVIVED
        this.uvm != null ? this.uvm : other.uvm);
82
  }
83
84
  /**
85
   * @return The extension identifiers of all extensions configured.
86
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-extension-id">§9.1.
87
   *     Extension Identifiers</a>
88
   */
89
  @Override
90
  public Set<String> getExtensionIds() {
91
    Set<String> ids = new HashSet<>();
92 1 1. getExtensionIds : negated conditional → KILLED
    if (appid != null) {
93
      ids.add(Extensions.Appid.EXTENSION_ID);
94
    }
95 1 1. getExtensionIds : negated conditional → KILLED
    if (largeBlob != null) {
96
      ids.add(Extensions.LargeBlob.EXTENSION_ID);
97
    }
98 1 1. getExtensionIds : negated conditional → KILLED
    if (getUvm()) {
99
      ids.add(Extensions.Uvm.EXTENSION_ID);
100
    }
101 1 1. getExtensionIds : replaced return value with Collections.emptySet for com/yubico/webauthn/data/AssertionExtensionInputs::getExtensionIds → KILLED
    return ids;
102
  }
103
104
  public static class AssertionExtensionInputsBuilder {
105
    /**
106
     * The input to the FIDO AppID Extension (<code>appid</code>).
107
     *
108
     * <p>You usually do not need to call this method explicitly; if {@link RelyingParty#getAppId()}
109
     * is present, then {@link RelyingParty#startAssertion(StartAssertionOptions)} will enable this
110
     * extension automatically.
111
     *
112
     * <p>This extension allows WebAuthn Relying Parties that have previously registered a
113
     * credential using the legacy FIDO JavaScript APIs to request an assertion. The FIDO APIs use
114
     * an alternative identifier for Relying Parties called an <a
115
     * href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html">AppID</a>,
116
     * and any credentials created using those APIs will be scoped to that identifier. Without this
117
     * extension, they would need to be re-registered in order to be scoped to an RP ID.
118
     *
119
     * <p>This extension does not allow FIDO-compatible credentials to be created. Thus, credentials
120
     * created with WebAuthn are not backwards compatible with the FIDO JavaScript APIs.
121
     *
122
     * @see <a
123
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
124
     *     FIDO AppID Extension (appid)</a>
125
     */
126 1 1. appid : negated conditional → KILLED
    public AssertionExtensionInputsBuilder appid(@NonNull Optional<AppId> appid) {
127 1 1. appid : replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::appid → KILLED
      return this.appid(appid.orElse(null));
128
    }
129
130
    /**
131
     * The input to the FIDO AppID Extension (<code>appid</code>).
132
     *
133
     * <p>You usually do not need to call this method explicitly; if {@link RelyingParty#getAppId()}
134
     * is present, then {@link RelyingParty#startAssertion(StartAssertionOptions)} will enable this
135
     * extension automatically.
136
     *
137
     * <p>This extension allows WebAuthn Relying Parties that have previously registered a
138
     * credential using the legacy FIDO JavaScript APIs to request an assertion. The FIDO APIs use
139
     * an alternative identifier for Relying Parties called an <a
140
     * href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html">AppID</a>,
141
     * and any credentials created using those APIs will be scoped to that identifier. Without this
142
     * extension, they would need to be re-registered in order to be scoped to an RP ID.
143
     *
144
     * <p>This extension does not allow FIDO-compatible credentials to be created. Thus, credentials
145
     * created with WebAuthn are not backwards compatible with the FIDO JavaScript APIs.
146
     *
147
     * @see <a
148
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
149
     *     FIDO AppID Extension (appid)</a>
150
     */
151
    public AssertionExtensionInputsBuilder appid(AppId appid) {
152
      this.appid = appid;
153 1 1. appid : replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::appid → KILLED
      return this;
154
    }
155
156
    /**
157
     * Enable the Large blob storage extension (<code>largeBlob</code>).
158
     *
159
     * <p>Suitable arguments can be obtained using {@link
160
     * Extensions.LargeBlob.LargeBlobAuthenticationInput#read()} or {@link
161
     * Extensions.LargeBlob.LargeBlobAuthenticationInput#write(ByteArray)}.
162
     *
163
     * @see Extensions.LargeBlob.LargeBlobAuthenticationInput#read()
164
     * @see Extensions.LargeBlob.LargeBlobAuthenticationInput#write(ByteArray)
165
     * @see <a
166
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
167
     *     Large blob storage extension (largeBlob)</a>
168
     */
169
    public AssertionExtensionInputsBuilder largeBlob(
170
        Extensions.LargeBlob.LargeBlobAuthenticationInput largeBlob) {
171
      this.largeBlob = largeBlob;
172 1 1. largeBlob : replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::largeBlob → KILLED
      return this;
173
    }
174
175
    /**
176
     * Enable the User Verification Method Extension (<code>uvm</code>).
177
     *
178
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3.
179
     *     User Verification Method Extension (uvm)</a>
180
     */
181
    public AssertionExtensionInputsBuilder uvm() {
182
      this.uvm = true;
183 1 1. uvm : replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::uvm → KILLED
      return this;
184
    }
185
186
    /** For compatibility with {@link Builder}(toBuilder = true) */
187
    private AssertionExtensionInputsBuilder uvm(Boolean uvm) {
188
      this.uvm = uvm;
189 1 1. uvm : replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::uvm → KILLED
      return this;
190
    }
191
  }
192
193
  /**
194
   * The input to the FIDO AppID Extension (<code>appid</code>).
195
   *
196
   * <p>This extension allows WebAuthn Relying Parties that have previously registered a credential
197
   * using the legacy FIDO JavaScript APIs to request an assertion. The FIDO APIs use an alternative
198
   * identifier for Relying Parties called an <a
199
   * href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html">AppID</a>,
200
   * and any credentials created using those APIs will be scoped to that identifier. Without this
201
   * extension, they would need to be re-registered in order to be scoped to an RP ID.
202
   *
203
   * <p>This extension does not allow FIDO-compatible credentials to be created. Thus, credentials
204
   * created with WebAuthn are not backwards compatible with the FIDO JavaScript APIs.
205
   *
206
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1.
207
   *     FIDO AppID Extension (appid)</a>
208
   */
209
  public Optional<AppId> getAppid() {
210 1 1. getAppid : replaced return value with Optional.empty for com/yubico/webauthn/data/AssertionExtensionInputs::getAppid → KILLED
    return Optional.ofNullable(appid);
211
  }
212
213
  /**
214
   * The input to the Large blob storage extension (<code>largeBlob</code>).
215
   *
216
   * <p>This extension allows a Relying Party to store opaque data associated with a credential.
217
   *
218
   * @see Extensions.LargeBlob.LargeBlobAuthenticationInput#read()
219
   * @see Extensions.LargeBlob.LargeBlobAuthenticationInput#write(ByteArray)
220
   * @see <a
221
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5.
222
   *     Large blob storage extension (largeBlob)</a>
223
   */
224
  public Optional<Extensions.LargeBlob.LargeBlobAuthenticationInput> getLargeBlob() {
225 1 1. getLargeBlob : replaced return value with Optional.empty for com/yubico/webauthn/data/AssertionExtensionInputs::getLargeBlob → KILLED
    return Optional.ofNullable(largeBlob);
226
  }
227
228
  /** For JSON serialization, to omit false and null values. */
229
  @JsonProperty("largeBlob")
230
  private Extensions.LargeBlob.LargeBlobAuthenticationInput getLargeBlobJson() {
231 3 1. getLargeBlobJson : negated conditional → KILLED
2. getLargeBlobJson : negated conditional → KILLED
3. getLargeBlobJson : negated conditional → KILLED
    return largeBlob != null && (largeBlob.getRead() || largeBlob.getWrite().isPresent())
232
        ? largeBlob
233
        : null;
234
  }
235
236
  /**
237
   * @return <code>true</code> if the User Verification Method Extension (<code>uvm</code>) is
238
   *     enabled, <code>false</code> otherwise.
239
   * @see AssertionExtensionInputsBuilder#uvm()
240
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3.
241
   *     User Verification Method Extension (uvm)</a>
242
   */
243
  public boolean getUvm() {
244 3 1. getUvm : replaced boolean return with true for com/yubico/webauthn/data/AssertionExtensionInputs::getUvm → KILLED
2. getUvm : negated conditional → KILLED
3. getUvm : negated conditional → KILLED
    return uvm != null && uvm;
245
  }
246
247
  /** For JSON serialization, to omit false values. */
248
  @JsonProperty("uvm")
249
  private Boolean getUvmJson() {
250 3 1. getUvmJson : replaced Boolean return with True for com/yubico/webauthn/data/AssertionExtensionInputs::getUvmJson → KILLED
2. getUvmJson : replaced Boolean return with False for com/yubico/webauthn/data/AssertionExtensionInputs::getUvmJson → KILLED
3. getUvmJson : negated conditional → KILLED
    return getUvm() ? true : null;
251
  }
252
}

Mutations

67

1.1
Location : <init>
Killed by : com.yubico.webauthn.data.AssertionExtensionInputsTest.itHasTheseBuilderMethods(com.yubico.webauthn.data.AssertionExtensionInputsTest)
negated conditional → KILLED

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

78

1.1
Location : merge
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs::merge → KILLED

79

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

80

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

81

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

92

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

95

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

98

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

101

1.1
Location : getExtensionIds
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with Collections.emptySet for com/yubico/webauthn/data/AssertionExtensionInputs::getExtensionIds → KILLED

126

1.1
Location : appid
Killed by : com.yubico.webauthn.data.AssertionExtensionInputsTest.itHasTheseBuilderMethods(com.yubico.webauthn.data.AssertionExtensionInputsTest)
negated conditional → KILLED

127

1.1
Location : appid
Killed by : com.yubico.webauthn.data.AssertionExtensionInputsTest.itHasTheseBuilderMethods(com.yubico.webauthn.data.AssertionExtensionInputsTest)
replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::appid → KILLED

153

1.1
Location : appid
Killed by : com.yubico.webauthn.data.AssertionExtensionInputsTest.itHasTheseBuilderMethods(com.yubico.webauthn.data.AssertionExtensionInputsTest)
replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::appid → KILLED

172

1.1
Location : largeBlob
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::largeBlob → KILLED

183

1.1
Location : uvm
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::uvm → KILLED

189

1.1
Location : uvm
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/data/AssertionExtensionInputs$AssertionExtensionInputsBuilder::uvm → KILLED

210

1.1
Location : getAppid
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/AssertionExtensionInputs::getAppid → KILLED

225

1.1
Location : getLargeBlob
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/AssertionExtensionInputs::getLargeBlob → KILLED

231

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

2.2
Location : getLargeBlobJson
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

3.3
Location : getLargeBlobJson
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

244

1.1
Location : getUvm
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced boolean return with true for com/yubico/webauthn/data/AssertionExtensionInputs::getUvm → KILLED

2.2
Location : getUvm
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
negated conditional → KILLED

3.3
Location : getUvm
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

250

1.1
Location : getUvmJson
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced Boolean return with True for com/yubico/webauthn/data/AssertionExtensionInputs::getUvmJson → KILLED

2.2
Location : getUvmJson
Killed by : com.yubico.webauthn.data.ExtensionsSpec
replaced Boolean return with False for com/yubico/webauthn/data/AssertionExtensionInputs::getUvmJson → KILLED

3.3
Location : getUvmJson
Killed by : com.yubico.webauthn.data.ExtensionsSpec
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0