Skip to content

Commit acebf79

Browse files
committed
Add PRF extension to tests
1 parent 491f4f9 commit acebf79

File tree

7 files changed

+335
-9
lines changed

7 files changed

+335
-9
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ public static class PrfRegistrationOutput {
908908
* @see <a href="https://www.w3.org/TR/webauthn-3/#prf-extension">§10.1.4. Pseudo-random
909909
* function extension (prf)</a>
910910
*/
911-
@JsonProperty private final boolean enabled;
911+
@JsonProperty private final Boolean enabled;
912912

913913
/**
914914
* The results of evaluating the PRF for the inputs given in eval or evalByCredential.
@@ -919,14 +919,14 @@ public static class PrfRegistrationOutput {
919919
@JsonProperty private final PrfValues results;
920920

921921
@JsonCreator
922-
private PrfRegistrationOutput(
923-
@JsonProperty("enabled") boolean enabled, @JsonProperty("results") PrfValues results) {
922+
PrfRegistrationOutput(
923+
@JsonProperty("enabled") Boolean enabled, @JsonProperty("results") PrfValues results) {
924924
this.enabled = enabled;
925925
this.results = results;
926926
}
927927

928928
/** TODO */
929-
public static PrfRegistrationOutput enabled(final boolean enabled) {
929+
public static PrfRegistrationOutput enabled(final Boolean enabled) {
930930
return new PrfRegistrationOutput(enabled, null);
931931
}
932932

@@ -936,7 +936,7 @@ public static PrfRegistrationOutput results(final PrfValues results) {
936936
}
937937

938938
public Optional<Boolean> getEnabled() {
939-
return Optional.of(enabled);
939+
return Optional.ofNullable(enabled);
940940
}
941941

942942
public Optional<PrfValues> getResults() {
@@ -963,7 +963,7 @@ public static class PrfAuthenticationOutput {
963963
@JsonProperty private final PrfValues results;
964964

965965
@JsonCreator
966-
private PrfAuthenticationOutput(@JsonProperty("results") PrfValues results) {
966+
PrfAuthenticationOutput(@JsonProperty("results") PrfValues results) {
967967
this.results = results;
968968
}
969969

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ import com.yubico.webauthn.data.ClientAssertionExtensionOutputs
4141
import com.yubico.webauthn.data.CollectedClientData
4242
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobAuthenticationInput
4343
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobAuthenticationOutput
44+
import com.yubico.webauthn.data.Extensions.Prf.PrfAuthenticationOutput
4445
import com.yubico.webauthn.data.Extensions.Uvm.UvmEntry
46+
import com.yubico.webauthn.data.Generators.Extensions.Prf.arbitraryPrfAuthenticationOutput
4547
import com.yubico.webauthn.data.Generators._
4648
import com.yubico.webauthn.data.PublicKeyCredential
4749
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions
@@ -2579,6 +2581,33 @@ class RelyingPartyAssertionSpec
25792581
}
25802582
}
25812583

2584+
it("pass through prf extension outputs when present.") {
2585+
forAll(minSuccessful(3)) { prfOutput: PrfAuthenticationOutput =>
2586+
val result = rp.finishAssertion(
2587+
FinishAssertionOptions
2588+
.builder()
2589+
.request(
2590+
testDataBase.assertion.get.request
2591+
)
2592+
.response(
2593+
testDataBase.assertion.get.response.toBuilder
2594+
.clientExtensionResults(
2595+
ClientAssertionExtensionOutputs
2596+
.builder()
2597+
.prf(prfOutput)
2598+
.build()
2599+
)
2600+
.build()
2601+
)
2602+
.build()
2603+
)
2604+
2605+
result.getClientExtensionOutputs.get().getPrf.toScala should equal(
2606+
Some(prfOutput)
2607+
)
2608+
}
2609+
}
2610+
25822611
describe("support the uvm extension") {
25832612
it("at authentication time.") {
25842613

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ import com.yubico.webauthn.data.Extensions.CredentialProtection.CredentialProtec
5757
import com.yubico.webauthn.data.Extensions.CredentialProtection.CredentialProtectionPolicy
5858
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobRegistrationInput.LargeBlobSupport
5959
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobRegistrationOutput
60+
import com.yubico.webauthn.data.Extensions.Prf.PrfRegistrationOutput
6061
import com.yubico.webauthn.data.Extensions.Uvm.UvmEntry
62+
import com.yubico.webauthn.data.Generators.Extensions.Prf.arbitraryPrfRegistrationOutput
6163
import com.yubico.webauthn.data.Generators._
6264
import com.yubico.webauthn.data.PublicKeyCredential
6365
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions
@@ -4550,6 +4552,31 @@ class RelyingPartyRegistrationSpec
45504552
}
45514553
}
45524554

4555+
it("pass through prf extension outputs when present.") {
4556+
forAll(minSuccessful(3)) { prfOutput: PrfRegistrationOutput =>
4557+
val testData = RegistrationTestData.Packed.BasicAttestation
4558+
val result = rp.finishRegistration(
4559+
FinishRegistrationOptions
4560+
.builder()
4561+
.request(testData.request)
4562+
.response(
4563+
testData.response.toBuilder
4564+
.clientExtensionResults(
4565+
ClientRegistrationExtensionOutputs
4566+
.builder()
4567+
.prf(prfOutput)
4568+
.build()
4569+
)
4570+
.build()
4571+
)
4572+
.build()
4573+
)
4574+
result.getClientExtensionOutputs.get().getPrf.toScala should equal(
4575+
Some(prfOutput)
4576+
)
4577+
}
4578+
}
4579+
45534580
describe("support the uvm extension") {
45544581
it("at registration time.") {
45554582

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

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ import com.yubico.webauthn.data.AuthenticatorTransport
3434
import com.yubico.webauthn.data.ByteArray
3535
import com.yubico.webauthn.data.Extensions.CredentialProtection.CredentialProtectionInput
3636
import com.yubico.webauthn.data.Extensions.CredentialProtection.CredentialProtectionPolicy
37+
import com.yubico.webauthn.data.Extensions.Prf.PrfAuthenticationInput
38+
import com.yubico.webauthn.data.Extensions.Prf.PrfRegistrationInput
39+
import com.yubico.webauthn.data.Generators.Extensions.Prf.arbitraryPrfAuthenticationInput
40+
import com.yubico.webauthn.data.Generators.Extensions.Prf.arbitraryPrfRegistrationInput
3741
import com.yubico.webauthn.data.Generators.Extensions.registrationExtensionInputs
3842
import com.yubico.webauthn.data.Generators._
3943
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions
@@ -578,6 +582,40 @@ class RelyingPartyStartOperationSpec
578582
}
579583
}
580584

585+
it("by default does not set the prf extension.") {
586+
val rp = relyingParty(userId = userId)
587+
val result = rp.startRegistration(
588+
StartRegistrationOptions
589+
.builder()
590+
.user(userId)
591+
.build()
592+
)
593+
result.getExtensions.getPrf.toScala should be(
594+
None
595+
)
596+
}
597+
598+
it("sets the prf extension if enabled in StartRegistrationOptions.") {
599+
forAll {
600+
(
601+
extensions: RegistrationExtensionInputs,
602+
prf: PrfRegistrationInput,
603+
) =>
604+
val rp = relyingParty(userId = userId)
605+
val result = rp.startRegistration(
606+
StartRegistrationOptions
607+
.builder()
608+
.user(userId)
609+
.extensions(extensions.toBuilder.prf(prf).build())
610+
.build()
611+
)
612+
613+
result.getExtensions.getPrf.toScala should equal(
614+
Some(prf)
615+
)
616+
}
617+
}
618+
581619
it("respects the residentKey setting.") {
582620
val rp = relyingParty(userId = userId)
583621

@@ -1063,6 +1101,35 @@ class RelyingPartyStartOperationSpec
10631101
)
10641102
}
10651103
}
1104+
1105+
it("by default does not set the prf extension.") {
1106+
val rp = relyingParty(userId = userId)
1107+
val result = rp.startAssertion(
1108+
StartAssertionOptions
1109+
.builder()
1110+
.build()
1111+
)
1112+
result.getPublicKeyCredentialRequestOptions.getExtensions.getPrf.toScala should be(
1113+
None
1114+
)
1115+
}
1116+
1117+
it("sets the prf extension if enabled in StartAssertionOptions.") {
1118+
forAll {
1119+
(extensions: AssertionExtensionInputs, prf: PrfAuthenticationInput) =>
1120+
val rp = relyingParty(userId = userId)
1121+
val result = rp.startAssertion(
1122+
StartAssertionOptions
1123+
.builder()
1124+
.extensions(extensions.toBuilder.prf(prf).build())
1125+
.build()
1126+
)
1127+
1128+
result.getPublicKeyCredentialRequestOptions.getExtensions.getPrf.toScala should equal(
1129+
Some(prf)
1130+
)
1131+
}
1132+
}
10661133
}
10671134
}
10681135

@@ -1557,6 +1624,40 @@ class RelyingPartyStartOperationSpec
15571624
}
15581625
}
15591626

1627+
it("by default does not set the prf extension.") {
1628+
val rp = relyingParty(userId = userId)
1629+
val result = rp.startRegistration(
1630+
StartRegistrationOptions
1631+
.builder()
1632+
.user(userId)
1633+
.build()
1634+
)
1635+
result.getExtensions.getPrf.toScala should be(
1636+
None
1637+
)
1638+
}
1639+
1640+
it("sets the prf extension if enabled in StartRegistrationOptions.") {
1641+
forAll {
1642+
(
1643+
extensions: RegistrationExtensionInputs,
1644+
prf: PrfRegistrationInput,
1645+
) =>
1646+
val rp = relyingParty(userId = userId)
1647+
val result = rp.startRegistration(
1648+
StartRegistrationOptions
1649+
.builder()
1650+
.user(userId)
1651+
.extensions(extensions.toBuilder.prf(prf).build())
1652+
.build()
1653+
)
1654+
1655+
result.getExtensions.getPrf.toScala should equal(
1656+
Some(prf)
1657+
)
1658+
}
1659+
}
1660+
15601661
it("respects the residentKey setting.") {
15611662
val rp = relyingParty(userId = userId)
15621663

@@ -2060,6 +2161,35 @@ class RelyingPartyStartOperationSpec
20602161
)
20612162
}
20622163
}
2164+
2165+
it("by default does not set the prf extension.") {
2166+
val rp = relyingParty(userId = userId)
2167+
val result = rp.startAssertion(
2168+
StartAssertionOptions
2169+
.builder()
2170+
.build()
2171+
)
2172+
result.getPublicKeyCredentialRequestOptions.getExtensions.getPrf.toScala should be(
2173+
None
2174+
)
2175+
}
2176+
2177+
it("sets the prf extension if enabled in StartAssertionOptions.") {
2178+
forAll {
2179+
(extensions: AssertionExtensionInputs, prf: PrfAuthenticationInput) =>
2180+
val rp = relyingParty(userId = userId)
2181+
val result = rp.startAssertion(
2182+
StartAssertionOptions
2183+
.builder()
2184+
.extensions(extensions.toBuilder.prf(prf).build())
2185+
.build()
2186+
)
2187+
2188+
result.getPublicKeyCredentialRequestOptions.getExtensions.getPrf.toScala should equal(
2189+
Some(prf)
2190+
)
2191+
}
2192+
}
20632193
}
20642194
}
20652195

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ import com.yubico.webauthn.data.ClientAssertionExtensionOutputs
4141
import com.yubico.webauthn.data.CollectedClientData
4242
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobAuthenticationInput
4343
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobAuthenticationOutput
44+
import com.yubico.webauthn.data.Extensions.Prf.PrfAuthenticationOutput
4445
import com.yubico.webauthn.data.Extensions.Uvm.UvmEntry
46+
import com.yubico.webauthn.data.Generators.Extensions.Prf.arbitraryPrfAuthenticationOutput
4547
import com.yubico.webauthn.data.Generators._
4648
import com.yubico.webauthn.data.PublicKeyCredential
4749
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions
@@ -2657,6 +2659,35 @@ class RelyingPartyV2AssertionSpec
26572659
}
26582660
}
26592661

2662+
it("pass through prf extension outputs when present.") {
2663+
forAll(minSuccessful(3)) { prfOutput: PrfAuthenticationOutput =>
2664+
val result = rp.finishAssertion(
2665+
FinishAssertionOptions
2666+
.builder()
2667+
.request(
2668+
testDataBase.assertion.get.request.toBuilder
2669+
.userHandle(testDataBase.userId.getId)
2670+
.build()
2671+
)
2672+
.response(
2673+
testDataBase.assertion.get.response.toBuilder
2674+
.clientExtensionResults(
2675+
ClientAssertionExtensionOutputs
2676+
.builder()
2677+
.prf(prfOutput)
2678+
.build()
2679+
)
2680+
.build()
2681+
)
2682+
.build()
2683+
)
2684+
2685+
result.getClientExtensionOutputs.get().getPrf.toScala should equal(
2686+
Some(prfOutput)
2687+
)
2688+
}
2689+
}
2690+
26602691
describe("support the uvm extension") {
26612692
it("at authentication time.") {
26622693

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ import com.yubico.webauthn.data.Extensions.CredentialProtection.CredentialProtec
5757
import com.yubico.webauthn.data.Extensions.CredentialProtection.CredentialProtectionPolicy
5858
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobRegistrationInput.LargeBlobSupport
5959
import com.yubico.webauthn.data.Extensions.LargeBlob.LargeBlobRegistrationOutput
60+
import com.yubico.webauthn.data.Extensions.Prf.PrfRegistrationOutput
6061
import com.yubico.webauthn.data.Extensions.Uvm.UvmEntry
62+
import com.yubico.webauthn.data.Generators.Extensions.Prf.arbitraryPrfRegistrationOutput
6163
import com.yubico.webauthn.data.Generators._
6264
import com.yubico.webauthn.data.PublicKeyCredential
6365
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions
@@ -4459,6 +4461,33 @@ class RelyingPartyV2RegistrationSpec
44594461
}
44604462
}
44614463

4464+
it("pass through prf extension outputs when present.") {
4465+
forAll(minSuccessful(3)) { prfOutput: PrfRegistrationOutput =>
4466+
val testData = RegistrationTestData.Packed.BasicAttestation
4467+
val result = rp.finishRegistration(
4468+
FinishRegistrationOptions
4469+
.builder()
4470+
.request(
4471+
testData.request
4472+
)
4473+
.response(
4474+
testData.response.toBuilder
4475+
.clientExtensionResults(
4476+
ClientRegistrationExtensionOutputs
4477+
.builder()
4478+
.prf(prfOutput)
4479+
.build()
4480+
)
4481+
.build()
4482+
)
4483+
.build()
4484+
)
4485+
result.getClientExtensionOutputs.get().getPrf.toScala should equal(
4486+
Some(prfOutput)
4487+
)
4488+
}
4489+
}
4490+
44624491
describe("support the uvm extension") {
44634492
it("at registration time.") {
44644493

0 commit comments

Comments
 (0)