Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Models] Enable nullable (1 of x) #581

Merged
merged 4 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions Src/Fido2.Models/AuthenticatorAssertionRawResponse.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable disable

using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;

using Fido2NetLib.Objects;
Expand All @@ -12,19 +13,19 @@ namespace Fido2NetLib;
public class AuthenticatorAssertionRawResponse
{
[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("id")]
public byte[] Id { get; set; }
[JsonPropertyName("id"), Required]
public byte[] Id { get; init; }

// might be wrong to base64url encode this...
[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("rawId")]
public byte[] RawId { get; set; }
[JsonPropertyName("rawId"), Required]
public byte[] RawId { get; init; }

[JsonPropertyName("response")]
public AssertionResponse Response { get; set; }
public AssertionResponse Response { get; init; }

[JsonPropertyName("type")]
public PublicKeyCredentialType? Type { get; set; }
[JsonPropertyName("type"), Required]
public PublicKeyCredentialType Type { get; init; }

[JsonPropertyName("extensions")]
[Obsolete("Use ClientExtensionResults instead")]
Expand All @@ -34,25 +35,27 @@ public AuthenticationExtensionsClientOutputs Extensions
set => ClientExtensionResults = value;
}

[JsonPropertyName("clientExtensionResults")]
[JsonPropertyName("clientExtensionResults"), Required]
public AuthenticationExtensionsClientOutputs ClientExtensionResults { get; set; }

public sealed class AssertionResponse
{
[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("authenticatorData")]
public byte[] AuthenticatorData { get; set; }
public required byte[] AuthenticatorData { get; init; }

[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("signature")]
public byte[] Signature { get; set; }
public required byte[] Signature { get; init; }

[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("clientDataJSON")]
public byte[] ClientDataJson { get; set; }
public required byte[] ClientDataJson { get; init; }

#nullable enable

[JsonPropertyName("userHandle")]
[JsonConverter(typeof(Base64UrlConverter))]
public byte[]? UserHandle { get; set; }
public byte[]? UserHandle { get; init; }
}
}
29 changes: 15 additions & 14 deletions Src/Fido2.Models/AuthenticatorAttestationRawResponse.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;

using Fido2NetLib.Objects;

Expand All @@ -7,18 +8,18 @@ namespace Fido2NetLib;
public sealed class AuthenticatorAttestationRawResponse
{
[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("id")]
public byte[] Id { get; set; }
[JsonPropertyName("id"), Required]
public byte[] Id { get; init; }

[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("rawId")]
public byte[] RawId { get; set; }
[JsonPropertyName("rawId"), Required]
public byte[] RawId { get; init; }

[JsonPropertyName("type")]
public PublicKeyCredentialType? Type { get; set; }
[JsonPropertyName("type"), Required]
public PublicKeyCredentialType Type { get; init; }

[JsonPropertyName("response")]
public AttestationResponse Response { get; set; }
[JsonPropertyName("response"), Required]
public AttestationResponse Response { get; init; }

[JsonPropertyName("extensions")]
[Obsolete("Use ClientExtensionResults instead")]
Expand All @@ -28,20 +29,20 @@ public AuthenticationExtensionsClientOutputs Extensions
set => ClientExtensionResults = value;
}

[JsonPropertyName("clientExtensionResults")]
[JsonPropertyName("clientExtensionResults"), Required]
public AuthenticationExtensionsClientOutputs ClientExtensionResults { get; set; }

public sealed class AttestationResponse
{
[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("attestationObject")]
public byte[] AttestationObject { get; set; }
public required byte[] AttestationObject { get; init; }

[JsonConverter(typeof(Base64UrlConverter))]
[JsonPropertyName("clientDataJSON")]
public byte[] ClientDataJson { get; set; }
public required byte[] ClientDataJson { get; init; }

[JsonPropertyName("transports")]
public AuthenticatorTransport[] Transports { get; set; }
[JsonPropertyName("transports"), Required]
public AuthenticatorTransport[] Transports { get; init; }
}
}
8 changes: 4 additions & 4 deletions Src/Fido2.Models/CredentialCreateOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,27 @@ public sealed class CredentialCreateOptions
/// Its value’s id member specifies the relying party identifier with which the credential should be associated.If omitted, its value will be the CredentialsContainer object’s relevant settings object's origin's effective domain.
/// </summary>
[JsonPropertyName("rp")]
public PublicKeyCredentialRpEntity Rp { get; set; }
public required PublicKeyCredentialRpEntity Rp { get; set; }

/// <summary>
/// This member contains data about the user account for which the Relying Party is requesting attestation.
/// Its value’s name, displayName and id members are required.
/// </summary>
[JsonPropertyName("user")]
public Fido2User User { get; set; }
public required Fido2User User { get; set; }

/// <summary>
/// Must be generated by the Server (Relying Party)
/// </summary>
[JsonPropertyName("challenge")]
[JsonConverter(typeof(Base64UrlConverter))]
public byte[] Challenge { get; set; }
public required byte[] Challenge { get; set; }

/// <summary>
/// This member contains information about the desired properties of the credential to be created. The sequence is ordered from most preferred to least preferred. The platform makes a best-effort to create the most preferred credential that it can.
/// </summary>
[JsonPropertyName("pubKeyCredParams")]
public IReadOnlyList<PubKeyCredParam> PubKeyCredParams { get; set; }
public required IReadOnlyList<PubKeyCredParam> PubKeyCredParams { get; set; }

/// <summary>
/// This member specifies a time, in milliseconds, that the caller is willing to wait for the call to complete. This is treated as a hint, and MAY be overridden by the platform.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public sealed class AuthenticationExtensionsLargeBlobOutputs
/// https://w3c.github.io/webauthn/#dom-authenticationextensionslargebloboutputs-supported
/// </summary>
[JsonPropertyName("supported")]
public bool Supported { get; set; } = false;
public bool Supported { get; init; } = false;

/// <summary>
/// The blob read from the authenticator.
Expand All @@ -34,7 +34,7 @@ public sealed class AuthenticationExtensionsLargeBlobOutputs
[JsonConverter(typeof(Base64UrlConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("blob")]
public byte[]? Blob { get; set; }
public byte[]? Blob { get; init; }

/// <summary>
/// Whether or not a blob was written to the authenticator.
Expand All @@ -44,5 +44,5 @@ public sealed class AuthenticationExtensionsLargeBlobOutputs
/// https://w3c.github.io/webauthn/#dom-authenticationextensionslargebloboutputs-written
/// </summary>
[JsonPropertyName("written")]
public bool Written { get; set; } = false;
public bool Written { get; init; } = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public sealed class AuthenticationExtensionsPRFOutputs
/// If PRFs are available for use with the created credential.
/// </summary>
[JsonPropertyName("enabled")]
public bool Enabled { get; set; }
public bool Enabled { get; init; }

/// <summary>
/// The results of evaluating the PRF inputs.
/// </summary>
[JsonPropertyName("results")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public AuthenticationExtensionsPRFValues Results { get; set; }
public AuthenticationExtensionsPRFValues Results { get; init; }
}
4 changes: 2 additions & 2 deletions Src/Fido2.Models/Objects/AuthenticationExtensionsPRFValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ public sealed class AuthenticationExtensionsPRFValues
/// </summary>
[JsonPropertyName("first")]
[JsonConverter(typeof(Base64UrlConverter))]
public required byte[] First { get; set; }
public required byte[] First { get; init; }

/// <summary>
/// salt2 value to the PRF evaluation.
/// </summary>
[JsonPropertyName("second")]
[JsonConverter(typeof(Base64UrlConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public byte[]? Second { get; set; }
public byte[]? Second { get; init; }
}

5 changes: 2 additions & 3 deletions Src/Fido2.Models/Objects/CredentialPropertiesOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ public class CredentialPropertiesOutput
/// This OPTIONAL property, known abstractly as the resident key credential property (i.e., client-side discoverable credential property), is a Boolean value indicating whether the PublicKeyCredential returned as a result of a registration ceremony is a client-side discoverable credential. If rk is true, the credential is a discoverable credential. if rk is false, the credential is a server-side credential. If rk is not present, it is not known whether the credential is a discoverable credential or a server-side credential.
/// </summary>
[JsonPropertyName("rk")]
public bool Rk { get; set; }

public bool Rk { get; init; }

/// <summary>
/// This OPTIONAL property is a human-palatable description of the credential’s managing authenticator, chosen by the user.
/// https://w3c.github.io/webauthn/#dom-credentialpropertiesoutput-authenticatordisplayname
/// </summary>
[JsonPropertyName("authenticatorDisplayName")]
public string? AuthenticatorDisplayName { get; set; }
public string? AuthenticatorDisplayName { get; init; }
}
4 changes: 4 additions & 0 deletions Src/Fido2.Models/Objects/KeyProtection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,25 @@ public enum KeyProtection
/// </summary>
[EnumMember(Value = "software")]
SOFTWARE = 1,

/// <summary>
/// This flag should be set if the authenticator uses hardware-based key management. Exclusive in authenticator metadata with KEY_PROTECTION_SOFTWARE
/// </summary>
[EnumMember(Value = "hardware")]
HARDWARE = 2,

/// <summary>
/// This flag should be set if the authenticator uses the Trusted Execution Environment [TEE] for key management. In authenticator metadata, this flag should be set in conjunction with KEY_PROTECTION_HARDWARE. Exclusive in authenticator metadata with KEY_PROTECTION_SOFTWARE, KEY_PROTECTION_SECURE_ELEMENT
/// </summary>
[EnumMember(Value = "tee")]
TEE = 4,

/// <summary>
/// This flag should be set if the authenticator uses a Secure Element [SecureElement] for key management. In authenticator metadata, this flag should be set in conjunction with KEY_PROTECTION_HARDWARE. Exclusive in authenticator metadata with KEY_PROTECTION_TEE, KEY_PROTECTION_SOFTWARE
/// </summary>
[EnumMember(Value = "secure_element")]
SECURE_ELEMENT = 0x8,

/// <summary>
/// This flag must be set if the authenticator does not store (wrapped) UAuth keys at the client, but relies on a server-provided key handle. This flag must be set in conjunction with one of the other KEY_PROTECTION flags to indicate how the local key handle wrapping key and operations are protected. Servers may unset this flag in authenticator policy if they are not prepared to store and return key handles, for example, if they have a requirement to respond indistinguishably to authentication attempts against userIDs that do and do not exist. Refer to [UAFProtocol] for more details.
/// </summary>
Expand Down
6 changes: 4 additions & 2 deletions Src/Fido2.Models/Objects/LargeBlobSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ public enum LargeBlobSupport
/// <summary>
/// largeBlob support is required -- credential creation will fail if largeBlob is not supported
/// </summary>
[EnumMember(Value = "required")] Required,
[EnumMember(Value = "required")]
Required,

/// <summary>
/// largeBlob support is preferred -- credential creation will succeed even if largeBlob is not supported.
/// </summary>
[EnumMember(Value = "preferred")] Preferred
[EnumMember(Value = "preferred")]
Preferred
}
4 changes: 2 additions & 2 deletions Src/Fido2.Models/Objects/Version.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public class Version
/// Major version.
/// </summary>
[JsonPropertyName("major")]
public ushort Major { get; set; }
public ushort Major { get; init; }

/// <summary>
/// Minor version.
/// </summary>
[JsonPropertyName("minor")]
public ushort Minor { get; set; }
public ushort Minor { get; init; }
}
2 changes: 1 addition & 1 deletion Src/Fido2/AuthenticatorAttestationResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public async Task<RegisteredPublicKeyCredential> VerifyAsync(

return new RegisteredPublicKeyCredential
{
Type = Raw.Type.Value,
Type = Raw.Type,
Id = authData.AttestedCredentialData.CredentialId,
PublicKey = authData.AttestedCredentialData.CredentialPublicKey.GetBytes(),
SignCount = authData.SignCount,
Expand Down
1 change: 1 addition & 0 deletions Src/Fido2/GetAssertionOptionsParams.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;

using Fido2NetLib.Objects;

namespace Fido2NetLib;
Expand Down
3 changes: 1 addition & 2 deletions Src/Fido2/IFido2.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading;
using System.Threading.Tasks;

using Fido2NetLib.Objects;
Expand Down
1 change: 1 addition & 0 deletions Src/Fido2/RequestNewCredentialParams.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;

using Fido2NetLib.Objects;

namespace Fido2NetLib;
Expand Down
5 changes: 4 additions & 1 deletion Tests/Fido2.Tests/AuthenticatorResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ public void TestAuthenticatorAttestationResponseAttestationObjectNull(byte[] val
Response = new AuthenticatorAttestationRawResponse.AttestationResponse
{
AttestationObject = value,
ClientDataJson = null!
}
};
var ex = Assert.Throws<Fido2VerificationException>(() => AuthenticatorAttestationResponse.Parse(rawResponse));
Expand All @@ -345,6 +346,7 @@ public void TestAuthenticatorAttestationObjectBadCBOR(byte[] value)
Response = new AuthenticatorAttestationRawResponse.AttestationResponse
{
AttestationObject = value,
ClientDataJson = null!
}
};

Expand All @@ -370,7 +372,8 @@ public void TestAuthenticatorAttestationObjectMalformed(byte[] value)
{
Response = new AuthenticatorAttestationRawResponse.AttestationResponse
{
AttestationObject = value
AttestationObject = value,
ClientDataJson = null!
}
};

Expand Down
Loading