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.JsonProperty; | |
29 | import com.fasterxml.jackson.core.JsonProcessingException; | |
30 | import com.fasterxml.jackson.databind.ObjectMapper; | |
31 | import com.fasterxml.jackson.databind.node.ObjectNode; | |
32 | import com.yubico.internal.util.CollectionUtil; | |
33 | import com.yubico.internal.util.JacksonCodecs; | |
34 | import java.util.List; | |
35 | import java.util.Optional; | |
36 | import lombok.Builder; | |
37 | import lombok.NonNull; | |
38 | import lombok.Value; | |
39 | ||
40 | /** | |
41 | * The PublicKeyCredentialRequestOptions dictionary supplies get() with the data it needs to | |
42 | * generate an assertion. | |
43 | * | |
44 | * <p>Its `challenge` member must be present, while its other members are optional. | |
45 | * | |
46 | * @see <a | |
47 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-publickeycredentialrequestoptions">§5.5. | |
48 | * Options for Assertion Generation (dictionary PublicKeyCredentialRequestOptions) </a> | |
49 | */ | |
50 | @Value | |
51 | @Builder(toBuilder = true) | |
52 | public class PublicKeyCredentialRequestOptions { | |
53 | ||
54 | /** | |
55 | * A challenge that the selected authenticator signs, along with other data, when producing an | |
56 | * authentication assertion. See the <a | |
57 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-cryptographic-challenges">§13.1 | |
58 | * Cryptographic Challenges</a> security consideration. | |
59 | */ | |
60 | @NonNull private final ByteArray challenge; | |
61 | ||
62 | /** | |
63 | * Specifies a time, in milliseconds, that the caller is willing to wait for the call to complete. | |
64 | * | |
65 | * <p>This is treated as a hint, and MAY be overridden by the client. | |
66 | */ | |
67 | private final Long timeout; | |
68 | ||
69 | /** | |
70 | * Specifies the relying party identifier claimed by the caller. | |
71 | * | |
72 | * <p>If omitted, its value will be set by the client. | |
73 | */ | |
74 | private final String rpId; | |
75 | ||
76 | /** | |
77 | * A list of {@link PublicKeyCredentialDescriptor} objects representing public key credentials | |
78 | * acceptable to the caller, in descending order of the caller’s preference (the first item in the | |
79 | * list is the most preferred credential, and so on down the list). | |
80 | */ | |
81 | private final List<PublicKeyCredentialDescriptor> allowCredentials; | |
82 | ||
83 | /** | |
84 | * Describes the Relying Party's requirements regarding <a | |
85 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">user | |
86 | * verification</a> for the <code>navigator.credentials.get()</code> operation. | |
87 | * | |
88 | * <p>Eligible authenticators are filtered to only those capable of satisfying this requirement. | |
89 | * | |
90 | * <p>By default, this is not set. When not set, the default in the browser is {@link | |
91 | * UserVerificationRequirement#PREFERRED}. | |
92 | * | |
93 | * @see UserVerificationRequirement | |
94 | * @see <a | |
95 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#enum-userVerificationRequirement">§5.8.6. | |
96 | * User Verification Requirement Enumeration (enum UserVerificationRequirement)</a> | |
97 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User | |
98 | * Verification</a> | |
99 | */ | |
100 | private final UserVerificationRequirement userVerification; | |
101 | ||
102 | /** | |
103 | * Additional parameters requesting additional processing by the client and authenticator. | |
104 | * | |
105 | * <p>For example, if transaction confirmation is sought from the user, then the prompt string | |
106 | * might be included as an extension. | |
107 | */ | |
108 | @NonNull @Builder.Default | |
109 | private final AssertionExtensionInputs extensions = AssertionExtensionInputs.builder().build(); | |
110 | ||
111 | @JsonCreator | |
112 | private PublicKeyCredentialRequestOptions( | |
113 |
1
1. <init> : negated conditional → KILLED |
@NonNull @JsonProperty("challenge") ByteArray challenge, |
114 | @JsonProperty("timeout") Long timeout, | |
115 | @JsonProperty("rpId") String rpId, | |
116 | @JsonProperty("allowCredentials") List<PublicKeyCredentialDescriptor> allowCredentials, | |
117 | @JsonProperty("userVerification") UserVerificationRequirement userVerification, | |
118 |
1
1. <init> : negated conditional → KILLED |
@NonNull @JsonProperty("extensions") AssertionExtensionInputs extensions) { |
119 | this.challenge = challenge; | |
120 | this.timeout = timeout; | |
121 | this.rpId = rpId; | |
122 | this.allowCredentials = | |
123 |
1
1. <init> : negated conditional → KILLED |
allowCredentials == null ? null : CollectionUtil.immutableList(allowCredentials); |
124 | this.userVerification = userVerification; | |
125 | this.extensions = extensions; | |
126 | } | |
127 | ||
128 | public Optional<Long> getTimeout() { | |
129 |
1
1. getTimeout : replaced return value with Optional.empty for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions::getTimeout → KILLED |
return Optional.ofNullable(timeout); |
130 | } | |
131 | ||
132 | public Optional<List<PublicKeyCredentialDescriptor>> getAllowCredentials() { | |
133 |
1
1. getAllowCredentials : replaced return value with Optional.empty for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions::getAllowCredentials → KILLED |
return Optional.ofNullable(allowCredentials); |
134 | } | |
135 | ||
136 | public Optional<UserVerificationRequirement> getUserVerification() { | |
137 |
1
1. getUserVerification : replaced return value with Optional.empty for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions::getUserVerification → KILLED |
return Optional.ofNullable(userVerification); |
138 | } | |
139 | ||
140 | /** | |
141 | * Serialize this {@link PublicKeyCredentialRequestOptions} value to JSON suitable for sending to | |
142 | * the client. | |
143 | * | |
144 | * <p>Any {@link ByteArray} values in this data structure will be {@link ByteArray#getBase64Url() | |
145 | * Base64Url} encoded. Those values MUST be decoded into <code>BufferSource</code> values (such as | |
146 | * <code>Uint8Array</code>) on the client side before calling <code>navigator.credentials.get() | |
147 | * </code>. | |
148 | * | |
149 | * <p>After decoding binary values, the resulting JavaScript object is suitable for passing as an | |
150 | * argument to <code>navigator.credentials.get()</code>. | |
151 | * | |
152 | * @return a JSON value suitable for sending to the client and passing as an argument to <code> | |
153 | * navigator.credentials.get()</code>, after decoding binary options from Base64Url strings. | |
154 | * @throws JsonProcessingException if JSON serialization fails. | |
155 | */ | |
156 | public String toCredentialsGetJson() throws JsonProcessingException { | |
157 | ObjectMapper json = JacksonCodecs.json(); | |
158 | ObjectNode result = json.createObjectNode(); | |
159 | result.set("publicKey", json.valueToTree(this)); | |
160 |
1
1. toCredentialsGetJson : replaced return value with "" for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions::toCredentialsGetJson → KILLED |
return json.writeValueAsString(result); |
161 | } | |
162 | ||
163 | public static PublicKeyCredentialRequestOptionsBuilder.MandatoryStages builder() { | |
164 |
1
1. builder : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions::builder → KILLED |
return new PublicKeyCredentialRequestOptionsBuilder.MandatoryStages(); |
165 | } | |
166 | ||
167 | public static class PublicKeyCredentialRequestOptionsBuilder { | |
168 | private Long timeout = null; | |
169 | private String rpId = null; | |
170 | private List<PublicKeyCredentialDescriptor> allowCredentials = null; | |
171 | ||
172 | public static class MandatoryStages { | |
173 | private final PublicKeyCredentialRequestOptionsBuilder builder = | |
174 | new PublicKeyCredentialRequestOptionsBuilder(); | |
175 | ||
176 | /** | |
177 | * {@link PublicKeyCredentialRequestOptionsBuilder#challenge(ByteArray) challenge} is a | |
178 | * required parameter. | |
179 | * | |
180 | * @see PublicKeyCredentialRequestOptionsBuilder#challenge(ByteArray) | |
181 | */ | |
182 | public PublicKeyCredentialRequestOptionsBuilder challenge(ByteArray challenge) { | |
183 |
1
1. challenge : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder$MandatoryStages::challenge → KILLED |
return builder.challenge(challenge); |
184 | } | |
185 | } | |
186 | ||
187 | /** | |
188 | * Specifies a time, in milliseconds, that the caller is willing to wait for the call to | |
189 | * complete. | |
190 | * | |
191 | * <p>This is treated as a hint, and MAY be overridden by the client. | |
192 | */ | |
193 |
1
1. timeout : negated conditional → KILLED |
public PublicKeyCredentialRequestOptionsBuilder timeout(@NonNull Optional<Long> timeout) { |
194 | this.timeout = timeout.orElse(null); | |
195 |
1
1. timeout : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::timeout → KILLED |
return this; |
196 | } | |
197 | ||
198 | /* | |
199 | * Workaround, see: https://github.com/rzwitserloot/lombok/issues/2623#issuecomment-714816001 | |
200 | * Consider reverting this workaround if Lombok fixes that issue. | |
201 | */ | |
202 | private PublicKeyCredentialRequestOptionsBuilder timeout(Long timeout) { | |
203 |
1
1. timeout : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::timeout → KILLED |
return this.timeout(Optional.ofNullable(timeout)); |
204 | } | |
205 | ||
206 | /** | |
207 | * Specifies a time, in milliseconds, that the caller is willing to wait for the call to | |
208 | * complete. | |
209 | * | |
210 | * <p>This is treated as a hint, and MAY be overridden by the client. | |
211 | */ | |
212 | public PublicKeyCredentialRequestOptionsBuilder timeout(long timeout) { | |
213 |
1
1. timeout : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::timeout → NO_COVERAGE |
return this.timeout(Optional.of(timeout)); |
214 | } | |
215 | ||
216 | /** | |
217 | * Specifies the relying party identifier claimed by the caller. | |
218 | * | |
219 | * <p>If omitted, its value will be set by the client. | |
220 | */ | |
221 |
1
1. rpId : negated conditional → KILLED |
public PublicKeyCredentialRequestOptionsBuilder rpId(@NonNull Optional<String> rpId) { |
222 |
1
1. rpId : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::rpId → KILLED |
return this.rpId(rpId.orElse(null)); |
223 | } | |
224 | ||
225 | /** | |
226 | * Specifies the relying party identifier claimed by the caller. | |
227 | * | |
228 | * <p>If omitted, its value will be set by the client. | |
229 | */ | |
230 | public PublicKeyCredentialRequestOptionsBuilder rpId(String rpId) { | |
231 | this.rpId = rpId; | |
232 |
1
1. rpId : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::rpId → KILLED |
return this; |
233 | } | |
234 | ||
235 | /** | |
236 | * A list of {@link PublicKeyCredentialDescriptor} objects representing public key credentials | |
237 | * acceptable to the caller, in descending order of the caller’s preference (the first item in | |
238 | * the list is the most preferred credential, and so on down the list). | |
239 | */ | |
240 | public PublicKeyCredentialRequestOptionsBuilder allowCredentials( | |
241 |
1
1. allowCredentials : negated conditional → KILLED |
@NonNull Optional<List<PublicKeyCredentialDescriptor>> allowCredentials) { |
242 |
1
1. allowCredentials : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::allowCredentials → KILLED |
return this.allowCredentials(allowCredentials.orElse(null)); |
243 | } | |
244 | ||
245 | /** | |
246 | * A list of {@link PublicKeyCredentialDescriptor} objects representing public key credentials | |
247 | * acceptable to the caller, in descending order of the caller’s preference (the first item in | |
248 | * the list is the most preferred credential, and so on down the list). | |
249 | */ | |
250 | public PublicKeyCredentialRequestOptionsBuilder allowCredentials( | |
251 | List<PublicKeyCredentialDescriptor> allowCredentials) { | |
252 | this.allowCredentials = allowCredentials; | |
253 |
1
1. allowCredentials : replaced return value with null for com/yubico/webauthn/data/PublicKeyCredentialRequestOptions$PublicKeyCredentialRequestOptionsBuilder::allowCredentials → KILLED |
return this; |
254 | } | |
255 | } | |
256 | } | |
Mutations | ||
113 |
1.1 |
|
118 |
1.1 |
|
123 |
1.1 |
|
129 |
1.1 |
|
133 |
1.1 |
|
137 |
1.1 |
|
160 |
1.1 |
|
164 |
1.1 |
|
183 |
1.1 |
|
193 |
1.1 |
|
195 |
1.1 |
|
203 |
1.1 |
|
213 |
1.1 |
|
221 |
1.1 |
|
222 |
1.1 |
|
232 |
1.1 |
|
241 |
1.1 |
|
242 |
1.1 |
|
253 |
1.1 |