Skip to content

Commit b7f1735

Browse files
authoredDec 11, 2024··
[Models] Enable nullable (1 of x) (#581)
* Match requireness of various properties to specification * React to requireness changes * Make various models immutable * Format code
1 parent f8471ac commit b7f1735

15 files changed

+61
-48
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable disable
22

3+
using System.ComponentModel.DataAnnotations;
34
using System.Text.Json.Serialization;
45

56
using Fido2NetLib.Objects;
@@ -12,19 +13,19 @@ namespace Fido2NetLib;
1213
public class AuthenticatorAssertionRawResponse
1314
{
1415
[JsonConverter(typeof(Base64UrlConverter))]
15-
[JsonPropertyName("id")]
16-
public byte[] Id { get; set; }
16+
[JsonPropertyName("id"), Required]
17+
public byte[] Id { get; init; }
1718

1819
// might be wrong to base64url encode this...
1920
[JsonConverter(typeof(Base64UrlConverter))]
20-
[JsonPropertyName("rawId")]
21-
public byte[] RawId { get; set; }
21+
[JsonPropertyName("rawId"), Required]
22+
public byte[] RawId { get; init; }
2223

2324
[JsonPropertyName("response")]
24-
public AssertionResponse Response { get; set; }
25+
public AssertionResponse Response { get; init; }
2526

26-
[JsonPropertyName("type")]
27-
public PublicKeyCredentialType? Type { get; set; }
27+
[JsonPropertyName("type"), Required]
28+
public PublicKeyCredentialType Type { get; init; }
2829

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

37-
[JsonPropertyName("clientExtensionResults")]
38+
[JsonPropertyName("clientExtensionResults"), Required]
3839
public AuthenticationExtensionsClientOutputs ClientExtensionResults { get; set; }
3940

4041
public sealed class AssertionResponse
4142
{
4243
[JsonConverter(typeof(Base64UrlConverter))]
4344
[JsonPropertyName("authenticatorData")]
44-
public byte[] AuthenticatorData { get; set; }
45+
public required byte[] AuthenticatorData { get; init; }
4546

4647
[JsonConverter(typeof(Base64UrlConverter))]
4748
[JsonPropertyName("signature")]
48-
public byte[] Signature { get; set; }
49+
public required byte[] Signature { get; init; }
4950

5051
[JsonConverter(typeof(Base64UrlConverter))]
5152
[JsonPropertyName("clientDataJSON")]
52-
public byte[] ClientDataJson { get; set; }
53+
public required byte[] ClientDataJson { get; init; }
54+
5355
#nullable enable
56+
5457
[JsonPropertyName("userHandle")]
5558
[JsonConverter(typeof(Base64UrlConverter))]
56-
public byte[]? UserHandle { get; set; }
59+
public byte[]? UserHandle { get; init; }
5760
}
5861
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Text.Json.Serialization;
1+
using System.ComponentModel.DataAnnotations;
2+
using System.Text.Json.Serialization;
23

34
using Fido2NetLib.Objects;
45

@@ -7,18 +8,18 @@ namespace Fido2NetLib;
78
public sealed class AuthenticatorAttestationRawResponse
89
{
910
[JsonConverter(typeof(Base64UrlConverter))]
10-
[JsonPropertyName("id")]
11-
public byte[] Id { get; set; }
11+
[JsonPropertyName("id"), Required]
12+
public byte[] Id { get; init; }
1213

1314
[JsonConverter(typeof(Base64UrlConverter))]
14-
[JsonPropertyName("rawId")]
15-
public byte[] RawId { get; set; }
15+
[JsonPropertyName("rawId"), Required]
16+
public byte[] RawId { get; init; }
1617

17-
[JsonPropertyName("type")]
18-
public PublicKeyCredentialType? Type { get; set; }
18+
[JsonPropertyName("type"), Required]
19+
public PublicKeyCredentialType Type { get; init; }
1920

20-
[JsonPropertyName("response")]
21-
public AttestationResponse Response { get; set; }
21+
[JsonPropertyName("response"), Required]
22+
public AttestationResponse Response { get; init; }
2223

2324
[JsonPropertyName("extensions")]
2425
[Obsolete("Use ClientExtensionResults instead")]
@@ -28,20 +29,20 @@ public AuthenticationExtensionsClientOutputs Extensions
2829
set => ClientExtensionResults = value;
2930
}
3031

31-
[JsonPropertyName("clientExtensionResults")]
32+
[JsonPropertyName("clientExtensionResults"), Required]
3233
public AuthenticationExtensionsClientOutputs ClientExtensionResults { get; set; }
3334

3435
public sealed class AttestationResponse
3536
{
3637
[JsonConverter(typeof(Base64UrlConverter))]
3738
[JsonPropertyName("attestationObject")]
38-
public byte[] AttestationObject { get; set; }
39+
public required byte[] AttestationObject { get; init; }
3940

4041
[JsonConverter(typeof(Base64UrlConverter))]
4142
[JsonPropertyName("clientDataJSON")]
42-
public byte[] ClientDataJson { get; set; }
43+
public required byte[] ClientDataJson { get; init; }
4344

44-
[JsonPropertyName("transports")]
45-
public AuthenticatorTransport[] Transports { get; set; }
45+
[JsonPropertyName("transports"), Required]
46+
public AuthenticatorTransport[] Transports { get; init; }
4647
}
4748
}

‎Src/Fido2.Models/CredentialCreateOptions.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,27 @@ public sealed class CredentialCreateOptions
1515
/// 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.
1616
/// </summary>
1717
[JsonPropertyName("rp")]
18-
public PublicKeyCredentialRpEntity Rp { get; set; }
18+
public required PublicKeyCredentialRpEntity Rp { get; set; }
1919

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

2727
/// <summary>
2828
/// Must be generated by the Server (Relying Party)
2929
/// </summary>
3030
[JsonPropertyName("challenge")]
3131
[JsonConverter(typeof(Base64UrlConverter))]
32-
public byte[] Challenge { get; set; }
32+
public required byte[] Challenge { get; set; }
3333

3434
/// <summary>
3535
/// 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.
3636
/// </summary>
3737
[JsonPropertyName("pubKeyCredParams")]
38-
public IReadOnlyList<PubKeyCredParam> PubKeyCredParams { get; set; }
38+
public required IReadOnlyList<PubKeyCredParam> PubKeyCredParams { get; set; }
3939

4040
/// <summary>
4141
/// 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.

‎Src/Fido2.Models/Objects/AuthenticationExtensionsLargeBlobOutputs.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public sealed class AuthenticationExtensionsLargeBlobOutputs
2222
/// https://w3c.github.io/webauthn/#dom-authenticationextensionslargebloboutputs-supported
2323
/// </summary>
2424
[JsonPropertyName("supported")]
25-
public bool Supported { get; set; } = false;
25+
public bool Supported { get; init; } = false;
2626

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

3939
/// <summary>
4040
/// Whether or not a blob was written to the authenticator.
@@ -44,5 +44,5 @@ public sealed class AuthenticationExtensionsLargeBlobOutputs
4444
/// https://w3c.github.io/webauthn/#dom-authenticationextensionslargebloboutputs-written
4545
/// </summary>
4646
[JsonPropertyName("written")]
47-
public bool Written { get; set; } = false;
47+
public bool Written { get; init; } = false;
4848
}

‎Src/Fido2.Models/Objects/AuthenticationExtensionsPRFOutputs.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ public sealed class AuthenticationExtensionsPRFOutputs
1111
/// If PRFs are available for use with the created credential.
1212
/// </summary>
1313
[JsonPropertyName("enabled")]
14-
public bool Enabled { get; set; }
14+
public bool Enabled { get; init; }
1515

1616
/// <summary>
1717
/// The results of evaluating the PRF inputs.
1818
/// </summary>
1919
[JsonPropertyName("results")]
2020
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
21-
public AuthenticationExtensionsPRFValues Results { get; set; }
21+
public AuthenticationExtensionsPRFValues Results { get; init; }
2222
}

‎Src/Fido2.Models/Objects/AuthenticationExtensionsPRFValues.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ public sealed class AuthenticationExtensionsPRFValues
1414
/// </summary>
1515
[JsonPropertyName("first")]
1616
[JsonConverter(typeof(Base64UrlConverter))]
17-
public required byte[] First { get; set; }
17+
public required byte[] First { get; init; }
1818

1919
/// <summary>
2020
/// salt2 value to the PRF evaluation.
2121
/// </summary>
2222
[JsonPropertyName("second")]
2323
[JsonConverter(typeof(Base64UrlConverter))]
2424
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
25-
public byte[]? Second { get; set; }
25+
public byte[]? Second { get; init; }
2626
}
2727

‎Src/Fido2.Models/Objects/CredentialPropertiesOutput.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ public class CredentialPropertiesOutput
1212
/// 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.
1313
/// </summary>
1414
[JsonPropertyName("rk")]
15-
public bool Rk { get; set; }
16-
15+
public bool Rk { get; init; }
1716

1817
/// <summary>
1918
/// This OPTIONAL property is a human-palatable description of the credential’s managing authenticator, chosen by the user.
2019
/// https://w3c.github.io/webauthn/#dom-credentialpropertiesoutput-authenticatordisplayname
2120
/// </summary>
2221
[JsonPropertyName("authenticatorDisplayName")]
23-
public string? AuthenticatorDisplayName { get; set; }
22+
public string? AuthenticatorDisplayName { get; init; }
2423
}

‎Src/Fido2.Models/Objects/KeyProtection.cs

+4
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,25 @@ public enum KeyProtection
1919
/// </summary>
2020
[EnumMember(Value = "software")]
2121
SOFTWARE = 1,
22+
2223
/// <summary>
2324
/// This flag should be set if the authenticator uses hardware-based key management. Exclusive in authenticator metadata with KEY_PROTECTION_SOFTWARE
2425
/// </summary>
2526
[EnumMember(Value = "hardware")]
2627
HARDWARE = 2,
28+
2729
/// <summary>
2830
/// 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
2931
/// </summary>
3032
[EnumMember(Value = "tee")]
3133
TEE = 4,
34+
3235
/// <summary>
3336
/// 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
3437
/// </summary>
3538
[EnumMember(Value = "secure_element")]
3639
SECURE_ELEMENT = 0x8,
40+
3741
/// <summary>
3842
/// 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.
3943
/// </summary>

‎Src/Fido2.Models/Objects/LargeBlobSupport.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ public enum LargeBlobSupport
1414
/// <summary>
1515
/// largeBlob support is required -- credential creation will fail if largeBlob is not supported
1616
/// </summary>
17-
[EnumMember(Value = "required")] Required,
17+
[EnumMember(Value = "required")]
18+
Required,
1819

1920
/// <summary>
2021
/// largeBlob support is preferred -- credential creation will succeed even if largeBlob is not supported.
2122
/// </summary>
22-
[EnumMember(Value = "preferred")] Preferred
23+
[EnumMember(Value = "preferred")]
24+
Preferred
2325
}

‎Src/Fido2.Models/Objects/Version.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ public class Version
1414
/// Major version.
1515
/// </summary>
1616
[JsonPropertyName("major")]
17-
public ushort Major { get; set; }
17+
public ushort Major { get; init; }
1818

1919
/// <summary>
2020
/// Minor version.
2121
/// </summary>
2222
[JsonPropertyName("minor")]
23-
public ushort Minor { get; set; }
23+
public ushort Minor { get; init; }
2424
}

‎Src/Fido2/AuthenticatorAttestationResponse.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public async Task<RegisteredPublicKeyCredential> VerifyAsync(
184184

185185
return new RegisteredPublicKeyCredential
186186
{
187-
Type = Raw.Type.Value,
187+
Type = Raw.Type,
188188
Id = authData.AttestedCredentialData.CredentialId,
189189
PublicKey = authData.AttestedCredentialData.CredentialPublicKey.GetBytes(),
190190
SignCount = authData.SignCount,

‎Src/Fido2/GetAssertionOptionsParams.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
34
using Fido2NetLib.Objects;
45

56
namespace Fido2NetLib;

‎Src/Fido2/IFido2.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Collections.Generic;
2-
using System.Threading;
1+
using System.Threading;
32
using System.Threading.Tasks;
43

54
using Fido2NetLib.Objects;

‎Src/Fido2/RequestNewCredentialParams.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
34
using Fido2NetLib.Objects;
45

56
namespace Fido2NetLib;

‎Tests/Fido2.Tests/AuthenticatorResponse.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ public void TestAuthenticatorAttestationResponseAttestationObjectNull(byte[] val
330330
Response = new AuthenticatorAttestationRawResponse.AttestationResponse
331331
{
332332
AttestationObject = value,
333+
ClientDataJson = null!
333334
}
334335
};
335336
var ex = Assert.Throws<Fido2VerificationException>(() => AuthenticatorAttestationResponse.Parse(rawResponse));
@@ -345,6 +346,7 @@ public void TestAuthenticatorAttestationObjectBadCBOR(byte[] value)
345346
Response = new AuthenticatorAttestationRawResponse.AttestationResponse
346347
{
347348
AttestationObject = value,
349+
ClientDataJson = null!
348350
}
349351
};
350352

@@ -370,7 +372,8 @@ public void TestAuthenticatorAttestationObjectMalformed(byte[] value)
370372
{
371373
Response = new AuthenticatorAttestationRawResponse.AttestationResponse
372374
{
373-
AttestationObject = value
375+
AttestationObject = value,
376+
ClientDataJson = null!
374377
}
375378
};
376379

0 commit comments

Comments
 (0)
Please sign in to comment.