diff --git a/Src/Fido2.Models/AuthenticatorAssertionRawResponse.cs b/Src/Fido2.Models/AuthenticatorAssertionRawResponse.cs index b89118d5..029285e7 100644 --- a/Src/Fido2.Models/AuthenticatorAssertionRawResponse.cs +++ b/Src/Fido2.Models/AuthenticatorAssertionRawResponse.cs @@ -27,7 +27,15 @@ public class AuthenticatorAssertionRawResponse public PublicKeyCredentialType? Type { get; set; } [JsonPropertyName("extensions")] - public AuthenticationExtensionsClientOutputs Extensions { get; set; } + [Obsolete("Use ClientExtensionResults instead")] + public AuthenticationExtensionsClientOutputs Extensions + { + get => ClientExtensionResults; + set => ClientExtensionResults = value; + } + + [JsonPropertyName("clientExtensionResults")] + public AuthenticationExtensionsClientOutputs ClientExtensionResults { get; set; } public sealed class AssertionResponse { diff --git a/Src/Fido2/AuthenticatorAssertionResponse.cs b/Src/Fido2/AuthenticatorAssertionResponse.cs index 953328f9..c9bfc661 100644 --- a/Src/Fido2/AuthenticatorAssertionResponse.cs +++ b/Src/Fido2/AuthenticatorAssertionResponse.cs @@ -115,7 +115,7 @@ public async Task VerifyAsync( // https://www.w3.org/TR/webauthn/#sctn-appid-extension // FIDO AppID Extension: // If true, the AppID was used and thus, when verifying an assertion, the Relying Party MUST expect the rpIdHash to be the hash of the AppID, not the RP ID. - var rpid = Raw.Extensions?.AppID ?? false ? options.Extensions?.AppID : options.RpId; + var rpid = Raw.ClientExtensionResults?.AppID ?? false ? options.Extensions?.AppID : options.RpId; byte[] hashedRpId = SHA256.HashData(Encoding.UTF8.GetBytes(rpid ?? string.Empty)); byte[] hash = SHA256.HashData(Raw.Response.ClientDataJson); @@ -144,9 +144,9 @@ public async Task VerifyAsync( // considering the client extension input values that were given in options.extensions and any specific policy of the Relying Party regarding unsolicited extensions, // i.e., those that were not specified as part of options.extensions. In the general case, the meaning of "are as expected" is specific to the Relying Party and which extensions are in use. byte[]? devicePublicKeyResult = null; - if (Raw.Extensions?.DevicePubKey is not null) + if (Raw.ClientExtensionResults?.DevicePubKey is not null) { - devicePublicKeyResult = await DevicePublicKeyAuthenticationAsync(storedDevicePublicKeys, Raw.Extensions, AuthenticatorData, hash).ConfigureAwait(false); + devicePublicKeyResult = await DevicePublicKeyAuthenticationAsync(storedDevicePublicKeys, Raw.ClientExtensionResults, AuthenticatorData, hash).ConfigureAwait(false); } // Pretty sure these conditions are not able to be met due to the AuthenticatorData constructor implementation diff --git a/Test/AuthenticatorResponse.cs b/Test/AuthenticatorResponse.cs index cbaea684..fc3819d9 100644 --- a/Test/AuthenticatorResponse.cs +++ b/Test/AuthenticatorResponse.cs @@ -1234,7 +1234,7 @@ public void TestAuthenticatorAssertionRawResponse() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = true, Extensions = new string[] { "foo", "bar" }, @@ -1264,13 +1264,13 @@ public void TestAuthenticatorAssertionRawResponse() Assert.Equal(new byte[] { 0xf1, 0xd0 }, assertionResponse.Response.Signature); Assert.Equal(clientDataJson, assertionResponse.Response.ClientDataJson); Assert.Equal(new byte[] { 0xf1, 0xd0 }, assertionResponse.Response.UserHandle); - Assert.True(assertionResponse.Extensions.AppID); - Assert.Equal(new string[] { "foo", "bar" }, assertionResponse.Extensions.Extensions); - Assert.Equal("test", assertionResponse.Extensions.Example); - Assert.Equal((ulong)4, assertionResponse.Extensions.UserVerificationMethod[0][0]); - Assert.True(assertionResponse.Extensions.PRF.Enabled); - Assert.Equal(new byte[] { 0xf1, 0xd0 }, assertionResponse.Extensions.PRF.Results.First); - Assert.Equal(new byte[] { 0xf1, 0xd0 }, assertionResponse.Extensions.PRF.Results.Second); + Assert.True(assertionResponse.ClientExtensionResults.AppID); + Assert.Equal(new string[] { "foo", "bar" }, assertionResponse.ClientExtensionResults.Extensions); + Assert.Equal("test", assertionResponse.ClientExtensionResults.Example); + Assert.Equal((ulong)4, assertionResponse.ClientExtensionResults.UserVerificationMethod[0][0]); + Assert.True(assertionResponse.ClientExtensionResults.PRF.Enabled); + Assert.Equal(new byte[] { 0xf1, 0xd0 }, assertionResponse.ClientExtensionResults.PRF.Results.First); + Assert.Equal(new byte[] { 0xf1, 0xd0 }, assertionResponse.ClientExtensionResults.PRF.Results.Second); } [Fact] @@ -1310,7 +1310,7 @@ public async Task TestAuthenticatorAssertionTypeNotPublicKey() Type = PublicKeyCredentialType.Invalid, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1378,7 +1378,7 @@ public async Task TestAuthenticatorAssertionIdMissing() Response = assertion, Type = PublicKeyCredentialType.PublicKey, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1447,7 +1447,7 @@ public async Task TestAuthenticatorAssertionRawIdMissing() Response = assertion, Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1516,7 +1516,7 @@ public async Task TestAuthenticatorAssertionUserHandleEmpty() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1585,7 +1585,7 @@ public async Task TestAuthenticatorAssertionUserHandleNotOwnerOfPublicKey() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1654,7 +1654,7 @@ public async Task TestAuthenticatorAssertionTypeNotWebAuthnGet() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1725,7 +1725,7 @@ public async Task TestAuthenticatorAssertionAppId() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = true, Extensions = new string[] { "foo", "bar" }, @@ -1795,7 +1795,7 @@ public async Task TestAuthenticatorAssertionInvalidRpIdHash() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1866,7 +1866,7 @@ public async Task TestAuthenticatorAssertionUPRequirementNotMet() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -1936,7 +1936,7 @@ public async Task TestAuthenticatorAssertionUVPolicyNotMet() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2004,7 +2004,7 @@ public async Task TestAuthenticatorAssertionBEPolicyRequired() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2073,7 +2073,7 @@ public async Task TestAuthenticatorAssertionBEPolicyDisallow() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2142,7 +2142,7 @@ public async Task TestAuthenticatorAssertionBSPolicyRequired() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2211,7 +2211,7 @@ public async Task TestAuthenticatorAssertionBSPolicyDisallow() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2281,7 +2281,7 @@ public async Task TestAuthenticatorAssertionStoredPublicKeyMissing() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2350,7 +2350,7 @@ public async Task TestAuthenticatorAssertionInvalidSignature() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, @@ -2426,7 +2426,7 @@ public async Task TestAuthenticatorAssertionSignCountSignature() Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, - Extensions = new AuthenticationExtensionsClientOutputs() + ClientExtensionResults = new AuthenticationExtensionsClientOutputs() { AppID = false, Extensions = new string[] { "foo", "bar" }, diff --git a/Test/ExistingU2fRegistrationDataTests.cs b/Test/ExistingU2fRegistrationDataTests.cs index d4eb6c15..4a61e46e 100644 --- a/Test/ExistingU2fRegistrationDataTests.cs +++ b/Test/ExistingU2fRegistrationDataTests.cs @@ -38,7 +38,7 @@ public async Task TestFido2AssertionWithExistingU2fRegistrationWithAppId() Id = keyHandleData, RawId = keyHandleData, Type = PublicKeyCredentialType.PublicKey, - Extensions = new AuthenticationExtensionsClientOutputs + ClientExtensionResults = new AuthenticationExtensionsClientOutputs { AppID = true },