diff --git a/NEWS b/NEWS index b413e25c2..4129d9baa 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,11 @@ Fixes: handle are both absent unless a user handle was returned by the authenticator. This was originally released in pre-release `1.12.3-RC3`, but was accidentally left out of the `1.12.3` release. +* Fixed regression in + `PublicKeyCredentialCreationOptions.toCredentialsCreateJson()`, which has not + been emitting a `requireResidentKey` member since version `2.0.0`. This meant + the JSON output was not backwards compatible with browsers that only support + the Level 1 version of the WebAuthn spec. New features: diff --git a/doc/Migrating_from_v1.adoc b/doc/Migrating_from_v1.adoc index eb19d0848..b8f04803b 100644 --- a/doc/Migrating_from_v1.adoc +++ b/doc/Migrating_from_v1.adoc @@ -26,10 +26,12 @@ Here is a high-level outline of what needs to be updated: - Update `getUserVerification()` and `getResidentKey()` calls to expect `Optional` values. -This migration guide is written for version `2.0.0` of the +Although the next section references version `2.4.0-RC2` for reasons detailed there, +this migration guide is written for version `2.0.0` of the `webauthn-server-core` module. Later `2.x` versions may introduce new features -but should remain compatible without further changes; consult the release notes -for a full list of new features. +but should remain compatible without further changes; please consult the +link:https://developers.yubico.com/java-webauthn-server/Release_Notes.html[release notes] +for an up to date list of new features. == Replace dependency on `webauthn-server-core-minimal` @@ -46,7 +48,7 @@ Maven example: - webauthn-server-core-minimal - 1.12.2 + webauthn-server-core -+ 2.0.0 ++ 2.4.0-RC2 compile ---------- @@ -56,10 +58,30 @@ Gradle: [source,diff] ---------- -compile 'com.yubico:webauthn-server-core-minimal:1.12.2' -+compile 'com.yubico:webauthn-server-core:2.0.0' ++compile 'com.yubico:webauthn-server-core:2.4.0-RC2' ---------- +[WARNING] +.*Backwards-incompatible regression in versions 2.0.0 to 2.4.0-RC1* +========== +Versions in the inclusive range `2.0.0` to `2.4.0-RC1` have +a backwards-incompatible regression in +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/data/PublicKeyCredentialCreationOptions.html#toCredentialsCreateJson()[`PublicKeyCredentialCreationOptions.toCredentialsCreateJson()`]: +When the +link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.3.0/com/yubico/webauthn/StartRegistrationOptions.StartRegistrationOptionsBuilder.html#authenticatorSelection(com.yubico.webauthn.data.AuthenticatorSelectionCriteria)[`authenticatorSelection`].link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/2.3.0/com/yubico/webauthn/data/AuthenticatorSelectionCriteria.AuthenticatorSelectionCriteriaBuilder.html#residentKey(com.yubico.webauthn.data.ResidentKeyRequirement)[`residentKey`] +parameter is set, a corresponding +link:https://www.w3.org/TR/webauthn-2/#dom-authenticatorselectioncriteria-requireresidentkey[`requireResidentKey`] +member is not emitted in the JSON output. +This is not backwards compatible with browsers that only support the +link:https://www.w3.org/TR/2019/REC-webauthn-1-20190304/#authenticatorSelection[Level 1 version of the WebAuthn spec]. +The regression is fixed in version `2.4.0-RC2` and greater. +We therefore urge users to upgrade from versions `1.x` directly to `2.4.0-RC2` or greater to maintain backwards compatibility. +Please consult the link:https://developers.yubico.com/java-webauthn-server/Release_Notes.html[release notes] +for an up to date list of additional changes and new features added since version `2.0.0`. +========== + + == Add JCA provider for EdDSA The library no longer depends explicitly on BouncyCastle for cryptography back-ends. diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorSelectionCriteria.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorSelectionCriteria.java index ec3566bd0..4fde736f2 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorSelectionCriteria.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorSelectionCriteria.java @@ -100,6 +100,14 @@ public Optional getAuthenticatorAttachment() { *

By default, this is not set. When not set, the default in the browser is {@link * ResidentKeyRequirement#DISCOURAGED}. * + *

When this is set, {@link PublicKeyCredentialCreationOptions#toCredentialsCreateJson()} will + * also emit a + * requireResidentKey member for backwards compatibility with WebAuthn Level 1. + * It will be set to true if this is set to {@link ResidentKeyRequirement#REQUIRED + * REQUIRED} and false if this is set to anything else. When this is not set, a + * requireResidentKey will not be emitted. + * * @see ResidentKeyRequirement * @see ยง5.4.6. @@ -112,6 +120,19 @@ public Optional getResidentKey() { return Optional.ofNullable(residentKey); } + /** + * For backwards compatibility with requireResidentKey. + * + * @see 5.4.4. + * Authenticator Selection Criteria (dictionary AuthenticatorSelectionCriteria) member + * requireResidentKey + */ + @JsonProperty + private Boolean isRequireResidentKey() { + return getResidentKey().map(rk -> rk == ResidentKeyRequirement.REQUIRED).orElse(null); + } + /** * Describes the Relying Party's requirements regarding user diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala index 2d7222bc0..7b491b189 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala @@ -24,6 +24,7 @@ package com.yubico.webauthn +import com.yubico.internal.util.JacksonCodecs import com.yubico.webauthn.Generators._ import com.yubico.webauthn.data.AssertionExtensionInputs import com.yubico.webauthn.data.AttestationConveyancePreference @@ -33,6 +34,7 @@ import com.yubico.webauthn.data.AuthenticatorTransport import com.yubico.webauthn.data.ByteArray import com.yubico.webauthn.data.Generators.Extensions.registrationExtensionInputs import com.yubico.webauthn.data.Generators._ +import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions import com.yubico.webauthn.data.PublicKeyCredentialDescriptor import com.yubico.webauthn.data.PublicKeyCredentialParameters import com.yubico.webauthn.data.RegistrationExtensionInputs @@ -454,18 +456,37 @@ class RelyingPartyStartOperationSpec .build() ) + def jsonRequireResidentKey( + pkcco: PublicKeyCredentialCreationOptions + ): Option[Boolean] = + Option( + JacksonCodecs + .json() + .readTree(pkcco.toCredentialsCreateJson) + .get("publicKey") + .get("authenticatorSelection") + .get("requireResidentKey") + ).map(_.booleanValue) + pkccoDiscouraged.getAuthenticatorSelection.get.getResidentKey.toScala should be( Some(ResidentKeyRequirement.DISCOURAGED) ) + jsonRequireResidentKey(pkccoDiscouraged) should be(Some(false)) + pkccoPreferred.getAuthenticatorSelection.get.getResidentKey.toScala should be( Some(ResidentKeyRequirement.PREFERRED) ) + jsonRequireResidentKey(pkccoPreferred) should be(Some(false)) + pkccoRequired.getAuthenticatorSelection.get.getResidentKey.toScala should be( Some(ResidentKeyRequirement.REQUIRED) ) + jsonRequireResidentKey(pkccoRequired) should be(Some(true)) + pkccoUnspecified.getAuthenticatorSelection.get.getResidentKey.toScala should be( None ) + jsonRequireResidentKey(pkccoUnspecified) should be(None) } it("respects the authenticatorAttachment parameter.") {