Skip to content

Commit 37f32c3

Browse files
committed
Added credProps.authenticatorDisplayName
1 parent b7b5893 commit 37f32c3

File tree

5 files changed

+107
-14
lines changed

5 files changed

+107
-14
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ New features:
5151
* (Experimental) Added property `RegisteredCredential.transports`.
5252
** NOTE: Experimental features may receive breaking changes without a major
5353
version increase.
54+
* (Experimental) Added property `credProps.authenticatorDisplayName`.
55+
** NOTE: Experimental features may receive breaking changes without a major
56+
version increase.
5457

5558

5659
== Version 2.5.2 ==

webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,7 @@
3030
import com.yubico.internal.util.CertificateParser;
3131
import com.yubico.webauthn.RelyingParty.RelyingPartyBuilder;
3232
import com.yubico.webauthn.attestation.AttestationTrustSource;
33-
import com.yubico.webauthn.data.AttestationType;
34-
import com.yubico.webauthn.data.AuthenticatorAttachment;
35-
import com.yubico.webauthn.data.AuthenticatorAttestationResponse;
36-
import com.yubico.webauthn.data.AuthenticatorData;
37-
import com.yubico.webauthn.data.AuthenticatorDataFlags;
38-
import com.yubico.webauthn.data.AuthenticatorRegistrationExtensionOutputs;
39-
import com.yubico.webauthn.data.AuthenticatorResponse;
40-
import com.yubico.webauthn.data.ByteArray;
41-
import com.yubico.webauthn.data.ClientRegistrationExtensionOutputs;
42-
import com.yubico.webauthn.data.PublicKeyCredential;
43-
import com.yubico.webauthn.data.PublicKeyCredentialDescriptor;
33+
import com.yubico.webauthn.data.*;
4434
import java.io.IOException;
4535
import java.security.NoSuchAlgorithmException;
4636
import java.security.PublicKey;
@@ -367,6 +357,30 @@ public Optional<Boolean> isDiscoverable() {
367357
.flatMap(credProps -> credProps.getRk());
368358
}
369359

360+
/**
361+
* Retrieve a suitable nickname for this credential, if one is available.
362+
*
363+
* <p>This returns the <code>authenticatorDisplayName</code> output from the <a
364+
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-authenticator-credential-properties-extension">
365+
* <code>credProps</code></a> extension.
366+
*
367+
* @return A user-chosen or vendor-default display name for the credential, if available.
368+
* Otherwise empty.
369+
* @see <a
370+
* href="https://w3c.github.io/webauthn/#dom-credentialpropertiesoutput-authenticatordisplayname">§10.1.3.
371+
* Credential Properties Extension (credProps), "authenticatorDisplayName" output</a>
372+
* @see Extensions.CredentialProperties.CredentialPropertiesOutput#getAuthenticatorDisplayName()
373+
* @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as
374+
* the standard matures.
375+
*/
376+
@JsonIgnore
377+
@Deprecated
378+
public Optional<String> getAuthenticatorDisplayName() {
379+
return getClientExtensionOutputs()
380+
.flatMap(outputs -> outputs.getCredProps())
381+
.flatMap(credProps -> credProps.getAuthenticatorDisplayName());
382+
}
383+
370384
/**
371385
* The <a
372386
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#attestation-trust-path">attestation

webauthn-server-core/src/main/java/com/yubico/webauthn/data/Extensions.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.fasterxml.jackson.annotation.JsonValue;
77
import com.upokecenter.cbor.CBORObject;
88
import com.upokecenter.cbor.CBORType;
9+
import com.yubico.webauthn.RegistrationResult;
910
import com.yubico.webauthn.StartRegistrationOptions;
1011
import com.yubico.webauthn.extension.uvm.KeyProtectionType;
1112
import com.yubico.webauthn.extension.uvm.MatcherProtectionType;
@@ -71,9 +72,15 @@ public static class CredentialPropertiesOutput {
7172
@JsonProperty("rk")
7273
private final Boolean rk;
7374

75+
@JsonProperty("authenticatorDisplayName")
76+
private final String authenticatorDisplayName;
77+
7478
@JsonCreator
75-
private CredentialPropertiesOutput(@JsonProperty("rk") Boolean rk) {
79+
private CredentialPropertiesOutput(
80+
@JsonProperty("rk") Boolean rk,
81+
@JsonProperty("authenticatorDisplayName") String authenticatorDisplayName) {
7682
this.rk = rk;
83+
this.authenticatorDisplayName = authenticatorDisplayName;
7784
}
7885

7986
/**
@@ -105,6 +112,24 @@ private CredentialPropertiesOutput(@JsonProperty("rk") Boolean rk) {
105112
public Optional<Boolean> getRk() {
106113
return Optional.ofNullable(rk);
107114
}
115+
116+
/**
117+
* This OPTIONAL property is a human-palatable description of the credential's managing
118+
* authenticator, chosen by the user.
119+
*
120+
* <p>If the RP includes an <code>[$credential record/authenticatorDisplayName$]</code>
121+
* [=struct/item=] in [=credential records=], the [=[RP]=] MAY offer this value, if present,
122+
* as a default value for the <code>[$credential record/authenticatorDisplayName$]</code> of
123+
* the new [=credential record=].
124+
*
125+
* @see RegistrationResult#getAuthenticatorDisplayName()
126+
* @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change
127+
* as the standard matures.
128+
*/
129+
@Deprecated
130+
public Optional<String> getAuthenticatorDisplayName() {
131+
return Optional.ofNullable(authenticatorDisplayName);
132+
}
108133
}
109134
}
110135

webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4289,6 +4289,51 @@ class RelyingPartyRegistrationSpec
42894289
}
42904290
}
42914291

4292+
describe("expose the credProps.authenticatorDisplayName extension output as RegistrationResult.getAuthenticatorDisplayName()") {
4293+
val testDataBase = RegistrationTestData.Packed.BasicAttestation
4294+
val testData = testDataBase.copy(requestedExtensions =
4295+
testDataBase.request.getExtensions.toBuilder.credProps().build()
4296+
)
4297+
4298+
it("""when set to "hej".""") {
4299+
val result = rp.finishRegistration(
4300+
FinishRegistrationOptions
4301+
.builder()
4302+
.request(testData.request)
4303+
.response(
4304+
testData.response.toBuilder
4305+
.clientExtensionResults(
4306+
ClientRegistrationExtensionOutputs
4307+
.builder()
4308+
.credProps(
4309+
CredentialPropertiesOutput
4310+
.builder()
4311+
.authenticatorDisplayName("hej")
4312+
.build()
4313+
)
4314+
.build()
4315+
)
4316+
.build()
4317+
)
4318+
.build()
4319+
)
4320+
4321+
result.getAuthenticatorDisplayName.toScala should equal(Some("hej"))
4322+
}
4323+
4324+
it("when not available.") {
4325+
val result = rp.finishRegistration(
4326+
FinishRegistrationOptions
4327+
.builder()
4328+
.request(testData.request)
4329+
.response(testData.response)
4330+
.build()
4331+
)
4332+
4333+
result.getAuthenticatorDisplayName.toScala should equal(None)
4334+
}
4335+
}
4336+
42924337
describe("support the largeBlob extension") {
42934338
it("being enabled at registration time.") {
42944339
val testData = RegistrationTestData.Packed.BasicAttestation

webauthn-server-core/src/test/scala/com/yubico/webauthn/data/Generators.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,8 +867,14 @@ object Generators {
867867
object CredProps {
868868
def credentialPropertiesOutput: Gen[CredentialPropertiesOutput] =
869869
for {
870-
rk <- arbitrary[Boolean]
871-
} yield CredentialPropertiesOutput.builder().rk(rk).build()
870+
rk <- arbitrary[Option[Boolean]]
871+
authenticatorDisplayName <- arbitrary[Option[String]]
872+
} yield {
873+
val b = CredentialPropertiesOutput.builder()
874+
rk.foreach(b.rk(_))
875+
authenticatorDisplayName.foreach(b.authenticatorDisplayName)
876+
b.build()
877+
}
872878
}
873879

874880
object LargeBlob {

0 commit comments

Comments
 (0)