From 1980c456483da2b926111a6c18bb896fac5ab96e Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 24 Nov 2022 15:45:40 +0100 Subject: [PATCH 01/17] Fix typo in NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5bc9ea9a3..3cc5ee846 100644 --- a/NEWS +++ b/NEWS @@ -44,7 +44,7 @@ Fixes: Fixes: -* Improved documentation of guaranteed provided by `FidoMetadataDownloader` and +* Improved documentation of guarantees provided by `FidoMetadataDownloader` and required of its parameters. From 608ca95da5fd86a2e75fcc23b0d8433c61784c61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Nov 2022 13:00:46 +0000 Subject: [PATCH 02/17] Bump spotless-plugin-gradle from 6.11.0 to 6.12.0 Bumps [spotless-plugin-gradle](https://github.com/diffplug/spotless) from 6.11.0 to 6.12.0. - [Release notes](https://github.com/diffplug/spotless/releases) - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md) - [Commits](https://github.com/diffplug/spotless/compare/gradle/6.11.0...gradle/6.12.0) --- updated-dependencies: - dependency-name: com.diffplug.spotless:spotless-plugin-gradle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ff23a4ccb..7a1772428 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { } dependencies { classpath 'com.cinnober.gradle:semver-git:2.5.0' - classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.11.0' + classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.12.0' classpath 'io.github.cosmicsilence:gradle-scalafix:0.1.13' } } From 4bd83005d69e1b8f887eaf29d1d0d884ad6794ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Nov 2022 13:00:43 +0000 Subject: [PATCH 03/17] Bump gradle-pitest-plugin from 1.9.0 to 1.9.11 Bumps [gradle-pitest-plugin](https://github.com/szpak/gradle-pitest-plugin) from 1.9.0 to 1.9.11. - [Release notes](https://github.com/szpak/gradle-pitest-plugin/releases) - [Changelog](https://github.com/szpak/gradle-pitest-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/szpak/gradle-pitest-plugin/compare/release/1.9.0...release/1.9.11) --- updated-dependencies: - dependency-name: info.solidsoft.gradle.pitest:gradle-pitest-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 7dc1ca3f0..c55c2e01c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -7,5 +7,5 @@ repositories { } dependencies { - implementation("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.9.0") + implementation("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.9.11") } From 4f4332bbc2674662261aa6f06bad80a2ca7b276a Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 15 Dec 2022 17:12:04 +0100 Subject: [PATCH 04/17] Fix typos in README --- README | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index 8b136845d..7a00cddf2 100644 --- a/README +++ b/README @@ -129,12 +129,12 @@ The server side involves: 3. Use the link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#startRegistration(com.yubico.webauthn.StartRegistrationOptions)[`RelyingParty.startRegistration(...)`] and - link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.fininshRegistration(...)`] + link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.finishRegistration(...)`] methods to perform registration ceremonies. 4. Use the link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#startAssertion(com.yubico.webauthn.StartAssertionOptions)[`RelyingParty.startAssertion(...)`] and - link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.fininshAssertion(...)`] + link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.finishAssertion(...)`] methods to perform authentication ceremonies. 5. Use the outputs of `finishRegistration` and `finishAssertion` to update your database, initiate sessions, etc. @@ -197,7 +197,7 @@ A registration ceremony consists of 5 main steps: and https://www.w3.org/TR/webauthn-2/#ref-for-dom-authenticatorattestationresponse-gettransports[`cred.response.getTransports()`] and return their results along with `cred` to the server. 4. Validate the response using - link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.fininshRegistration(...)`]. + link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.finishRegistration(...)`]. 5. Update your database using the `finishRegistration` output. This example uses GitHub's link:https://github.com/github/webauthn-json[webauthn-json] library to do both (2) and (3) in one function call. @@ -232,7 +232,7 @@ You will need to keep this link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html[`PublicKeyCredentialCreationOptions`] object in temporary storage so you can also pass it into -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.fininshRegistration(...)`] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.finishRegistration(...)`] later. If needed, you can use the link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html#toJson()[toJson()] @@ -303,7 +303,7 @@ Like registration ceremonies, an authentication ceremony consists of 5 main step https://www.w3.org/TR/webauthn-2/#ref-for-dom-publickeycredential-getclientextensionresults[`cred.getClientExtensionResults()`] and return the result along with `cred` to the server. 4. Validate the response using - link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.fininshAssertion(...)`]. + link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.finishAssertion(...)`]. 5. Update your database using the `finishAssertion` output, and act upon the result (for example, grant login access). This example uses GitHub's link:https://github.com/github/webauthn-json[webauthn-json] library to do both (2) and (3) in one function call. @@ -323,7 +323,7 @@ Again, you will need to keep this link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/AssertionRequest.html[`AssertionRequest`] object in temporary storage so you can also pass it into -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.fininshAssertion(...)`] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.finishAssertion(...)`] later. If needed, you can use the link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/AssertionRequest.html#toJson()[toJson()] @@ -433,7 +433,7 @@ AssertionRequest request = rp.startAssertion(StartAssertionOptions.builder() ---------- Then -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.fininshAssertion(...)`] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.finishAssertion(...)`] will enforce that user verification was performed. However, there is no guarantee that the user's authenticator will support this unless the user has some credential created with the From 15e9108ccd9e04c7ad729254b7b52bb170696d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Gon=C3=A7alves?= Date: Fri, 16 Dec 2022 08:12:24 +0000 Subject: [PATCH 05/17] Support authenticatorAttachment in PublicKeyCredential --- .../com/yubico/webauthn/AssertionResult.java | 14 +++++++++ .../yubico/webauthn/RegistrationResult.java | 14 +++++++++ .../webauthn/data/PublicKeyCredential.java | 22 +++++++++++-- .../webauthn/RelyingPartyAssertionSpec.scala | 31 +++++++++++++++++++ .../RelyingPartyRegistrationSpec.scala | 28 +++++++++++++++++ 5 files changed, 106 insertions(+), 3 deletions(-) diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java index b42ff37f9..f12297400 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java @@ -29,6 +29,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.yubico.webauthn.data.AuthenticatorAssertionExtensionOutputs; import com.yubico.webauthn.data.AuthenticatorAssertionResponse; +import com.yubico.webauthn.data.AuthenticatorAttachment; import com.yubico.webauthn.data.AuthenticatorData; import com.yubico.webauthn.data.ByteArray; import com.yubico.webauthn.data.ClientAssertionExtensionOutputs; @@ -195,6 +196,19 @@ public boolean isBackedUp() { return credentialResponse.getResponse().getParsedAuthenticatorData().getFlags().BS; } + /** + * The authenticator + * attachment modality in effect at the time the asserted credential was used. + * + * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as + * the standard matures. + */ + @Deprecated + @JsonIgnore + public Optional getAuthenticatorAttachment() { + return credentialResponse.getAuthenticatorAttachment(); + } + /** * The new signature * count of the credential used for the assertion. diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java index 88bbcfdbb..0e6d24c56 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java @@ -31,6 +31,7 @@ import com.yubico.webauthn.RelyingParty.RelyingPartyBuilder; import com.yubico.webauthn.attestation.AttestationTrustSource; import com.yubico.webauthn.data.AttestationType; +import com.yubico.webauthn.data.AuthenticatorAttachment; import com.yubico.webauthn.data.AuthenticatorAttestationResponse; import com.yubico.webauthn.data.AuthenticatorRegistrationExtensionOutputs; import com.yubico.webauthn.data.ByteArray; @@ -175,6 +176,19 @@ public boolean isBackedUp() { return credential.getResponse().getParsedAuthenticatorData().getFlags().BS; } + /** + * The authenticator + * attachment modality in effect at the time the credential was created. + * + * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as + * the standard matures. + */ + @Deprecated + @JsonIgnore + public Optional getAuthenticatorAttachment() { + return credential.getAuthenticatorAttachment(); + } + /** * The signature count returned with the created credential. * diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java index 3141912ca..fa34e10f6 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java @@ -25,11 +25,11 @@ package com.yubico.webauthn.data; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.yubico.internal.util.JacksonCodecs; import java.io.IOException; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.NonNull; @@ -46,7 +46,6 @@ */ @Value @Builder(toBuilder = true) -@JsonIgnoreProperties({"authenticatorAttachment"}) public class PublicKeyCredential< A extends AuthenticatorResponse, B extends ClientExtensionOutputs> { @@ -68,6 +67,8 @@ public class PublicKeyCredential< */ @NonNull private final A response; + private final AuthenticatorAttachment authenticatorAttachment; + /** * A map containing extension identifier → client extension output entries produced by the * extension’s client extension processing. @@ -83,6 +84,7 @@ private PublicKeyCredential( @JsonProperty("id") ByteArray id, @JsonProperty("rawId") ByteArray rawId, @NonNull @JsonProperty("response") A response, + @JsonProperty("authenticatorAttachment") AuthenticatorAttachment authenticatorAttachment, @NonNull @JsonProperty("clientExtensionResults") B clientExtensionResults, @NonNull @JsonProperty("type") PublicKeyCredentialType type) { if (id == null && rawId == null) { @@ -95,6 +97,7 @@ private PublicKeyCredential( this.id = id == null ? rawId : id; this.response = response; + this.authenticatorAttachment = authenticatorAttachment; this.clientExtensionResults = clientExtensionResults; this.type = type; } @@ -102,9 +105,22 @@ private PublicKeyCredential( private PublicKeyCredential( ByteArray id, @NonNull A response, + AuthenticatorAttachment authenticatorAttachment, @NonNull B clientExtensionResults, @NonNull PublicKeyCredentialType type) { - this(id, null, response, clientExtensionResults, type); + this(id, null, response, authenticatorAttachment, clientExtensionResults, type); + } + + /** + * The authenticator + * attachment modality in effect at the time the credential was used. + * + * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as + * the standard matures. + */ + @Deprecated + public Optional getAuthenticatorAttachment() { + return Optional.ofNullable(authenticatorAttachment); } public static diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala index 8f9e309c7..f817ad746 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala @@ -31,6 +31,7 @@ import com.upokecenter.cbor.CBORObject import com.yubico.internal.util.JacksonCodecs import com.yubico.webauthn.data.AssertionExtensionInputs import com.yubico.webauthn.data.AuthenticatorAssertionResponse +import com.yubico.webauthn.data.AuthenticatorAttachment import com.yubico.webauthn.data.AuthenticatorDataFlags import com.yubico.webauthn.data.AuthenticatorTransport import com.yubico.webauthn.data.ByteArray @@ -2592,6 +2593,36 @@ class RelyingPartyAssertionSpec resultWithBeOnly.isBackedUp should be(false) resultWithBackup.isBackedUp should be(true) } + + it( + "exposes getAuthenticatorAttachment() with the authenticatorAttachment value from the PublicKeyCredential." + ) { + val pkcTemplate = + TestAuthenticator.createAssertion( + challenge = + request.getPublicKeyCredentialRequestOptions.getChallenge, + credentialKey = credentialKeypair, + credentialId = credential.getId, + ) + + forAll { authenticatorAttachment: Option[AuthenticatorAttachment] => + val pkc = pkcTemplate.toBuilder + .authenticatorAttachment(authenticatorAttachment.orNull) + .build() + + val result = rp.finishAssertion( + FinishAssertionOptions + .builder() + .request(request) + .response(pkc) + .build() + ) + + result.getAuthenticatorAttachment should equal( + pkc.getAuthenticatorAttachment + ) + } + } } } } diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala index 983cd281d..a737f23b4 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala @@ -42,6 +42,7 @@ import com.yubico.webauthn.attestation.AttestationTrustSource import com.yubico.webauthn.attestation.AttestationTrustSource.TrustRootsResult import com.yubico.webauthn.data.AttestationObject import com.yubico.webauthn.data.AttestationType +import com.yubico.webauthn.data.AuthenticatorAttachment import com.yubico.webauthn.data.AuthenticatorAttestationResponse import com.yubico.webauthn.data.AuthenticatorData import com.yubico.webauthn.data.AuthenticatorDataFlags @@ -4619,6 +4620,33 @@ class RelyingPartyRegistrationSpec resultWithBeOnly.isBackedUp should be(false) resultWithBackup.isBackedUp should be(true) } + + it( + "exposes getAuthenticatorAttachment() with the authenticatorAttachment value from the PublicKeyCredential." + ) { + val (pkcTemplate, _, _) = + TestAuthenticator.createUnattestedCredential(challenge = + request.getChallenge + ) + + forAll { authenticatorAttachment: Option[AuthenticatorAttachment] => + val pkc = pkcTemplate.toBuilder + .authenticatorAttachment(authenticatorAttachment.orNull) + .build() + + val result = rp.finishRegistration( + FinishRegistrationOptions + .builder() + .request(request) + .response(pkc) + .build() + ) + + result.getAuthenticatorAttachment should equal( + pkc.getAuthenticatorAttachment + ) + } + } } } From c41bcdbd33d602dcf08ff9ff7c60658043abf8d2 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 16 Dec 2022 16:00:49 +0100 Subject: [PATCH 06/17] Add JavaDoc cross-references between getAuthenticatorAttachment() methods --- .../com/yubico/webauthn/AssertionResult.java | 1 + .../yubico/webauthn/RegistrationResult.java | 1 + .../webauthn/data/PublicKeyCredential.java | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java index f12297400..f426943f1 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/AssertionResult.java @@ -200,6 +200,7 @@ public boolean isBackedUp() { * The authenticator * attachment modality in effect at the time the asserted credential was used. * + * @see PublicKeyCredential#getAuthenticatorAttachment() * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as * the standard matures. */ diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java index 0e6d24c56..73c8d6e14 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java @@ -180,6 +180,7 @@ public boolean isBackedUp() { * The authenticator * attachment modality in effect at the time the credential was created. * + * @see PublicKeyCredential#getAuthenticatorAttachment() * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as * the standard matures. */ diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java index fa34e10f6..ee0b5a38e 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredential.java @@ -28,6 +28,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.yubico.internal.util.JacksonCodecs; +import com.yubico.webauthn.AssertionResult; +import com.yubico.webauthn.FinishAssertionOptions; +import com.yubico.webauthn.FinishRegistrationOptions; +import com.yubico.webauthn.RegistrationResult; +import com.yubico.webauthn.RelyingParty; import java.io.IOException; import java.util.Optional; import lombok.AllArgsConstructor; @@ -113,8 +118,19 @@ private PublicKeyCredential( /** * The authenticator - * attachment modality in effect at the time the credential was used. + * attachment modality in effect at the time the credential was created or used. * + *

If parsed from JSON, this will be present if and only if the input was a valid value of + * {@link AuthenticatorAttachment}. + * + *

The same value will also be available via {@link + * RegistrationResult#getAuthenticatorAttachment()} or {@link + * AssertionResult#getAuthenticatorAttachment()} on the result from {@link + * RelyingParty#finishRegistration(FinishRegistrationOptions)} or {@link + * RelyingParty#finishAssertion(FinishAssertionOptions)}. + * + * @see RegistrationResult#getAuthenticatorAttachment() + * @see AssertionResult#getAuthenticatorAttachment() * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as * the standard matures. */ From 8c165d89e90312af86c805c8c311f8a9ce8b4aed Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 16 Dec 2022 16:09:37 +0100 Subject: [PATCH 07/17] Update AuthenticatorAttachment tests --- .../data/AuthenticatorAttachment.java | 13 +----- .../com/yubico/webauthn/data/EnumsSpec.scala | 7 ++- .../com/yubico/webauthn/data/JsonIoSpec.scala | 43 ++++++++++++++++--- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorAttachment.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorAttachment.java index 96c666659..d5d338b42 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorAttachment.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorAttachment.java @@ -26,7 +26,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.Optional; import java.util.stream.Stream; import lombok.AllArgsConstructor; import lombok.Getter; @@ -73,18 +72,8 @@ public enum AuthenticatorAttachment { @JsonValue @Getter @NonNull private final String value; - private static Optional fromString(@NonNull String value) { - return Stream.of(values()).filter(v -> v.value.equals(value)).findAny(); - } - @JsonCreator private static AuthenticatorAttachment fromJsonString(@NonNull String value) { - return fromString(value) - .orElseThrow( - () -> - new IllegalArgumentException( - String.format( - "Unknown %s value: %s", - AuthenticatorAttachment.class.getSimpleName(), value))); + return Stream.of(values()).filter(v -> v.value.equals(value)).findAny().orElse(null); } } diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/EnumsSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/EnumsSpec.scala index 8e35e8558..dbe5ca609 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/EnumsSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/EnumsSpec.scala @@ -61,11 +61,10 @@ class EnumsSpec describe("AuthenticatorAttachment") { describe("can be parsed from JSON") { - it("but throws IllegalArgumentException for unknown values.") { - val result = Try( + it("and ignores for unknown values.") { + val result = json.readValue("\"foo\"", classOf[AuthenticatorAttachment]) - ) - result.failed.get.getCause shouldBe an[IllegalArgumentException] + result should be(null) } } } diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala index 29cfa491f..0fd026f9b 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala @@ -41,12 +41,13 @@ import com.yubico.webauthn.extension.appid.Generators._ import org.junit.runner.RunWith import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary.arbitrary -import org.scalacheck.Gen import org.scalatest.funspec.AnyFunSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.junit.JUnitRunner import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks +import scala.jdk.OptionConverters.RichOptional + @RunWith(classOf[JUnitRunner]) class JsonIoSpec extends AnyFunSpec @@ -351,15 +352,16 @@ class JsonIoSpec ) } - it("allows and ignores an authenticatorAttachment attribute.") { + it( + "allows an authenticatorAttachment attribute, but ignores unknown values." + ) { def test[P <: PublicKeyCredential[_, _]](tpe: TypeReference[P])(implicit a: Arbitrary[P] ): Unit = { forAll( a.arbitrary, - Gen.oneOf( - arbitrary[AuthenticatorAttachment].map(_.getValue), - arbitrary[String], + arbitrary[String].suchThat(s => + !AuthenticatorAttachment.values.map(_.getValue).contains(s) ), ) { (value: P, authenticatorAttachment: String) => val tree: ObjectNode = json.valueToTree(value) @@ -370,8 +372,37 @@ class JsonIoSpec val encoded = json.writeValueAsString(tree) println(authenticatorAttachment) val decoded = json.readValue(encoded, tpe) + decoded.getAuthenticatorAttachment.asScala should be(None) + } + + forAll( + a.arbitrary, + arbitrary[AuthenticatorAttachment], + ) { (value: P, authenticatorAttachment: AuthenticatorAttachment) => + val tree: ObjectNode = json.valueToTree(value) + tree.set( + "authenticatorAttachment", + new TextNode(authenticatorAttachment.getValue), + ) + val encoded = json.writeValueAsString(tree) + println(authenticatorAttachment) + val decoded = json.readValue(encoded, tpe) + + decoded.getAuthenticatorAttachment.asScala should equal( + Some(authenticatorAttachment) + ) + } + + forAll( + a.arbitrary + ) { (value: P) => + val tree: ObjectNode = json.valueToTree( + value.toBuilder.authenticatorAttachment(null).build() + ) + val encoded = json.writeValueAsString(tree) + val decoded = json.readValue(encoded, tpe) - decoded should equal(value) + decoded.getAuthenticatorAttachment.asScala should be(None) } } From 0c817c2675838a076b99bd36bb17891bb99d3eea Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 16 Dec 2022 16:44:20 +0100 Subject: [PATCH 08/17] Add authenticatorAttachment to NEWS --- NEWS | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/NEWS b/NEWS index 3cc5ee846..57d91e86f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,20 @@ +== Version 2.3.0 (unreleased) == + +New features: + +* (Experimental) Added `authenticatorAttachment` property to response objects: + ** NOTE: Experimental features may receive breaking changes without a major + version increase. + ** Added method `getAuthenticatorAttachment()` to `PublicKeyCredential` and + corresponding builder method + `authenticatorAttachment(AuthenticatorAttachment)`. + ** Added method `getAuthenticatorAttachment()` to `RegistrationResult` and + `AssertionResult`, which echo `getAuthenticatorAttachment()` from the + corresponding `PublicKeyCredential`. + ** Thanks to GitHub user luisgoncalves for the contribution, see + https://github.com/Yubico/java-webauthn-server/pull/250 + + == Version 2.2.0 == `webauthn-server-core`: From 35427521ed6dabc83a6fd01f394e796bb51bfd32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:01:00 +0000 Subject: [PATCH 09/17] Bump spotless-plugin-gradle from 6.12.0 to 6.12.1 Bumps [spotless-plugin-gradle](https://github.com/diffplug/spotless) from 6.12.0 to 6.12.1. - [Release notes](https://github.com/diffplug/spotless/releases) - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md) - [Commits](https://github.com/diffplug/spotless/compare/gradle/6.12.0...gradle/6.12.1) --- updated-dependencies: - dependency-name: com.diffplug.spotless:spotless-plugin-gradle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7a1772428..b5a73d21f 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { } dependencies { classpath 'com.cinnober.gradle:semver-git:2.5.0' - classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.12.0' + classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.12.1' classpath 'io.github.cosmicsilence:gradle-scalafix:0.1.13' } } From a0eb8a255310dbade6b2c89056925f7b37fa1b63 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 13:37:38 +0100 Subject: [PATCH 10/17] Correct semver exception for @Deprecated features @Deprecated features are still part of the public API unless they're also tagged as EXPERIMENTAL in JavaDoc. --- NEWS | 6 ++++++ README | 8 ++++---- webauthn-server-attestation/README.adoc | 3 +-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 57d91e86f..5d1b20c01 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,12 @@ New features: ** Thanks to GitHub user luisgoncalves for the contribution, see https://github.com/Yubico/java-webauthn-server/pull/250 +Other: + +* Fixed the README description of SemVer exceptions: `@Deprecated` features are + still part of the public API unless they also have an `EXPERIMENTAL:` tag in + JavaDoc. + == Version 2.2.0 == diff --git a/README b/README index 7a00cddf2..3b5f383db 100644 --- a/README +++ b/README @@ -61,10 +61,10 @@ This library uses link:https://semver.org/[semantic versioning]. The public API consists of all public classes, methods and fields in the `com.yubico.webauthn` package and its subpackages, i.e., everything covered by the link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/package-summary.html[Javadoc], -*with the exception* of things annotated with `@Deprecated`. -In particular, features with a `@deprecated EXPERIMENTAL:` tag in JavaDoc are -considered unstable and may receive breaking changes without a major version -increase. +*with the exception* of features annotated with a `@Deprecated` annotation and a +`@deprecated EXPERIMENTAL:` tag in JavaDoc. +Such features are considered unstable and may receive breaking changes without a +major version increase. Package-private classes and methods are NOT part of the public API. The `com.yubico:yubico-util` module is NOT part of the public API. diff --git a/webauthn-server-attestation/README.adoc b/webauthn-server-attestation/README.adoc index 65d5f6ee1..c7741e8fb 100644 --- a/webauthn-server-attestation/README.adoc +++ b/webauthn-server-attestation/README.adoc @@ -109,8 +109,7 @@ compile 'com.yubico:webauthn-server-attestation:2.2.0' This library uses link:https://semver.org/[semantic versioning]. The public API consists of all public classes, methods and fields in the `com.yubico.fido.metadata` package and its subpackages, i.e., everything covered by the -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-attestation/2.2.0/com/yubico/fido/metadata/package-summary.html[Javadoc], -*with the exception* of things annotated with `@Deprecated`. +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-attestation/2.2.0/com/yubico/fido/metadata/package-summary.html[Javadoc]. Package-private classes and methods are NOT part of the public API. The `com.yubico:yubico-util` module is NOT part of the public API. From 1b403cf43825283bcc048156db56ae2416750440 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 14:26:48 +0100 Subject: [PATCH 11/17] Bring package-info.java up to date with library --- NEWS | 2 + .../com/yubico/webauthn/package-info.java | 73 ++++++++++++------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index 5d1b20c01..a49496e1e 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ Other: * Fixed the README description of SemVer exceptions: `@Deprecated` features are still part of the public API unless they also have an `EXPERIMENTAL:` tag in JavaDoc. +* Brought `com.yubico.webauthn` package JavaDoc up to date with new library + features. == Version 2.2.0 == diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/package-info.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/package-info.java index e9e79f439..85057f464 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/package-info.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/package-info.java @@ -1,5 +1,5 @@ /** - * This package makes up the public API of the webauthn-server-core library. + * This package and its subpackages make up the public API of the webauthn-server-core library. * *

The main entry point is the {@link com.yubico.webauthn.RelyingParty} class. It provides * methods for generating inputs to the navigator.credentials.create() and @@ -82,15 +82,22 @@ * com.yubico.webauthn.data.PublicKeyCredentialCreationOptions} which can be serialized to JSON and * passed as the publicKey argument to navigator.credentials.create(). You * can use the {@link com.yubico.webauthn.data.PublicKeyCredentialCreationOptions#toBuilder() - * toBuilder()} method to make any modifications you need. You should store this in temporary - * storage so that it can later be passed as an argument to {@link - * com.yubico.webauthn.RelyingParty#finishRegistration(FinishRegistrationOptions)}. - * - *

After receiving the response from the client, construct a {@link - * com.yubico.webauthn.data.PublicKeyCredential}<{@link - * com.yubico.webauthn.data.AuthenticatorAttestationResponse}, {@link - * com.yubico.webauthn.data.ClientRegistrationExtensionOutputs}> from the response and wrap that - * in a {@link com.yubico.webauthn.FinishRegistrationOptions} along with the {@link + * toBuilder()} method to make any modifications you need, then the {@link + * com.yubico.webauthn.data.PublicKeyCredentialCreationOptions#toCredentialsCreateJson()} method is + * suitable for converting the value to JSON to send to the client. + * + *

You should also store the {@link com.yubico.webauthn.data.PublicKeyCredentialCreationOptions} + * object in temporary storage so that it can later be passed as an argument to {@link + * com.yubico.webauthn.RelyingParty#finishRegistration(FinishRegistrationOptions)}. If you need to + * serialize the object for storage, the {@link + * com.yubico.webauthn.data.PublicKeyCredentialCreationOptions#toJson()} and {@link + * com.yubico.webauthn.data.PublicKeyCredentialCreationOptions#fromJson(java.lang.String)} methods + * are suitable for serializing to and from a string value. + * + *

After receiving the response from the client, use the {@link + * com.yubico.webauthn.data.PublicKeyCredential#parseRegistrationResponseJson(java.lang.String)} + * function to parse the response and wrap it in a {@link + * com.yubico.webauthn.FinishRegistrationOptions} along with the {@link * com.yubico.webauthn.data.PublicKeyCredentialCreationOptions} used to initiate the request. Pass * that as the argument to {@link * com.yubico.webauthn.RelyingParty#finishRegistration(FinishRegistrationOptions)}, which will @@ -107,14 +114,19 @@ * com.yubico.webauthn.RegistrationResult#getPublicKeyCose() publicKeyCose} as a new * credential for the user. The {@link com.yubico.webauthn.CredentialRepository} will need to * look these up for authentication. + *

  • Store the {@link com.yubico.webauthn.RegistrationResult#getSignatureCount() signature + * counter} value in the new credential. If available, this will be used in future + * authentication ceremonies do detect authenticator cloning. + *
  • Optionally, store the {@link com.yubico.webauthn.RegistrationResult#isDiscoverable() + * isDiscoverable} flag, if present, in the new credential. This may help you determine which + * user interaction flows are possible with which credential. *
  • If you care about authenticator attestation, check that the {@link * com.yubico.webauthn.RegistrationResult#isAttestationTrusted() attestationTrusted} field * satisfies your attestation policy. For this you will likely need to configure the {@link * com.yubico.webauthn.RelyingParty.RelyingPartyBuilder#attestationTrustSource(com.yubico.webauthn.attestation.AttestationTrustSource) * attestationTrustSource} setting on your {@link com.yubico.webauthn.RelyingParty} instance. - * You may also want to consult some external data source to verify the authenticity of the - * {@link com.yubico.webauthn.data.AuthenticatorAttestationResponse#getAttestationObject() - * attestation object}. + * See also the webauthn-server-attestation for an implementation of such an + * attestation trust and metadata source. *
  • If you care about authenticator attestation, it is recommended to also store the raw {@link * com.yubico.webauthn.data.AuthenticatorAttestationResponse#getAttestationObject() * attestation object} as part of the credential. This enables you to retroactively inspect @@ -130,11 +142,13 @@ * com.yubico.webauthn.RelyingParty#startAssertion(StartAssertionOptions)}. The main parameter you * need to set here is the {@link * com.yubico.webauthn.StartAssertionOptions.StartAssertionOptionsBuilder#username(java.util.Optional) - * username} of the user to authenticate, but even this parameter is optional. If the username is - * not set, then the {@link + * username} or {@link + * com.yubico.webauthn.StartAssertionOptions.StartAssertionOptionsBuilder#userHandle(java.util.Optional) + * user handle} of the user to authenticate, but even these parameters are optional. If neither is + * set, then the {@link * com.yubico.webauthn.data.PublicKeyCredentialRequestOptions#getAllowCredentials() - * allowCredentials} parameter will not be set. This which means the user must use a client-side-resident + * allowCredentials} parameter will not be set. This means the user must use a client-side-discoverable * credential to authenticate; also known as "first-factor authentication". This use case has * both advantages and disadvantages; see the Web Authentication specification for an extended * discussion of this. @@ -143,18 +157,21 @@ * startAssertion} method returns an {@link com.yubico.webauthn.AssertionRequest} containing the * username, if any, and a {@link com.yubico.webauthn.data.PublicKeyCredentialRequestOptions} * instance which can be serialized to JSON and passed as the publicKey argument to - * navigator.credentials.get(). Again, store the {@link - * com.yubico.webauthn.AssertionRequest} in temporary storage so it can be passed as an argument to - * {@link + * navigator.credentials.get(). Again, use {@link + * com.yubico.webauthn.AssertionRequest#toBuilder()} to make any necessary changes, {@link + * com.yubico.webauthn.AssertionRequest#toCredentialsGetJson()} to convert it to JSON for sending to + * the client, and store the {@link com.yubico.webauthn.AssertionRequest} in temporary storage so it + * can be passed as an argument to {@link * com.yubico.webauthn.RelyingParty#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)}. - * - *

    After receiving the response from the client, construct a {@link - * com.yubico.webauthn.data.PublicKeyCredential}<{@link - * com.yubico.webauthn.data.AuthenticatorAssertionResponse}, {@link - * com.yubico.webauthn.data.ClientAssertionExtensionOutputs}> from the response and wrap that in - * a {@link com.yubico.webauthn.FinishAssertionOptions} along with the {@link - * com.yubico.webauthn.AssertionRequest} used to initiate the request. Pass that as the argument to - * {@link + * Again, {@link com.yubico.webauthn.AssertionRequest#toJson()} and {@link + * com.yubico.webauthn.AssertionRequest#fromJson(java.lang.String)} can be used to convert to and + * from JSON for storage. + * + *

    After receiving the response from the client, use {@link + * com.yubico.webauthn.data.PublicKeyCredential#parseAssertionResponseJson(java.lang.String)} to + * parse the response, then wrap that in a {@link com.yubico.webauthn.FinishAssertionOptions} along + * with the {@link com.yubico.webauthn.AssertionRequest} used to initiate the request. Pass that as + * the argument to {@link * com.yubico.webauthn.RelyingParty#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)}, * which will return an {@link com.yubico.webauthn.AssertionResult} if successful and throw an * exception if not. Regardless of whether it succeeds, you should remove the {@link From 48cf7aa988ae0756539ceba8a686809ee42c308c Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 15:26:13 +0100 Subject: [PATCH 12/17] Add table of contents heading --- README | 2 ++ webauthn-server-attestation/README.adoc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README b/README index 3b5f383db..590560aa4 100644 --- a/README +++ b/README @@ -28,6 +28,8 @@ If you are, we urge you to upgrade your Java deployment to a version that is saf ========== +*Table of contents* + toc::[] diff --git a/webauthn-server-attestation/README.adoc b/webauthn-server-attestation/README.adoc index c7741e8fb..6cc0e6c3f 100644 --- a/webauthn-server-attestation/README.adoc +++ b/webauthn-server-attestation/README.adoc @@ -9,6 +9,8 @@ https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation[attestation by interfacing with the https://fidoalliance.org/metadata/[FIDO Metadata Service]. +*Table of contents* + toc::[] == Features From df930cf7c79bd1bc3354098bb9516f351b67d5f9 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 15:42:31 +0100 Subject: [PATCH 13/17] Move 1.x migration section to after Getting started --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 590560aa4..8bfe04f04 100644 --- a/README +++ b/README @@ -112,11 +112,6 @@ link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server- for in-depth API documentation. -== Migrating from version `1.x` - -See link:doc/Migrating_from_v1.adoc[the migration guide]. - - == Getting started Using this library comes in two parts: the server side and the client side. @@ -454,6 +449,11 @@ PublicKeyCredentialCreationOptions request = rp.startRegistration( ---------- +== Migrating from version `1.x` + +See link:doc/Migrating_from_v1.adoc[the migration guide]. + + == Migrating from U2F This section is only relevant for applications that have user credentials registered via the From 310282e6cbdd73ee906d6b9582000e709d77fc80 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 16:29:12 +0100 Subject: [PATCH 14/17] Configure cross-links from webauthn-server-attestation JavaDoc to core JavaDoc --- build.gradle | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.gradle b/build.gradle index 7a1772428..9007d7661 100644 --- a/build.gradle +++ b/build.gradle @@ -257,6 +257,19 @@ subprojects { project -> } +// Configure cross-links from webauthn-server-attestation JavaDoc to core JavaDoc +project(':webauthn-server-attestation').tasks.javadoc { + var coreProj = project(':webauthn-server-core') + var coreJavadoc = coreProj.tasks.javadoc + inputs.files coreJavadoc.outputs.files + + // These links won't work locally, but they will work on developers.yubico.com + options.linksOffline("../../webauthn-server-core/${coreProj.version}", "${coreJavadoc.destinationDir}") + + // Use this instead for local testing + //options.linksOffline("file://${coreJavadoc.destinationDir}", "${coreJavadoc.destinationDir}") +} + // The root project has no sources, but the dependency platform also needs to be published as an artifact // See https://docs.gradle.org/current/userguide/java_platform_plugin.html // See https://github.com/Yubico/java-webauthn-server/issues/93#issuecomment-822806951 From 1aa00d93af7e0291e7db3560008b7f63246dfd68 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 16:45:47 +0100 Subject: [PATCH 15/17] Tweak wording in webauthn-server-attestation README --- webauthn-server-attestation/README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webauthn-server-attestation/README.adoc b/webauthn-server-attestation/README.adoc index 6cc0e6c3f..06e4042c8 100644 --- a/webauthn-server-attestation/README.adoc +++ b/webauthn-server-attestation/README.adoc @@ -311,7 +311,7 @@ link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server- settings in link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-attestation/2.2.0/com/yubico/fido/metadata/FidoMetadataService.html[`FidoMetadataService`]. The filters are predicate functions; -each metadata entry will be trusted if and only if the prefilter predicate returns `true` for that entry. +each metadata entry will be included in the data source if and only if the prefilter predicate returns `true` for that entry. Similarly during registration or metadata lookup, the authenticator will be matched with each metadata entry only if the registration-time filter returns `true` for that pair of authenticator and metadata entry. You can also use the From 5b169dffbb16da385d812989fa27bd712aea724a Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 17:58:57 +0100 Subject: [PATCH 16/17] Move Features section first in README --- README | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/README b/README index 8bfe04f04..6695d5ce0 100644 --- a/README +++ b/README @@ -33,6 +33,29 @@ If you are, we urge you to upgrade your Java deployment to a version that is saf toc::[] +== Features + +- Generates request objects suitable as parameters to + `navigator.credentials.create()` and `.get()` +- Performs all necessary + https://www.w3.org/TR/webauthn/#sctn-rp-operations[validation logic] on the + response from the client +- No mutable state or side effects - everything (except builders) is thread safe +- Optionally integrates with an "attestation trust source" to verify + https://www.w3.org/TR/webauthn/#sctn-attestation[authenticator attestations] +- Reproducible builds: release signatures match fresh builds from source. See + link:#reproducible-builds[Reproducible builds] below. + + +=== Non-features + +This library has no concept of accounts, sessions, permissions or identity +federation, and it is not an authentication framework; it only deals with +executing the WebAuthn authentication mechanism. Sessions, account management +and other higher level concepts can make use of this authentication mechanism, +but the authentication mechanism alone does not make a security system. + + == Dependency configuration Maven: @@ -82,29 +105,6 @@ In addition to the main `webauthn-server-core` module, there is also: https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation[attestation statements]. -== Features - -- Generates request objects suitable as parameters to - `navigator.credentials.create()` and `.get()` -- Performs all necessary - https://www.w3.org/TR/webauthn/#sctn-rp-operations[validation logic] on the - response from the client -- No mutable state or side effects - everything (except builders) is thread safe -- Optionally integrates with an "attestation trust source" to verify - https://www.w3.org/TR/webauthn/#sctn-attestation[authenticator attestations] -- Reproducible builds: release signatures match fresh builds from source. See - link:#reproducible-builds[Reproducible builds] below. - - -=== Non-features - -This library has no concept of accounts, sessions, permissions or identity -federation, and it is not an authentication framework; it only deals with -executing the WebAuthn authentication mechanism. Sessions, account management -and other higher level concepts can make use of this authentication mechanism, -but the authentication mechanism alone does not make a security system. - - == Documentation See the From 2281112e9d2adb2ed2ed944ebc8c9cf91a978824 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 11 Jan 2023 18:01:16 +0100 Subject: [PATCH 17/17] Fix formatting of method names in README --- README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index 6695d5ce0..38097b512 100644 --- a/README +++ b/README @@ -232,9 +232,9 @@ so you can also pass it into link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishRegistration(com.yubico.webauthn.FinishRegistrationOptions)[`RelyingParty.finishRegistration(...)`] later. If needed, you can use the -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html#toJson()[toJson()] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html#toJson()[`toJson()`] and -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html#fromJson(java.lang.String)[fromJson(String)] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html#fromJson(java.lang.String)[`fromJson(String)`] methods to serialize and deserialize the value for storage. Now call the WebAuthn API on the client side: @@ -323,9 +323,9 @@ so you can also pass it into link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/RelyingParty.html#finishAssertion(com.yubico.webauthn.FinishAssertionOptions)[`RelyingParty.finishAssertion(...)`] later. If needed, you can use the -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/AssertionRequest.html#toJson()[toJson()] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/AssertionRequest.html#toJson()[`toJson()`] and -link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/AssertionRequest.html#fromJson(java.lang.String)[fromJson(String)] +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.2.0/com/yubico/webauthn/AssertionRequest.html#fromJson(java.lang.String)[`fromJson(String)`] methods to serialize and deserialize the value for storage. Now call the WebAuthn API on the client side: