1 | package com.yubico.webauthn.data; | |
2 | ||
3 | import com.fasterxml.jackson.annotation.JsonCreator; | |
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
5 | import com.fasterxml.jackson.annotation.JsonProperty; | |
6 | import com.fasterxml.jackson.annotation.JsonValue; | |
7 | import com.upokecenter.cbor.CBORObject; | |
8 | import com.upokecenter.cbor.CBORType; | |
9 | import com.yubico.internal.util.ExceptionUtil; | |
10 | import com.yubico.webauthn.FinishRegistrationOptions; | |
11 | import com.yubico.webauthn.RelyingParty; | |
12 | import com.yubico.webauthn.StartAssertionOptions; | |
13 | import com.yubico.webauthn.StartRegistrationOptions; | |
14 | import com.yubico.webauthn.extension.uvm.KeyProtectionType; | |
15 | import com.yubico.webauthn.extension.uvm.MatcherProtectionType; | |
16 | import com.yubico.webauthn.extension.uvm.UserVerificationMethod; | |
17 | import java.util.Arrays; | |
18 | import java.util.Collections; | |
19 | import java.util.HashMap; | |
20 | import java.util.List; | |
21 | import java.util.Map; | |
22 | import java.util.Optional; | |
23 | import java.util.Set; | |
24 | import java.util.stream.Collectors; | |
25 | import java.util.stream.Stream; | |
26 | import lombok.AllArgsConstructor; | |
27 | import lombok.Builder; | |
28 | import lombok.NonNull; | |
29 | import lombok.Value; | |
30 | import lombok.experimental.UtilityClass; | |
31 | import lombok.extern.slf4j.Slf4j; | |
32 | ||
33 | /** Definitions for WebAuthn extensions. */ | |
34 | @Slf4j | |
35 | @UtilityClass | |
36 | public class Extensions { | |
37 | ||
38 | /** | |
39 | * Definitions for the FIDO AppID Extension (<code>appid</code>). | |
40 | * | |
41 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-extension">§10.1. | |
42 | * FIDO AppID Extension (appid)</a> | |
43 | */ | |
44 | public static class Appid { | |
45 | static final String EXTENSION_ID = "appid"; | |
46 | } | |
47 | ||
48 | /** | |
49 | * Definitions for the 10.2. FIDO AppID Exclusion Extension (<code>appidExclude</code>). | |
50 | * | |
51 | * @see <a | |
52 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-appid-exclude-extension">10.2. | |
53 | * FIDO AppID Exclusion Extension (appidExclude)</a> | |
54 | */ | |
55 | public static class AppidExclude { | |
56 | static final String EXTENSION_ID = "appidExclude"; | |
57 | } | |
58 | ||
59 | /** | |
60 | * Definitions for the Credential Properties Extension (<code>credProps</code>). | |
61 | * | |
62 | * @see <a | |
63 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-credential-properties-extension">§10.4. | |
64 | * Credential Properties Extension (credProps)</a> | |
65 | */ | |
66 | public static class CredentialProperties { | |
67 | static final String EXTENSION_ID = "credProps"; | |
68 | ||
69 | /** | |
70 | * Extension outputs for the Credential Properties Extension (<code>credProps</code>). | |
71 | * | |
72 | * @see <a | |
73 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-credential-properties-extension">§10.4. | |
74 | * Credential Properties Extension (credProps)</a> | |
75 | */ | |
76 | @Value | |
77 | @Builder | |
78 | @JsonIgnoreProperties(ignoreUnknown = true) | |
79 | public static class CredentialPropertiesOutput { | |
80 | @JsonProperty("rk") | |
81 | private final Boolean rk; | |
82 | ||
83 | @JsonCreator | |
84 | private CredentialPropertiesOutput(@JsonProperty("rk") Boolean rk) { | |
85 | this.rk = rk; | |
86 | } | |
87 | ||
88 | /** | |
89 | * This OPTIONAL property, known abstractly as the <b>resident key credential property</b> | |
90 | * (i.e., <b>client-side discoverable credential property</b>), is a Boolean value indicating | |
91 | * whether the {@link PublicKeyCredential} returned as a result of a registration ceremony is | |
92 | * a <i>client-side discoverable credential</i> (passkey). | |
93 | * | |
94 | * <p>If this is <code>true</code>, the credential is a <i>discoverable credential</i> | |
95 | * (passkey). | |
96 | * | |
97 | * <p>If this is <code>false</code>, the credential is a <i>server-side credential</i>. | |
98 | * | |
99 | * <p>If this is not present, it is not known whether the credential is a discoverable | |
100 | * credential or a server-side credential. | |
101 | * | |
102 | * @see <a | |
103 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-credentialpropertiesoutput-rk">§10.4. | |
104 | * Credential Properties Extension (credProps)</a> | |
105 | * @see <a | |
106 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-credential">Client-side | |
107 | * discoverable Credential</a> | |
108 | * @see <a | |
109 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#server-side-credential">Server-side | |
110 | * Credential</a> | |
111 | * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a | |
112 | * href="https://passkeys.dev">passkeys.dev</a> reference | |
113 | */ | |
114 | public Optional<Boolean> getRk() { | |
115 |
1
1. getRk : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProperties$CredentialPropertiesOutput::getRk → KILLED |
return Optional.ofNullable(rk); |
116 | } | |
117 | } | |
118 | } | |
119 | ||
120 | /** | |
121 | * Definitions for the Credential Protection (<code>credProtect</code>) extension. | |
122 | * | |
123 | * @since 2.7.0 | |
124 | * @see <a | |
125 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
126 | * §12.1. Credential Protection (credProtect)</a> | |
127 | */ | |
128 | public static class CredentialProtection { | |
129 | static final String EXTENSION_ID = "credProtect"; | |
130 | ||
131 | /** | |
132 | * Policy values for the Credential Protection (<code>credProtect</code>) extension. | |
133 | * | |
134 | * <p>Available values: | |
135 | * | |
136 | * <ul> | |
137 | * <li>{@link #UV_OPTIONAL} | |
138 | * <li>{@link #UV_OPTIONAL_WITH_CREDENTIAL_ID_LIST} | |
139 | * <li>{@link #UV_REQUIRED} | |
140 | * </ul> | |
141 | * | |
142 | * @since 2.7.0 | |
143 | * @see <a | |
144 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
145 | * §12.1. Credential Protection (credProtect)</a> | |
146 | * @see CredentialProtectionInput#prefer(CredentialProtectionPolicy) | |
147 | * @see CredentialProtectionInput#require(CredentialProtectionPolicy) | |
148 | */ | |
149 | @AllArgsConstructor | |
150 | public enum CredentialProtectionPolicy { | |
151 | /** | |
152 | * In this configuration, performing some form of user verification is always OPTIONAL. This | |
153 | * is the default behaviour if the extension is not specified; note however that some browsers | |
154 | * may set a different default extension input if the extension is not explicitly specified. | |
155 | * | |
156 | * @since 2.7.0 | |
157 | * @see <a | |
158 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
159 | * §12.1. Credential Protection (credProtect)</a> | |
160 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User | |
161 | * Verification</a> | |
162 | */ | |
163 | UV_OPTIONAL(0x01, "userVerificationOptional"), | |
164 | ||
165 | /** | |
166 | * In this configuration, performing some form of user verification is OPTIONAL when the | |
167 | * credential is used as the second authentication factor, and REQUIRED when the credential is | |
168 | * used as the first authentication factor. | |
169 | * | |
170 | * <p>In technical terms, user verification is REQUIRED when {@link | |
171 | * PublicKeyCredentialRequestOptions#getAllowCredentials() allowCredentials} is empty and | |
172 | * OPTIONAL when it is non-empty. {@link | |
173 | * PublicKeyCredentialRequestOptions#getAllowCredentials() allowCredentials} is non-empty when | |
174 | * {@link StartAssertionOptions.StartAssertionOptionsBuilder#username(String) username} or | |
175 | * {@link StartAssertionOptions.StartAssertionOptionsBuilder#userHandle(ByteArray) userHandle} | |
176 | * was set in the call to {@link RelyingParty#startAssertion(StartAssertionOptions)}, and is | |
177 | * empty when neither was set. | |
178 | * | |
179 | * @since 2.7.0 | |
180 | * @see <a | |
181 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
182 | * §12.1. Credential Protection (credProtect)</a> | |
183 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User | |
184 | * Verification</a> | |
185 | */ | |
186 | UV_OPTIONAL_WITH_CREDENTIAL_ID_LIST(0x02, "userVerificationOptionalWithCredentialIDList"), | |
187 | ||
188 | /** | |
189 | * In this configuration, performing some form of user verification is always REQUIRED. | |
190 | * | |
191 | * @since 2.7.0 | |
192 | * @see <a | |
193 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
194 | * §12.1. Credential Protection (credProtect)</a> | |
195 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">User | |
196 | * Verification</a> | |
197 | */ | |
198 | UV_REQUIRED(0x03, "userVerificationRequired"); | |
199 | ||
200 | final int cborValue; | |
201 | ||
202 | @JsonValue private final String jsValue; | |
203 | ||
204 | private static Optional<CredentialProtectionPolicy> fromCbor(int cborValue) { | |
205 |
1
1. fromCbor : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromCbor → KILLED |
return Arrays.stream(CredentialProtectionPolicy.values()) |
206 |
2
1. lambda$fromCbor$0 : replaced boolean return with true for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromCbor$0 → KILLED 2. lambda$fromCbor$0 : negated conditional → KILLED |
.filter(policy -> policy.cborValue == cborValue) |
207 | .findAny(); | |
208 | } | |
209 | ||
210 | private static Optional<CredentialProtectionPolicy> fromJs(String jsonValue) { | |
211 |
1
1. fromJs : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromJs → KILLED |
return Arrays.stream(CredentialProtectionPolicy.values()) |
212 |
2
1. lambda$fromJs$1 : replaced boolean return with false for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJs$1 → KILLED 2. lambda$fromJs$1 : replaced boolean return with true for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJs$1 → KILLED |
.filter(policy -> policy.jsValue.equals(jsonValue)) |
213 | .findAny(); | |
214 | } | |
215 | ||
216 | @JsonCreator | |
217 |
1
1. fromJsonString : negated conditional → KILLED |
private static CredentialProtectionPolicy fromJsonString(@NonNull String value) { |
218 |
1
1. fromJsonString : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::fromJsonString → KILLED |
return fromJs(value) |
219 | .orElseThrow( | |
220 | () -> | |
221 |
1
1. lambda$fromJsonString$2 : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionPolicy::lambda$fromJsonString$2 → NO_COVERAGE |
new IllegalArgumentException( |
222 | String.format( | |
223 | "Unknown %s value: %s", | |
224 | CredentialProtectionPolicy.class.getSimpleName(), value))); | |
225 | } | |
226 | } | |
227 | ||
228 | /** | |
229 | * Extension inputs for the Credential Protection (<code>credProtect</code>) extension. | |
230 | * | |
231 | * <p>Instances may be created using the {@link #prefer(CredentialProtectionPolicy)} and {@link | |
232 | * #require(CredentialProtectionPolicy)} factory functions. | |
233 | * | |
234 | * @since 2.7.0 | |
235 | * @see <a | |
236 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
237 | * §12.1. Credential Protection (credProtect)</a> | |
238 | */ | |
239 | @Value | |
240 | public static class CredentialProtectionInput { | |
241 | /** | |
242 | * The requested credential protection policy. This policy may or may not be satisfied; see | |
243 | * {@link #isEnforceCredentialProtectionPolicy()}. | |
244 | * | |
245 | * @since 2.7.0 | |
246 | * @see CredentialProtectionPolicy | |
247 | * @see #isEnforceCredentialProtectionPolicy() | |
248 | * @see <a | |
249 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
250 | * §12.1. Credential Protection (credProtect)</a> | |
251 | */ | |
252 | private final CredentialProtectionPolicy credentialProtectionPolicy; | |
253 | ||
254 | /** | |
255 | * If this is <code>true</code> and {@link #getCredentialProtectionPolicy() | |
256 | * credentialProtectionPolicy} is not {@link CredentialProtectionPolicy#UV_OPTIONAL}, {@link | |
257 | * RelyingParty#finishRegistration(FinishRegistrationOptions)} will validate that the policy | |
258 | * set in {@link #getCredentialProtectionPolicy()} was satisfied and the browser is requested | |
259 | * to fail the registration if the policy cannot be satisfied. | |
260 | * | |
261 | * <p>{@link CredentialProtectionInput#prefer(CredentialProtectionPolicy)} sets this to <code> | |
262 | * false</code>. {@link CredentialProtectionInput#require(CredentialProtectionPolicy)} sets | |
263 | * this to <code>true</code>. | |
264 | * | |
265 | * @since 2.7.0 | |
266 | * @see CredentialProtectionPolicy | |
267 | * @see #getCredentialProtectionPolicy() | |
268 | * @see <a | |
269 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
270 | * §12.1. Credential Protection (credProtect)</a> | |
271 | */ | |
272 | private final boolean enforceCredentialProtectionPolicy; | |
273 | ||
274 | @JsonCreator | |
275 | private CredentialProtectionInput( | |
276 | @JsonProperty("credentialProtectionPolicy") | |
277 | CredentialProtectionPolicy credentialProtectionPolicy, | |
278 | @JsonProperty("enforceCredentialProtectionPolicy") | |
279 | Boolean enforceCredentialProtectionPolicy) { | |
280 | this.credentialProtectionPolicy = credentialProtectionPolicy; | |
281 |
1
1. <init> : negated conditional → KILLED |
this.enforceCredentialProtectionPolicy = |
282 |
1
1. <init> : negated conditional → KILLED |
enforceCredentialProtectionPolicy != null && enforceCredentialProtectionPolicy; |
283 | } | |
284 | ||
285 | /** | |
286 | * Create a Credential Protection (<code>credProtect</code>) extension input that requests the | |
287 | * given policy when possible. | |
288 | * | |
289 | * <p>If the policy cannot be satisfied, the browser is requested to continue the registration | |
290 | * anyway. To determine what policy was applied, use {@link | |
291 | * AuthenticatorRegistrationExtensionOutputs#getCredProtect()} to inspect the extension | |
292 | * output. {@link RelyingParty#finishRegistration(FinishRegistrationOptions)} will not | |
293 | * validate what policy was applied. | |
294 | * | |
295 | * <p>Use {@link #require(CredentialProtectionPolicy)} instead to forbid the registration from | |
296 | * proceeding if the extension is not supported or the policy cannot be satisfied. | |
297 | * | |
298 | * @param policy the policy to request. | |
299 | * @return a <code>credProtect</code> extension input that requests the given policy when | |
300 | * possible. The browser is requested to continue the registration even if this policy | |
301 | * cannot be satisfied. | |
302 | * @since 2.7.0 | |
303 | * @see #require(CredentialProtectionPolicy) | |
304 | * @see <a | |
305 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
306 | * §12.1. Credential Protection (credProtect)</a> | |
307 | */ | |
308 | public static CredentialProtectionInput prefer( | |
309 |
1
1. prefer : negated conditional → KILLED |
@NonNull final CredentialProtectionPolicy policy) { |
310 |
1
1. prefer : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionInput::prefer → KILLED |
return new CredentialProtectionInput(policy, false); |
311 | } | |
312 | ||
313 | /** | |
314 | * Create a Credential Protection (<code>credProtect</code>) extension input that requires the | |
315 | * given policy. | |
316 | * | |
317 | * <p>If the policy is not {@link CredentialProtectionPolicy#UV_OPTIONAL} and cannot be | |
318 | * satisfied, the browser is requested to abort the registration instead of proceeding. {@link | |
319 | * RelyingParty#finishRegistration(FinishRegistrationOptions)} will validate that the policy | |
320 | * returned in the authenticator extension output equals this input policy, and throw an | |
321 | * exception otherwise. You can also use {@link | |
322 | * AuthenticatorRegistrationExtensionOutputs#getCredProtect()} to inspect the extension output | |
323 | * yourself. | |
324 | * | |
325 | * <p>Note that if the browser or authenticator does not support the extension, the | |
326 | * registration will fail. Use {@link #prefer(CredentialProtectionPolicy)} instead to allow | |
327 | * the registration to proceed if the extension is not supported or the policy cannot be | |
328 | * satisfied. | |
329 | * | |
330 | * @param policy the policy to require. | |
331 | * @return a <code>credProtect</code> extension input that requires the given policy. The | |
332 | * browser is requested to abort the registration if this policy cannot be satisfied. | |
333 | * @since 2.7.0 | |
334 | * @see <a | |
335 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
336 | * §12.1. Credential Protection (credProtect)</a> | |
337 | */ | |
338 | public static CredentialProtectionInput require( | |
339 |
1
1. require : negated conditional → KILLED |
@NonNull final CredentialProtectionPolicy policy) { |
340 |
1
1. require : replaced return value with null for com/yubico/webauthn/data/Extensions$CredentialProtection$CredentialProtectionInput::require → KILLED |
return new CredentialProtectionInput(policy, true); |
341 | } | |
342 | } | |
343 | ||
344 | /** | |
345 | * Validate that the given response satisfies the <code>credProtect</code> extension policy set | |
346 | * in the request. | |
347 | * | |
348 | * <p>If the {@link | |
349 | * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput) | |
350 | * credProtect} extension is not set in the request, this has no effect. | |
351 | * | |
352 | * <p>If the {@link | |
353 | * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput) | |
354 | * credProtect} extension is set in the request with {@link | |
355 | * CredentialProtectionInput#isEnforceCredentialProtectionPolicy() | |
356 | * enforceCredentialProtectionPolicy} set to <code>false</code> or {@link | |
357 | * CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} set to | |
358 | * {@link CredentialProtectionPolicy#UV_OPTIONAL}, this has no effect. | |
359 | * | |
360 | * <p>If the {@link | |
361 | * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput) | |
362 | * credProtect} extension is set in the request with {@link | |
363 | * CredentialProtectionInput#isEnforceCredentialProtectionPolicy() | |
364 | * enforceCredentialProtectionPolicy} set to <code>true</code> and {@link | |
365 | * CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} is not | |
366 | * set to {@link CredentialProtectionPolicy#UV_OPTIONAL}, then this throws an {@link | |
367 | * IllegalArgumentException} if the <code>credProtect</code> authenticator extension output does | |
368 | * not equal the {@link CredentialProtectionInput#getCredentialProtectionPolicy() | |
369 | * credentialProtectionPolicy} set in the request. | |
370 | * | |
371 | * <p>This function is called automatically in {@link | |
372 | * RelyingParty#finishRegistration(FinishRegistrationOptions)}; you should not need to call it | |
373 | * yourself. | |
374 | * | |
375 | * @param request the arguments to start the registration ceremony. | |
376 | * @param response the response from the registration ceremony. | |
377 | * @throws IllegalArgumentException if the {@link | |
378 | * RegistrationExtensionInputs.RegistrationExtensionInputsBuilder#credProtect(CredentialProtectionInput) | |
379 | * credProtect} extension is set in the request with {@link | |
380 | * CredentialProtectionInput#isEnforceCredentialProtectionPolicy() | |
381 | * enforceCredentialProtectionPolicy} set to <code>true</code> and {@link | |
382 | * CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} not | |
383 | * set to {@link CredentialProtectionPolicy#UV_OPTIONAL}, and the <code>credProtect | |
384 | * </code> authenticator extension output does not equal the {@link | |
385 | * CredentialProtectionInput#getCredentialProtectionPolicy() credentialProtectionPolicy} set | |
386 | * in the request. | |
387 | * @since 2.7.0 | |
388 | * @see <a | |
389 | * href="https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-credProtect-extension">CTAP2 | |
390 | * §12.1. Credential Protection (credProtect)</a> | |
391 | */ | |
392 | public static void validateExtensionOutput( | |
393 | PublicKeyCredentialCreationOptions request, | |
394 | PublicKeyCredential<AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs> | |
395 | response) { | |
396 | request | |
397 | .getExtensions() | |
398 | .getCredProtect() | |
399 |
1
1. validateExtensionOutput : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent( |
400 | credProtectInput -> { | |
401 |
1
1. lambda$validateExtensionOutput$0 : negated conditional → KILLED |
if (credProtectInput.isEnforceCredentialProtectionPolicy() |
402 |
1
1. lambda$validateExtensionOutput$0 : negated conditional → KILLED |
&& credProtectInput.getCredentialProtectionPolicy() |
403 | != CredentialProtectionPolicy.UV_OPTIONAL) { | |
404 | Optional<CredentialProtectionPolicy> outputPolicy = | |
405 | response | |
406 | .getResponse() | |
407 | .getParsedAuthenticatorData() | |
408 | .getExtensions() | |
409 | .flatMap(CredentialProtection::parseAuthenticatorExtensionOutput); | |
410 |
1
1. lambda$validateExtensionOutput$0 : removed call to com/yubico/internal/util/ExceptionUtil::assertTrue → KILLED |
ExceptionUtil.assertTrue( |
411 | outputPolicy.equals( | |
412 | Optional.of(credProtectInput.getCredentialProtectionPolicy())), | |
413 | "Unsatisfied credProtect policy: required %s, got: %s", | |
414 | credProtectInput.getCredentialProtectionPolicy(), | |
415 | outputPolicy); | |
416 | } | |
417 | }); | |
418 | } | |
419 | ||
420 | static Optional<CredentialProtectionPolicy> parseAuthenticatorExtensionOutput(CBORObject cbor) { | |
421 |
1
1. parseAuthenticatorExtensionOutput : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection::parseAuthenticatorExtensionOutput → KILLED |
return Optional.ofNullable(cbor.get(EXTENSION_ID)) |
422 | .map( | |
423 | cborObject -> | |
424 |
3
1. lambda$parseAuthenticatorExtensionOutput$1 : replaced Integer return value with 0 for com/yubico/webauthn/data/Extensions$CredentialProtection::lambda$parseAuthenticatorExtensionOutput$1 → KILLED 2. lambda$parseAuthenticatorExtensionOutput$1 : negated conditional → KILLED 3. lambda$parseAuthenticatorExtensionOutput$1 : negated conditional → KILLED |
cborObject.isNumber() && cborObject.AsNumber().IsInteger() |
425 | ? cborObject.AsInt32() | |
426 | : null) | |
427 |
1
1. lambda$parseAuthenticatorExtensionOutput$2 : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$CredentialProtection::lambda$parseAuthenticatorExtensionOutput$2 → KILLED |
.flatMap(CredentialProtectionPolicy::fromCbor); |
428 | } | |
429 | } | |
430 | ||
431 | /** | |
432 | * Definitions for the Large blob storage extension (<code>largeBlob</code>). | |
433 | * | |
434 | * @see <a | |
435 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
436 | * Large blob storage extension (largeBlob)</a> | |
437 | */ | |
438 | public static class LargeBlob { | |
439 | static final String EXTENSION_ID = "largeBlob"; | |
440 | ||
441 | /** | |
442 | * Extension inputs for the Large blob storage extension (<code>largeBlob</code>) in | |
443 | * registration ceremonies. | |
444 | * | |
445 | * @see <a | |
446 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
447 | * Large blob storage extension (largeBlob)</a> | |
448 | */ | |
449 | @Value | |
450 | public static class LargeBlobRegistrationInput { | |
451 | /** | |
452 | * The Relying Party's preference of whether the created credential should support the <code> | |
453 | * largeBlob</code> extension. | |
454 | */ | |
455 | @JsonProperty private final LargeBlobSupport support; | |
456 | ||
457 | @JsonCreator | |
458 | public LargeBlobRegistrationInput( | |
459 | /** | |
460 | * The Relying Party's preference of whether the created credential should support the | |
461 | * <code> | |
462 | * largeBlob</code> extension. | |
463 | * | |
464 | * <p>Currently the only valid values are {@link LargeBlobSupport#REQUIRED} and {@link | |
465 | * LargeBlobSupport#PREFERRED}, but custom values MAY be constructed in case more values | |
466 | * are added in future revisions of the extension. | |
467 | */ | |
468 | @JsonProperty("support") LargeBlobSupport support) { | |
469 | this.support = support; | |
470 | } | |
471 | ||
472 | /** | |
473 | * The known valid arguments for the Large blob storage extension (<code>largeBlob</code>) | |
474 | * input in registration ceremonies. | |
475 | * | |
476 | * <p>Currently the only valid values are {@link LargeBlobSupport#REQUIRED} and {@link | |
477 | * LargeBlobSupport#PREFERRED}, but custom values MAY be constructed in case more values are | |
478 | * added in future revisions of the extension. | |
479 | * | |
480 | * @see #REQUIRED | |
481 | * @see #PREFERRED | |
482 | * @see <a | |
483 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
484 | * Large blob storage extension (largeBlob)</a> | |
485 | */ | |
486 | @Value | |
487 | public static class LargeBlobSupport { | |
488 | /** | |
489 | * The authenticator used for registration MUST support the <code>largeBlob</code> | |
490 | * extension. | |
491 | * | |
492 | * <p>Note: If the client does not support the <code>largeBlob</code> extension, this | |
493 | * requirement MAY be ignored. | |
494 | * | |
495 | * <p>Note: CTAP authenticators only support <code>largeBlob</code> in combination with | |
496 | * {@link AuthenticatorSelectionCriteria#getResidentKey()} set to <code>REQUIRED</code> in | |
497 | * {@link StartRegistrationOptions#getAuthenticatorSelection()}. | |
498 | * | |
499 | * @see <a | |
500 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
501 | * Large blob storage extension (largeBlob)</a> | |
502 | */ | |
503 | public static final LargeBlobSupport REQUIRED = new LargeBlobSupport("required"); | |
504 | ||
505 | /** | |
506 | * If the authenticator used for registration supports the <code>largeBlob</code> extension, | |
507 | * it will be enabled for the created credential. If not supported, the credential will be | |
508 | * created without large blob support. | |
509 | * | |
510 | * <p>Note: CTAP authenticators only support <code>largeBlob</code> in combination with | |
511 | * {@link AuthenticatorSelectionCriteria#getResidentKey()} set to <code>REQUIRED</code> in | |
512 | * {@link StartRegistrationOptions#getAuthenticatorSelection()}. | |
513 | * | |
514 | * @see <a | |
515 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
516 | * Large blob storage extension (largeBlob)</a> | |
517 | */ | |
518 | public static final LargeBlobSupport PREFERRED = new LargeBlobSupport("preferred"); | |
519 | ||
520 | /** | |
521 | * The underlying string value of this {@link LargeBlobSupport} value. | |
522 | * | |
523 | * @see #REQUIRED | |
524 | * @see #PREFERRED | |
525 | */ | |
526 | @JsonValue private final String value; | |
527 | ||
528 | /** | |
529 | * Returns a new {@link Set} containing the {@link #REQUIRED} and {@link #PREFERRED} values. | |
530 | */ | |
531 | public static Set<LargeBlobSupport> values() { | |
532 |
1
1. values : replaced return value with Collections.emptySet for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobRegistrationInput$LargeBlobSupport::values → KILLED |
return Stream.of(REQUIRED, PREFERRED).collect(Collectors.toSet()); |
533 | } | |
534 | } | |
535 | } | |
536 | ||
537 | /** | |
538 | * Extension inputs for the Large blob storage extension (<code>largeBlob</code>) in | |
539 | * authentication ceremonies. | |
540 | * | |
541 | * <p>Use the {@link #read()} and {@link #write(ByteArray)} factory functions to construct this | |
542 | * type. | |
543 | * | |
544 | * @see <a | |
545 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
546 | * Large blob storage extension (largeBlob)</a> | |
547 | */ | |
548 | @Value | |
549 | public static class LargeBlobAuthenticationInput { | |
550 | /** | |
551 | * If <code>true</code>, indicates that the Relying Party would like to fetch the | |
552 | * previously-written blob associated with the asserted credential. | |
553 | * | |
554 | * @see #read() | |
555 | * @see <a | |
556 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5. | |
557 | * Large blob storage extension (largeBlob)</a> | |
558 | */ | |
559 | @JsonProperty private final boolean read; | |
560 | ||
561 | /** | |
562 | * An opaque byte string that the Relying Party wishes to store with the existing credential. | |
563 | * | |
564 | * @see #write(ByteArray) | |
565 | * @see <a | |
566 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-write">§10.5. | |
567 | * Large blob storage extension (largeBlob)</a> | |
568 | */ | |
569 | @JsonProperty private final ByteArray write; | |
570 | ||
571 | @JsonCreator | |
572 | private LargeBlobAuthenticationInput( | |
573 | @JsonProperty("read") final Boolean read, @JsonProperty("write") final ByteArray write) { | |
574 |
3
1. <init> : negated conditional → KILLED 2. <init> : negated conditional → KILLED 3. <init> : negated conditional → KILLED |
if (read != null && read && write != null) { |
575 | throw new IllegalArgumentException( | |
576 | "Parameters \"read\" and \"write\" of largeBlob extension must not both be present."); | |
577 | } | |
578 | ||
579 |
2
1. <init> : negated conditional → KILLED 2. <init> : negated conditional → KILLED |
this.read = read != null && read; |
580 | this.write = write; | |
581 | } | |
582 | ||
583 | /** | |
584 | * Configure the Large blob storage extension (<code>largeBlob</code>) to fetch the | |
585 | * previously-written blob associated with the asserted credential. | |
586 | * | |
587 | * <p>Mutually exclusive with {@link #write(ByteArray)}. | |
588 | * | |
589 | * @see <a | |
590 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5. | |
591 | * Large blob storage extension (largeBlob)</a> | |
592 | */ | |
593 | public static LargeBlobAuthenticationInput read() { | |
594 |
1
1. read : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::read → KILLED |
return new LargeBlobAuthenticationInput(true, null); |
595 | } | |
596 | ||
597 | /** | |
598 | * Configure the Large blob storage extension (<code>largeBlob</code>) to store the given byte | |
599 | * array with the existing credential. | |
600 | * | |
601 | * <p>Mutually exclusive with {@link #read()}. | |
602 | * | |
603 | * @see <a | |
604 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-write">§10.5. | |
605 | * Large blob storage extension (largeBlob)</a> | |
606 | */ | |
607 |
1
1. write : negated conditional → KILLED |
public static LargeBlobAuthenticationInput write(@NonNull final ByteArray write) { |
608 |
1
1. write : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::write → SURVIVED |
return new LargeBlobAuthenticationInput(false, write); |
609 | } | |
610 | ||
611 | /** | |
612 | * @return <code>true</code> if the <code>read</code> property is set to <code>true</code>, | |
613 | * <code>false</code> otherwise. | |
614 | * @see #read() | |
615 | * @see <a | |
616 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5. | |
617 | * Large blob storage extension (largeBlob)</a> | |
618 | */ | |
619 | public boolean getRead() { | |
620 |
2
1. getRead : replaced boolean return with false for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getRead → KILLED 2. getRead : replaced boolean return with true for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getRead → KILLED |
return read; |
621 | } | |
622 | ||
623 | /** | |
624 | * @return The value of the <code>write</code> property if configured, empty otherwise. | |
625 | * @see #write(ByteArray) | |
626 | * @see <a | |
627 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargeblobinputs-read">§10.5. | |
628 | * Large blob storage extension (largeBlob)</a> | |
629 | */ | |
630 | public Optional<ByteArray> getWrite() { | |
631 |
1
1. getWrite : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationInput::getWrite → SURVIVED |
return Optional.ofNullable(write); |
632 | } | |
633 | } | |
634 | ||
635 | /** | |
636 | * Extension outputs for the Large blob storage extension (<code>largeBlob</code>) in | |
637 | * registration ceremonies. | |
638 | * | |
639 | * <p>Use the {@link #supported(boolean)} factory function to construct this type. | |
640 | * | |
641 | * @see <a | |
642 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
643 | * Large blob storage extension (largeBlob)</a> | |
644 | */ | |
645 | @Value | |
646 | public static class LargeBlobRegistrationOutput { | |
647 | /** | |
648 | * <code>true</code> if, and only if, the created credential supports storing large blobs. | |
649 | * | |
650 | * @see <a | |
651 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargebloboutputs-supported">§10.5. | |
652 | * Large blob storage extension (largeBlob)</a> | |
653 | * @see LargeBlobRegistrationInput#getSupport() | |
654 | */ | |
655 | @JsonProperty private final boolean supported; | |
656 | ||
657 | @JsonCreator | |
658 | private LargeBlobRegistrationOutput(@JsonProperty("supported") boolean supported) { | |
659 | this.supported = supported; | |
660 | } | |
661 | ||
662 | /** | |
663 | * Create a Large blob storage extension output with the <code>supported</code> output set to | |
664 | * the given value. | |
665 | * | |
666 | * @see <a | |
667 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-authenticationextensionslargebloboutputs"> | |
668 | * dictionary AuthenticationExtensionsLargeBlobOutputs</a> | |
669 | */ | |
670 | public static LargeBlobRegistrationOutput supported(boolean supported) { | |
671 |
1
1. supported : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobRegistrationOutput::supported → KILLED |
return new LargeBlobRegistrationOutput(supported); |
672 | } | |
673 | } | |
674 | ||
675 | /** | |
676 | * Extension outputs for the Large blob storage extension (<code>largeBlob</code>) in | |
677 | * authentication ceremonies. | |
678 | * | |
679 | * @see <a | |
680 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-large-blob-extension">§10.5. | |
681 | * Large blob storage extension (largeBlob)</a> | |
682 | */ | |
683 | @Value | |
684 | public static class LargeBlobAuthenticationOutput { | |
685 | @JsonProperty private final ByteArray blob; | |
686 | @JsonProperty private final Boolean written; | |
687 | ||
688 | @JsonCreator | |
689 | private LargeBlobAuthenticationOutput( | |
690 | @JsonProperty("blob") ByteArray blob, @JsonProperty("written") Boolean written) { | |
691 | this.blob = blob; | |
692 | this.written = written; | |
693 | } | |
694 | ||
695 | /** | |
696 | * Create a Large blob storage extension output with the <code>blob</code> output set to the | |
697 | * given value. | |
698 | * | |
699 | * <p>This corresponds to the extension input {@link LargeBlobAuthenticationInput#read() | |
700 | * LargeBlobAuthenticationInput.read()}. | |
701 | * | |
702 | * @see <a | |
703 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-authenticationextensionslargebloboutputs"> | |
704 | * dictionary AuthenticationExtensionsLargeBlobOutputs</a> | |
705 | */ | |
706 | public static LargeBlobAuthenticationOutput read(final ByteArray blob) { | |
707 |
1
1. read : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::read → KILLED |
return new LargeBlobAuthenticationOutput(blob, null); |
708 | } | |
709 | ||
710 | /** | |
711 | * Create a Large blob storage extension output with the <code>written</code> output set to | |
712 | * the given value. | |
713 | * | |
714 | * <p>This corresponds to the extension input {@link | |
715 | * LargeBlobAuthenticationInput#write(ByteArray) | |
716 | * LargeBlobAuthenticationInput.write(ByteArray)}. | |
717 | * | |
718 | * @see <a | |
719 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictdef-authenticationextensionslargebloboutputs"> | |
720 | * dictionary AuthenticationExtensionsLargeBlobOutputs</a> | |
721 | */ | |
722 | public static LargeBlobAuthenticationOutput write(final boolean write) { | |
723 |
1
1. write : replaced return value with null for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::write → KILLED |
return new LargeBlobAuthenticationOutput(null, write); |
724 | } | |
725 | ||
726 | /** | |
727 | * The opaque byte string that was associated with the credential identified by {@link | |
728 | * PublicKeyCredential#getId()}. Only valid if {@link LargeBlobAuthenticationInput#getRead()} | |
729 | * was <code>true</code>. | |
730 | * | |
731 | * @return A present {@link Optional} if {@link LargeBlobAuthenticationInput#getRead()} was | |
732 | * <code>true</code> and the blob content was successfully read. Otherwise (if {@link | |
733 | * LargeBlobAuthenticationInput#getRead()} was <code>false</code> or the content failed to | |
734 | * be read) an empty {@link Optional}. | |
735 | * @see <a | |
736 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargebloboutputs-blob">§10.5. | |
737 | * Large blob storage extension (largeBlob)</a> | |
738 | */ | |
739 | public Optional<ByteArray> getBlob() { | |
740 |
1
1. getBlob : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::getBlob → KILLED |
return Optional.ofNullable(blob); |
741 | } | |
742 | ||
743 | /** | |
744 | * A boolean that indicates that the contents of {@link | |
745 | * LargeBlob.LargeBlobAuthenticationInput#write(ByteArray) | |
746 | * LargeBlobAuthenticationInput#write(ByteArray)} were successfully stored on the | |
747 | * authenticator, associated with the specified credential. | |
748 | * | |
749 | * @return Empty if {@link LargeBlobAuthenticationInput#getWrite()} was not present. Otherwise | |
750 | * <code>true</code> if and only if the value of {@link | |
751 | * LargeBlobAuthenticationInput#getWrite()} was successfully stored by the authenticator. | |
752 | * @see <a | |
753 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-authenticationextensionslargebloboutputs-written">§10.5. | |
754 | * Large blob storage extension (largeBlob)</a> | |
755 | */ | |
756 | public Optional<Boolean> getWritten() { | |
757 |
1
1. getWritten : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$LargeBlob$LargeBlobAuthenticationOutput::getWritten → KILLED |
return Optional.ofNullable(written); |
758 | } | |
759 | } | |
760 | } | |
761 | ||
762 | /** | |
763 | * Definitions for the Pseudo-random function extension (<code>prf</code>). | |
764 | * | |
765 | * @since 2.7.0 | |
766 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
767 | * Pseudo-random function extension (prf)</a> | |
768 | */ | |
769 | public static class Prf { | |
770 | static final String EXTENSION_ID = "prf"; | |
771 | ||
772 | /** | |
773 | * One or two inputs to or outputs from the pseudo-random function (PRF) associated with a | |
774 | * credential. | |
775 | * | |
776 | * <p>{@link #getFirst()} is always present, but {@link #getSecond()} is empty when only one | |
777 | * input or output was given. | |
778 | * | |
779 | * @since 2.7.0 | |
780 | * @see #one(ByteArray) | |
781 | * @see #two(ByteArray, ByteArray) | |
782 | * @see #oneOrTwo(ByteArray, Optional) | |
783 | * @see <a | |
784 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfvalues">dictionary | |
785 | * AuthenticationExtensionsPRFValues</a> | |
786 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
787 | * Pseudo-random function extension (prf)</a> | |
788 | */ | |
789 | @Value | |
790 | public static class PrfValues { | |
791 | /** | |
792 | * The first PRF input to evaluate, or the result of that evaluation. | |
793 | * | |
794 | * @since 2.7.0 | |
795 | * @see <a | |
796 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfvalues-first">AuthenticationExtensionsPRFValues.first</a> | |
797 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
798 | * Pseudo-random function extension (prf)</a> | |
799 | */ | |
800 | @JsonProperty @NonNull private final ByteArray first; | |
801 | ||
802 | /** | |
803 | * The second PRF input to evaluate, if any, or the result of that evaluation. | |
804 | * | |
805 | * @since 2.7.0 | |
806 | * @see <a | |
807 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfvalues-second">AuthenticationExtensionsPRFValues.second</a> | |
808 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
809 | * Pseudo-random function extension (prf)</a> | |
810 | */ | |
811 | @JsonProperty private final ByteArray second; | |
812 | ||
813 | @JsonCreator | |
814 | private PrfValues( | |
815 |
1
1. <init> : negated conditional → KILLED |
@JsonProperty("first") @NonNull final ByteArray first, |
816 | @JsonProperty("second") final ByteArray second) { | |
817 | this.first = first; | |
818 | this.second = second; | |
819 | } | |
820 | ||
821 | /** | |
822 | * The second PRF input to evaluate, if any, or the result of that evaluation. | |
823 | * | |
824 | * @since 2.7.0 | |
825 | * @see <a | |
826 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfvalues-second">AuthenticationExtensionsPRFValues.second</a> | |
827 | */ | |
828 | public Optional<ByteArray> getSecond() { | |
829 |
1
1. getSecond : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfValues::getSecond → KILLED |
return Optional.ofNullable(second); |
830 | } | |
831 | ||
832 | /** | |
833 | * Construct a {@link PrfValues} with a single PRF input or output. | |
834 | * | |
835 | * @param first the PRF input or output. Must not be null. | |
836 | * @since 2.7.0 | |
837 | * @see <a | |
838 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfvalues">dictionary | |
839 | * AuthenticationExtensionsPRFValues</a> | |
840 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
841 | * Pseudo-random function extension (prf)</a> | |
842 | */ | |
843 |
1
1. one : negated conditional → KILLED |
public static PrfValues one(@NonNull ByteArray first) { |
844 |
1
1. one : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfValues::one → KILLED |
return new PrfValues(first, null); |
845 | } | |
846 | ||
847 | /** | |
848 | * Construct a {@link PrfValues} with two PRF inputs or outputs. | |
849 | * | |
850 | * @param first the first PRF input or output. Must not be null. | |
851 | * @param second the second PRF input or output. Must not be null. | |
852 | * @since 2.7.0 | |
853 | * @see <a | |
854 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfvalues">dictionary | |
855 | * AuthenticationExtensionsPRFValues</a> | |
856 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
857 | * Pseudo-random function extension (prf)</a> | |
858 | */ | |
859 |
2
1. two : negated conditional → KILLED 2. two : negated conditional → KILLED |
public static PrfValues two(@NonNull ByteArray first, @NonNull ByteArray second) { |
860 |
1
1. two : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfValues::two → KILLED |
return new PrfValues(first, second); |
861 | } | |
862 | ||
863 | /** | |
864 | * Construct a {@link PrfValues} with two PRF inputs or outputs if <code>second</code> is | |
865 | * present, otherwise a {@link PrfValues} with one inputs or output. | |
866 | * | |
867 | * @param first the first PRF input or output. Must not be null. | |
868 | * @param second the second PRF input or output, if any. Must not be null, but may be empty. | |
869 | * @since 2.7.0 | |
870 | * @see <a | |
871 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfvalues">dictionary | |
872 | * AuthenticationExtensionsPRFValues</a> | |
873 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
874 | * Pseudo-random function extension (prf)</a> | |
875 | */ | |
876 | public static PrfValues oneOrTwo( | |
877 |
2
1. oneOrTwo : negated conditional → KILLED 2. oneOrTwo : negated conditional → KILLED |
@NonNull ByteArray first, @NonNull Optional<ByteArray> second) { |
878 |
1
1. oneOrTwo : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfValues::oneOrTwo → KILLED |
return new PrfValues(first, second.orElse(null)); |
879 | } | |
880 | } | |
881 | ||
882 | /** | |
883 | * Inputs for the Pseudo-random function extension (<code>prf</code>) in registration | |
884 | * ceremonies. | |
885 | * | |
886 | * @since 2.7.0 | |
887 | * @see <a | |
888 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfinputs">dictionary | |
889 | * AuthenticationExtensionsPRFInputs</a> | |
890 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
891 | * Pseudo-random function extension (prf)</a> | |
892 | */ | |
893 | @Value | |
894 | public static class PrfRegistrationInput { | |
895 | /** | |
896 | * PRF inputs to evaluate immediately if possible. Note that not all authenticators support | |
897 | * this, in which case a follow-up authentication ceremony may be needed in order to evaluate | |
898 | * the PRF. | |
899 | * | |
900 | * @since 2.7.0 | |
901 | * @see #eval(PrfValues) | |
902 | * @see <a | |
903 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
904 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
905 | * Pseudo-random function extension (prf)</a> | |
906 | */ | |
907 | @JsonProperty private final PrfValues eval; | |
908 | ||
909 | @JsonCreator | |
910 | private PrfRegistrationInput(@JsonProperty("eval") PrfValues eval) { | |
911 | this.eval = eval; | |
912 | } | |
913 | ||
914 | /** | |
915 | * PRF inputs to evaluate immediately if possible. Note that not all authenticators support | |
916 | * this, in which case a follow-up authentication ceremony may be needed in order to evaluate | |
917 | * the PRF. | |
918 | * | |
919 | * @since 2.7.0 | |
920 | * @see #eval(PrfValues) | |
921 | * @see <a | |
922 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
923 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
924 | * Pseudo-random function extension (prf)</a> | |
925 | */ | |
926 | public Optional<PrfValues> getEval() { | |
927 |
1
1. getEval : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfRegistrationInput::getEval → KILLED |
return Optional.ofNullable(eval); |
928 | } | |
929 | ||
930 | /** | |
931 | * Enable PRF for the created credential, without evaluating the PRF at this time. | |
932 | * | |
933 | * @since 2.7.0 | |
934 | * @see #eval(PrfValues) | |
935 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
936 | * Pseudo-random function extension (prf)</a> | |
937 | */ | |
938 | public static PrfRegistrationInput enable() { | |
939 |
1
1. enable : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfRegistrationInput::enable → KILLED |
return new PrfRegistrationInput(null); |
940 | } | |
941 | ||
942 | /** | |
943 | * Enable PRF for the created credential, and attempt to immediately evaluate the PRF with the | |
944 | * given inputs. Note that not all authenticators support this, in which case a follow-up | |
945 | * authentication ceremony may be needed in order to evaluate the PRF. | |
946 | * | |
947 | * @since 2.7.0 | |
948 | * @see #enable() | |
949 | * @see #getEval() | |
950 | * @see <a | |
951 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
952 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
953 | * Pseudo-random function extension (prf)</a> | |
954 | */ | |
955 |
1
1. eval : negated conditional → KILLED |
public static PrfRegistrationInput eval(@NonNull PrfValues eval) { |
956 |
1
1. eval : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfRegistrationInput::eval → KILLED |
return new PrfRegistrationInput(eval); |
957 | } | |
958 | } | |
959 | ||
960 | /** | |
961 | * Outputs for the Pseudo-random function extension (<code>prf</code>) in registration | |
962 | * ceremonies. | |
963 | * | |
964 | * @since 2.7.0 | |
965 | * @see <a | |
966 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfoutputs">dictionary | |
967 | * AuthenticationExtensionsPRFOutputs</a> | |
968 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
969 | * Pseudo-random function extension (prf)</a> | |
970 | */ | |
971 | @Value | |
972 | public static class PrfRegistrationOutput { | |
973 | ||
974 | /** | |
975 | * <code>true</code> if, and only if, a PRF is available for use with the created credential. | |
976 | * | |
977 | * @since 2.7.0 | |
978 | * @see <a | |
979 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfoutputs-enabled">AuthenticationExtensionsPRFOutputs.enabled</a> | |
980 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
981 | * Pseudo-random function extension (prf)</a> | |
982 | */ | |
983 | @JsonProperty private final Boolean enabled; | |
984 | ||
985 | /** | |
986 | * The results of evaluating the PRF for the inputs given in {@link | |
987 | * PrfRegistrationInput#getEval() eval}, if any. | |
988 | * | |
989 | * @since 2.7.0 | |
990 | * @see <a | |
991 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfoutputs-results">AuthenticationExtensionsPRFOutputs.results</a> | |
992 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
993 | * Pseudo-random function extension (prf)</a> | |
994 | */ | |
995 | @JsonProperty private final PrfValues results; | |
996 | ||
997 | @JsonCreator | |
998 | PrfRegistrationOutput( | |
999 | @JsonProperty("enabled") Boolean enabled, @JsonProperty("results") PrfValues results) { | |
1000 | this.enabled = enabled; | |
1001 | this.results = results; | |
1002 | } | |
1003 | ||
1004 | /** | |
1005 | * <code>true</code> if, and only if, a PRF is available for use with the created credential. | |
1006 | * | |
1007 | * @since 2.7.0 | |
1008 | * @see <a | |
1009 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfoutputs-enabled">AuthenticationExtensionsPRFOutputs.enabled</a> | |
1010 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1011 | * Pseudo-random function extension (prf)</a> | |
1012 | */ | |
1013 | public Optional<Boolean> getEnabled() { | |
1014 |
1
1. getEnabled : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfRegistrationOutput::getEnabled → NO_COVERAGE |
return Optional.ofNullable(enabled); |
1015 | } | |
1016 | ||
1017 | /** | |
1018 | * The results of evaluating the PRF for the inputs given in {@link | |
1019 | * PrfRegistrationInput#getEval() eval}, if any. | |
1020 | * | |
1021 | * @since 2.7.0 | |
1022 | * @see <a | |
1023 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfoutputs-results">AuthenticationExtensionsPRFOutputs.results</a> | |
1024 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1025 | * Pseudo-random function extension (prf)</a> | |
1026 | */ | |
1027 | public Optional<PrfValues> getResults() { | |
1028 |
1
1. getResults : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfRegistrationOutput::getResults → NO_COVERAGE |
return Optional.ofNullable(results); |
1029 | } | |
1030 | } | |
1031 | ||
1032 | /** | |
1033 | * Inputs for the Pseudo-random function extension (<code>prf</code>) in authentication | |
1034 | * ceremonies. | |
1035 | * | |
1036 | * @since 2.7.0 | |
1037 | * @see <a | |
1038 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfinputs">dictionary | |
1039 | * AuthenticationExtensionsPRFInputs</a> | |
1040 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1041 | * Pseudo-random function extension (prf)</a> | |
1042 | */ | |
1043 | @Value | |
1044 | public static class PrfAuthenticationInput { | |
1045 | /** | |
1046 | * PRF inputs to use for any credential without a dedicated input listed in {@link | |
1047 | * #getEvalByCredential()}. | |
1048 | * | |
1049 | * @since 2.7.0 | |
1050 | * @see #eval(PrfValues) | |
1051 | * @see #evalByCredentialWithFallback(Map, PrfValues) | |
1052 | * @see <a | |
1053 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
1054 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1055 | * Pseudo-random function extension (prf)</a> | |
1056 | */ | |
1057 | @JsonProperty private final PrfValues eval; | |
1058 | ||
1059 | /** | |
1060 | * A map of credential IDs to PRF inputs to use for that credential. Credentials without a | |
1061 | * mapping here fall back to the inputs in {@link #getEval()} if present, otherwise no PRF is | |
1062 | * evaluated for those credentials. | |
1063 | * | |
1064 | * @since 2.7.0 | |
1065 | * @see #evalByCredential(Map) | |
1066 | * @see #evalByCredentialWithFallback(Map, PrfValues) | |
1067 | * @see <a | |
1068 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-evalbycredential">AuthenticationExtensionsPRFInputs.evalByCredential</a> | |
1069 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1070 | * Pseudo-random function extension (prf)</a> | |
1071 | */ | |
1072 | @JsonProperty private final Map<ByteArray, PrfValues> evalByCredential; | |
1073 | ||
1074 | @JsonCreator | |
1075 | private PrfAuthenticationInput( | |
1076 | @JsonProperty("eval") PrfValues eval, | |
1077 | @JsonProperty("evalByCredential") Map<ByteArray, PrfValues> evalByCredential) { | |
1078 | this.eval = eval; | |
1079 | this.evalByCredential = | |
1080 |
1
1. <init> : negated conditional → KILLED |
evalByCredential == null ? null : Collections.unmodifiableMap(evalByCredential); |
1081 | } | |
1082 | ||
1083 | /** | |
1084 | * PRF inputs to use for any credential without a dedicated input listed in {@link | |
1085 | * #getEvalByCredential()}. | |
1086 | * | |
1087 | * @since 2.7.0 | |
1088 | * @see #eval(PrfValues) | |
1089 | * @see #evalByCredentialWithFallback(Map, PrfValues) | |
1090 | * @see <a | |
1091 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
1092 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1093 | * Pseudo-random function extension (prf)</a> | |
1094 | */ | |
1095 | public Optional<PrfValues> getEval() { | |
1096 |
1
1. getEval : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::getEval → KILLED |
return Optional.ofNullable(eval); |
1097 | } | |
1098 | ||
1099 | /** | |
1100 | * A map of credential IDs to PRF inputs to use for that credential. Credentials without a | |
1101 | * mapping here fall back to the inputs in {@link #getEval()} if present, otherwise no PRF is | |
1102 | * evaluated for those credentials. | |
1103 | * | |
1104 | * @since 2.7.0 | |
1105 | * @see #evalByCredential(Map) | |
1106 | * @see #evalByCredentialWithFallback(Map, PrfValues) | |
1107 | * @see <a | |
1108 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-evalbycredential">AuthenticationExtensionsPRFInputs.evalByCredential</a> | |
1109 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1110 | * Pseudo-random function extension (prf)</a> | |
1111 | */ | |
1112 | public Optional<Map<ByteArray, PrfValues>> getEvalByCredential() { | |
1113 |
1
1. getEvalByCredential : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::getEvalByCredential → KILLED |
return Optional.ofNullable(evalByCredential); |
1114 | } | |
1115 | ||
1116 | private static HashMap<ByteArray, PrfValues> descriptorsToIds( | |
1117 | Map<PublicKeyCredentialDescriptor, PrfValues> evalByCredential) { | |
1118 |
1
1. descriptorsToIds : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::descriptorsToIds → KILLED |
return evalByCredential.entrySet().stream() |
1119 | .reduce( | |
1120 | new HashMap<>(), | |
1121 | (ebc, entry) -> { | |
1122 | ebc.put(entry.getKey().getId(), entry.getValue()); | |
1123 |
1
1. lambda$descriptorsToIds$0 : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::lambda$descriptorsToIds$0 → KILLED |
return ebc; |
1124 | }, | |
1125 | (a, b) -> { | |
1126 |
1
1. lambda$descriptorsToIds$1 : removed call to java/util/HashMap::putAll → NO_COVERAGE |
a.putAll(b); |
1127 |
1
1. lambda$descriptorsToIds$1 : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::lambda$descriptorsToIds$1 → NO_COVERAGE |
return a; |
1128 | }); | |
1129 | } | |
1130 | ||
1131 | /** | |
1132 | * Use the same PRF inputs for all credentials. | |
1133 | * | |
1134 | * @since 2.7.0 | |
1135 | * @see #getEval() | |
1136 | * @see <a | |
1137 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
1138 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1139 | * Pseudo-random function extension (prf)</a> | |
1140 | */ | |
1141 |
1
1. eval : negated conditional → KILLED |
public static PrfAuthenticationInput eval(@NonNull PrfValues eval) { |
1142 |
1
1. eval : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::eval → KILLED |
return new PrfAuthenticationInput(eval, null); |
1143 | } | |
1144 | ||
1145 | /** | |
1146 | * Use different PRF inputs for different credentials, and skip PRF evaluation for any | |
1147 | * credentials not present in the map. | |
1148 | * | |
1149 | * @since 2.7.0 | |
1150 | * @see #getEvalByCredential() | |
1151 | * @see <a | |
1152 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-evalbycredential">AuthenticationExtensionsPRFInputs.evalByCredential</a> | |
1153 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1154 | * Pseudo-random function extension (prf)</a> | |
1155 | */ | |
1156 | public static PrfAuthenticationInput evalByCredential( | |
1157 |
1
1. evalByCredential : negated conditional → KILLED |
@NonNull Map<PublicKeyCredentialDescriptor, PrfValues> evalByCredential) { |
1158 |
1
1. evalByCredential : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::evalByCredential → KILLED |
return new PrfAuthenticationInput(null, descriptorsToIds(evalByCredential)); |
1159 | } | |
1160 | ||
1161 | /** | |
1162 | * Use different PRF inputs for different credentials, and "fallback" inputs for any | |
1163 | * credentials not present in the map. | |
1164 | * | |
1165 | * @param evalByCredential a map of credential IDs to PRF inputs to use for that credential. | |
1166 | * @param eval "fallback" inputs to use for any credential not listed in <code> | |
1167 | * evalByCredential</code>. | |
1168 | * @since 2.7.0 | |
1169 | * @see #getEvalByCredential() | |
1170 | * @see #getEval() () | |
1171 | * @see <a | |
1172 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-evalbycredential">AuthenticationExtensionsPRFInputs.evalByCredential</a> | |
1173 | * @see <a | |
1174 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfinputs-eval">AuthenticationExtensionsPRFInputs.eval</a> | |
1175 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1176 | * Pseudo-random function extension (prf)</a> | |
1177 | */ | |
1178 | public static PrfAuthenticationInput evalByCredentialWithFallback( | |
1179 |
1
1. evalByCredentialWithFallback : negated conditional → KILLED |
@NonNull Map<PublicKeyCredentialDescriptor, PrfValues> evalByCredential, |
1180 |
1
1. evalByCredentialWithFallback : negated conditional → KILLED |
@NonNull PrfValues eval) { |
1181 |
1
1. evalByCredentialWithFallback : replaced return value with null for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationInput::evalByCredentialWithFallback → KILLED |
return new PrfAuthenticationInput(eval, descriptorsToIds(evalByCredential)); |
1182 | } | |
1183 | } | |
1184 | ||
1185 | /** | |
1186 | * Outputs for the Pseudo-random function extension (<code>prf</code>) in authentication | |
1187 | * ceremonies. | |
1188 | * | |
1189 | * @since 2.7.0 | |
1190 | * @see <a | |
1191 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dictdef-authenticationextensionsprfoutputs">dictionary | |
1192 | * AuthenticationExtensionsPRFOutputs</a> | |
1193 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1194 | * Pseudo-random function extension (prf)</a> | |
1195 | */ | |
1196 | @Value | |
1197 | public static class PrfAuthenticationOutput { | |
1198 | ||
1199 | /** | |
1200 | * The results of evaluating the PRF for the inputs given in {@link | |
1201 | * PrfAuthenticationInput#getEval() eval} or {@link | |
1202 | * PrfAuthenticationInput#getEvalByCredential() evalByCredential}, if any. | |
1203 | * | |
1204 | * @since 2.7.0 | |
1205 | * @see <a | |
1206 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfoutputs-results">AuthenticationExtensionsPRFOutputs.results</a> | |
1207 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1208 | * Pseudo-random function extension (prf)</a> | |
1209 | */ | |
1210 | @JsonProperty private final PrfValues results; | |
1211 | ||
1212 | @JsonCreator | |
1213 | PrfAuthenticationOutput(@JsonProperty("results") PrfValues results) { | |
1214 | this.results = results; | |
1215 | } | |
1216 | ||
1217 | /** | |
1218 | * The results of evaluating the PRF for the inputs given in {@link | |
1219 | * PrfAuthenticationInput#getEval() eval} or {@link | |
1220 | * PrfAuthenticationInput#getEvalByCredential() evalByCredential}, if any. | |
1221 | * | |
1222 | * @since 2.7.0 | |
1223 | * @see <a | |
1224 | * href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#dom-authenticationextensionsprfoutputs-results">AuthenticationExtensionsPRFOutputs.results</a> | |
1225 | * @see <a href="https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#prf-extension">§10.1.4. | |
1226 | * Pseudo-random function extension (prf)</a> | |
1227 | */ | |
1228 | public Optional<PrfValues> getResults() { | |
1229 |
1
1. getResults : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Prf$PrfAuthenticationOutput::getResults → NO_COVERAGE |
return Optional.ofNullable(results); |
1230 | } | |
1231 | } | |
1232 | } | |
1233 | ||
1234 | /** | |
1235 | * Definitions for the User Verification Method (<code>uvm</code>) Extension. | |
1236 | * | |
1237 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3. | |
1238 | * User Verification Method Extension (uvm)</a> | |
1239 | */ | |
1240 | public static class Uvm { | |
1241 | static final String EXTENSION_ID = "uvm"; | |
1242 | ||
1243 | /** | |
1244 | * A <code>uvmEntry</code> as defined in <a | |
1245 | * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3. User | |
1246 | * Verification Method Extension (uvm)</a>. | |
1247 | * | |
1248 | * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-uvm-extension">§10.3. | |
1249 | * User Verification Method Extension (uvm)</a> | |
1250 | * @see UserVerificationMethod | |
1251 | * @see KeyProtectionType | |
1252 | * @see MatcherProtectionType | |
1253 | */ | |
1254 | @Value | |
1255 | public static class UvmEntry { | |
1256 | private final UserVerificationMethod userVerificationMethod; | |
1257 | private final KeyProtectionType keyProtectionType; | |
1258 | private final MatcherProtectionType matcherProtectionType; | |
1259 | ||
1260 | public UvmEntry( | |
1261 | @JsonProperty("userVerificationMethod") UserVerificationMethod userVerificationMethod, | |
1262 | @JsonProperty("keyProtectionType") KeyProtectionType keyProtectionType, | |
1263 | @JsonProperty("matcherProtectionType") MatcherProtectionType matcherProtectionType) { | |
1264 | this.userVerificationMethod = userVerificationMethod; | |
1265 | this.keyProtectionType = keyProtectionType; | |
1266 | this.matcherProtectionType = matcherProtectionType; | |
1267 | } | |
1268 | } | |
1269 | ||
1270 | static Optional<List<UvmEntry>> parseAuthenticatorExtensionOutput(CBORObject cbor) { | |
1271 |
1
1. parseAuthenticatorExtensionOutput : negated conditional → KILLED |
if (validateAuthenticatorExtensionOutput(cbor)) { |
1272 |
1
1. parseAuthenticatorExtensionOutput : replaced return value with Optional.empty for com/yubico/webauthn/data/Extensions$Uvm::parseAuthenticatorExtensionOutput → KILLED |
return Optional.of( |
1273 | cbor.get(EXTENSION_ID).getValues().stream() | |
1274 | .map( | |
1275 | uvmEntry -> | |
1276 |
1
1. lambda$parseAuthenticatorExtensionOutput$0 : replaced return value with null for com/yubico/webauthn/data/Extensions$Uvm::lambda$parseAuthenticatorExtensionOutput$0 → KILLED |
new UvmEntry( |
1277 | UserVerificationMethod.fromValue(uvmEntry.get(0).AsInt32Value()), | |
1278 | KeyProtectionType.fromValue( | |
1279 | uvmEntry.get(1).AsNumber().ToInt16IfExact()), | |
1280 | MatcherProtectionType.fromValue( | |
1281 | uvmEntry.get(2).AsNumber().ToInt16IfExact()))) | |
1282 | .collect(Collectors.toList())); | |
1283 | } else { | |
1284 | return Optional.empty(); | |
1285 | } | |
1286 | } | |
1287 | ||
1288 | private static boolean validateAuthenticatorExtensionOutput(CBORObject extensions) { | |
1289 |
1
1. validateAuthenticatorExtensionOutput : negated conditional → KILLED |
if (!extensions.ContainsKey(EXTENSION_ID)) { |
1290 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → KILLED |
return false; |
1291 | } | |
1292 | ||
1293 | CBORObject uvm = extensions.get(EXTENSION_ID); | |
1294 |
1
1. validateAuthenticatorExtensionOutput : negated conditional → KILLED |
if (uvm.getType() != CBORType.Array) { |
1295 | log.debug( | |
1296 | "Invalid CBOR type for \"{}\" extension output: expected array, was: {}", | |
1297 | EXTENSION_ID, | |
1298 | uvm.getType()); | |
1299 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE |
return false; |
1300 | } | |
1301 | ||
1302 |
4
1. validateAuthenticatorExtensionOutput : changed conditional boundary → SURVIVED 2. validateAuthenticatorExtensionOutput : changed conditional boundary → SURVIVED 3. validateAuthenticatorExtensionOutput : negated conditional → KILLED 4. validateAuthenticatorExtensionOutput : negated conditional → KILLED |
if (uvm.size() < 1 || uvm.size() > 3) { |
1303 | log.debug( | |
1304 | "Invalid length \"{}\" extension output array: expected 1 to 3 (inclusive), was: {}", | |
1305 | EXTENSION_ID, | |
1306 | uvm.size()); | |
1307 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE |
return false; |
1308 | } | |
1309 | ||
1310 | for (CBORObject entry : uvm.getValues()) { | |
1311 |
1
1. validateAuthenticatorExtensionOutput : negated conditional → KILLED |
if (entry.getType() != CBORType.Array) { |
1312 | log.debug("Invalid CBOR type for uvmEntry: expected array, was: {}", entry.getType()); | |
1313 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE |
return false; |
1314 | } | |
1315 | ||
1316 |
1
1. validateAuthenticatorExtensionOutput : negated conditional → KILLED |
if (entry.size() != 3) { |
1317 | log.debug("Invalid length for uvmEntry: expected 3, was: {}", entry.size()); | |
1318 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE |
return false; |
1319 | } | |
1320 | ||
1321 | for (CBORObject i : entry.getValues()) { | |
1322 |
2
1. validateAuthenticatorExtensionOutput : negated conditional → KILLED 2. validateAuthenticatorExtensionOutput : negated conditional → KILLED |
if (!(i.isNumber() && i.AsNumber().IsInteger())) { |
1323 | log.debug("Invalid type for uvmEntry element: expected integer, was: {}", i.getType()); | |
1324 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with true for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → NO_COVERAGE |
return false; |
1325 | } | |
1326 | } | |
1327 | } | |
1328 | ||
1329 |
1
1. validateAuthenticatorExtensionOutput : replaced boolean return with false for com/yubico/webauthn/data/Extensions$Uvm::validateAuthenticatorExtensionOutput → KILLED |
return true; |
1330 | } | |
1331 | } | |
1332 | } | |
Mutations | ||
115 |
1.1 |
|
205 |
1.1 |
|
206 |
1.1 2.2 |
|
211 |
1.1 |
|
212 |
1.1 2.2 |
|
217 |
1.1 |
|
218 |
1.1 |
|
221 |
1.1 |
|
281 |
1.1 |
|
282 |
1.1 |
|
309 |
1.1 |
|
310 |
1.1 |
|
339 |
1.1 |
|
340 |
1.1 |
|
399 |
1.1 |
|
401 |
1.1 |
|
402 |
1.1 |
|
410 |
1.1 |
|
421 |
1.1 |
|
424 |
1.1 2.2 3.3 |
|
427 |
1.1 |
|
532 |
1.1 |
|
574 |
1.1 2.2 3.3 |
|
579 |
1.1 2.2 |
|
594 |
1.1 |
|
607 |
1.1 |
|
608 |
1.1 |
|
620 |
1.1 2.2 |
|
631 |
1.1 |
|
671 |
1.1 |
|
707 |
1.1 |
|
723 |
1.1 |
|
740 |
1.1 |
|
757 |
1.1 |
|
815 |
1.1 |
|
829 |
1.1 |
|
843 |
1.1 |
|
844 |
1.1 |
|
859 |
1.1 2.2 |
|
860 |
1.1 |
|
877 |
1.1 2.2 |
|
878 |
1.1 |
|
927 |
1.1 |
|
939 |
1.1 |
|
955 |
1.1 |
|
956 |
1.1 |
|
1014 |
1.1 |
|
1028 |
1.1 |
|
1080 |
1.1 |
|
1096 |
1.1 |
|
1113 |
1.1 |
|
1118 |
1.1 |
|
1123 |
1.1 |
|
1126 |
1.1 |
|
1127 |
1.1 |
|
1141 |
1.1 |
|
1142 |
1.1 |
|
1157 |
1.1 |
|
1158 |
1.1 |
|
1179 |
1.1 |
|
1180 |
1.1 |
|
1181 |
1.1 |
|
1229 |
1.1 |
|
1271 |
1.1 |
|
1272 |
1.1 |
|
1276 |
1.1 |
|
1289 |
1.1 |
|
1290 |
1.1 |
|
1294 |
1.1 |
|
1299 |
1.1 |
|
1302 |
1.1 2.2 3.3 4.4 |
|
1307 |
1.1 |
|
1311 |
1.1 |
|
1313 |
1.1 |
|
1316 |
1.1 |
|
1318 |
1.1 |
|
1322 |
1.1 2.2 |
|
1324 |
1.1 |
|
1329 |
1.1 |