Skip to content

Commit

Permalink
Remove base-class, Status and ErrorMessage (#529)
Browse files Browse the repository at this point in the history
* Remove base-class

* Removed usage of Status/ErrorMessage in tests

* Rename MakeNewCredentialResult.Result to .Credential

* format

* Removed MakeNewCredentialResult

* fixed after rebase

* Passes conformance tests

* undo local changes

* small fix

* small fix
abergs authored Jul 16, 2024
1 parent 184f70f commit cb71a15
Showing 23 changed files with 182 additions and 305 deletions.
5 changes: 0 additions & 5 deletions BlazorWasmDemo/Client/Shared/UserService.cs
Original file line number Diff line number Diff line change
@@ -134,11 +134,6 @@ public async Task<string> LoginAsync(string? username)
return "No options received";
}

if (options.Status != "ok")
{
return options.ErrorMessage ?? string.Empty;
}

// Present options to user and get response (usernameless users will be asked by their authenticator, which credential they want to use to sign the challenge)
var assertion = await _webAuthn.VerifyAsync(options);

54 changes: 22 additions & 32 deletions BlazorWasmDemo/Server/Controllers/UserController.cs
Original file line number Diff line number Diff line change
@@ -126,9 +126,9 @@ public CredentialCreateOptions GetCredentialOptions(
// 6. return options to client
return options;
}
catch (Exception e)
catch (Exception)
{
return new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) };
throw;
}
}

@@ -150,29 +150,25 @@ public async Task<string> CreateCredentialAsync([FromRoute] string username, [Fr
// 2. Create callback so that lib can verify credential id is unique to this user

// 3. Verify and make the credentials
var result = await _fido2.MakeNewCredentialAsync(attestationResponse, options, CredentialIdUniqueToUserAsync, cancellationToken: cancellationToken);

if (result.Status is "error" || result.Result is null)
{
return result.ErrorMessage ?? string.Empty;
}
var credential = await _fido2.MakeNewCredentialAsync(attestationResponse, options, CredentialIdUniqueToUserAsync, cancellationToken: cancellationToken);

// 4. Store the credentials in db
_demoStorage.AddCredentialToUser(options.User, new StoredCredential
{
AttestationFormat = result.Result.AttestationFormat,
Id = result.Result.Id,
PublicKey = result.Result.PublicKey,
UserHandle = result.Result.User.Id,
SignCount = result.Result.SignCount,

AttestationFormat = credential.AttestationFormat,
Id = credential.Id,
PublicKey = credential.PublicKey,
UserHandle = credential.User.Id,
SignCount = credential.SignCount,
RegDate = DateTimeOffset.UtcNow,
AaGuid = result.Result.AaGuid,
DevicePublicKeys = [result.Result.DevicePublicKey],
Transports = result.Result.Transports,
IsBackupEligible = result.Result.IsBackupEligible,
IsBackedUp = result.Result.IsBackedUp,
AttestationObject = result.Result.AttestationObject,
AttestationClientDataJson = result.Result.AttestationClientDataJson,
AaGuid = credential.AaGuid,
DevicePublicKeys = [credential.DevicePublicKey],
Transports = credential.Transports,
IsBackupEligible = credential.IsBackupEligible,
IsBackedUp = credential.IsBackedUp,
AttestationObject = credential.AttestationObject,
AttestationClientDataJson = credential.AttestationClientDataJson,
});

// 5. Now we need to remove the options from the pending dictionary
@@ -228,9 +224,9 @@ public AssertionOptions MakeAssertionOptions([FromRoute] string? username, [From
// 5. return options to client
return options;
}
catch (Exception e)
catch (Exception)
{
return new AssertionOptions { Status = "error", ErrorMessage = FormatException(e) };
throw;
}
}

@@ -280,19 +276,13 @@ public async Task<string> MakeAssertionAsync([FromBody] AuthenticatorAssertionRa
cancellationToken: cancellationToken);

// 4. Store the updated counter
if (res.Status is "ok")
_demoStorage.UpdateCounter(res.CredentialId, res.SignCount);
if (res.DevicePublicKey is not null)
{
_demoStorage.UpdateCounter(res.CredentialId, res.SignCount);
if (res.DevicePublicKey is not null)
{
creds.DevicePublicKeys.Add(res.DevicePublicKey);
}
}
else
{
return $"Error: {res.ErrorMessage}";
creds.DevicePublicKeys.Add(res.DevicePublicKey);
}


// 5. return result to client
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateEncodedJwt(
36 changes: 18 additions & 18 deletions Demo/Controller.cs
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ public JsonResult MakeCredentialOptions([FromForm] string username,
}
catch (Exception e)
{
return Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) });
return Json(new { Status = "error", ErrorMessage = FormatException(e) });
}
}

@@ -106,32 +106,32 @@ public async Task<JsonResult> MakeCredential([FromBody] AuthenticatorAttestation
};

// 2. Verify and make the credentials
var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback, cancellationToken: cancellationToken);
var credential = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback, cancellationToken: cancellationToken);

// 3. Store the credentials in db
DemoStorage.AddCredentialToUser(options.User, new StoredCredential
{
Id = success.Result.Id,
PublicKey = success.Result.PublicKey,
UserHandle = success.Result.User.Id,
SignCount = success.Result.SignCount,
AttestationFormat = success.Result.AttestationFormat,
Id = credential.Id,
PublicKey = credential.PublicKey,
UserHandle = credential.User.Id,
SignCount = credential.SignCount,
AttestationFormat = credential.AttestationFormat,
RegDate = DateTimeOffset.UtcNow,
AaGuid = success.Result.AaGuid,
Transports = success.Result.Transports,
IsBackupEligible = success.Result.IsBackupEligible,
IsBackedUp = success.Result.IsBackedUp,
AttestationObject = success.Result.AttestationObject,
AttestationClientDataJson = success.Result.AttestationClientDataJson,
DevicePublicKeys = [success.Result.DevicePublicKey]
AaGuid = credential.AaGuid,
Transports = credential.Transports,
IsBackupEligible = credential.IsBackupEligible,
IsBackedUp = credential.IsBackedUp,
AttestationObject = credential.AttestationObject,
AttestationClientDataJson = credential.AttestationClientDataJson,
DevicePublicKeys = [credential.DevicePublicKey]
});

// 4. return "ok" to the client
return Json(success);
return Json(credential);
}
catch (Exception e)
{
return Json(new MakeNewCredentialResult(status: "error", errorMessage: FormatException(e), result: null));
return Json(new { status = "error", errorMessage = FormatException(e) });
}
}

@@ -176,7 +176,7 @@ public ActionResult AssertionOptionsPost([FromForm] string username, [FromForm]

catch (Exception e)
{
return Json(new AssertionOptions { Status = "error", ErrorMessage = FormatException(e) });
return Json(new { Status = "error", ErrorMessage = FormatException(e) });
}
}

@@ -217,7 +217,7 @@ public async Task<JsonResult> MakeAssertion([FromBody] AuthenticatorAssertionRaw
}
catch (Exception e)
{
return Json(new VerifyAssertionResult { Status = "error", ErrorMessage = FormatException(e) });
return Json(new { Status = "error", ErrorMessage = FormatException(e) });
}
}
}
33 changes: 22 additions & 11 deletions Demo/TestController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Text;

using System.Text.Json;
using System.Text.Json.Serialization;
using Fido2NetLib;
using Fido2NetLib.Development;
using Fido2NetLib.Objects;
@@ -34,7 +35,7 @@ public TestController(IOptions<Fido2Configuration> fido2Configuration)

[HttpPost]
[Route("/attestation/options")]
public JsonResult MakeCredentialOptionsTest([FromBody] TEST_MakeCredentialParams opts)
public OkObjectResult MakeCredentialOptionsTest([FromBody] TEST_MakeCredentialParams opts)
{
var attType = opts.Attestation;

@@ -72,12 +73,16 @@ public JsonResult MakeCredentialOptionsTest([FromBody] TEST_MakeCredentialParams
HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson());

// 5. return options to client
return Json(options);

var jsonResponse = JsonSerializer.SerializeToNode(options);
jsonResponse["status"] = "ok";
jsonResponse["errorMessage"] = "";
return new OkObjectResult(jsonResponse);
}

[HttpPost]
[Route("/attestation/result")]
public async Task<JsonResult> MakeCredentialResultTestAsync([FromBody] AuthenticatorAttestationRawResponse attestationResponse, CancellationToken cancellationToken)
public async Task<OkObjectResult> MakeCredentialResultTestAsync([FromBody] AuthenticatorAttestationRawResponse attestationResponse, CancellationToken cancellationToken)
{
// 1. get the options we sent the client
var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
@@ -91,19 +96,22 @@ public async Task<JsonResult> MakeCredentialResultTestAsync([FromBody] Authentic
};

// 2. Verify and make the credentials
var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback, cancellationToken: cancellationToken);
var credential = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback, cancellationToken: cancellationToken);

// 3. Store the credentials in db
_demoStorage.AddCredentialToUser(options.User, new StoredCredential
{
Id = success.Result.Id,
PublicKey = success.Result.PublicKey,
UserHandle = success.Result.User.Id,
SignCount = success.Result.SignCount
Id = credential.Id,
PublicKey = credential.PublicKey,
UserHandle = credential.User.Id,
SignCount = credential.SignCount
});

// 4. return "ok" to the client
return Json(success);
var jsonResponse = JsonSerializer.SerializeToNode(credential);
jsonResponse["status"] = "ok";
jsonResponse["errorMessage"] = "";
return new OkObjectResult(jsonResponse);
}

[HttpPost]
@@ -142,7 +150,10 @@ public IActionResult AssertionOptionsTest([FromBody] TEST_AssertionClientParams
HttpContext.Session.SetString("fido2.assertionOptions", options.ToJson());

// 5. Return options to client
return Json(options);
var jsonResponse = JsonSerializer.SerializeToNode(options);
jsonResponse["status"] = "ok";
jsonResponse["errorMessage"] = "";
return new OkObjectResult(jsonResponse);
}

[HttpPost]
4 changes: 1 addition & 3 deletions Src/Fido2.Models/AssertionOptions.cs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ namespace Fido2NetLib;
/// <summary>
/// Sent to the browser when we want to Assert credentials and authenticate a user
/// </summary>
public class AssertionOptions : Fido2ResponseBase
public class AssertionOptions
{
/// <summary>
/// This member represents a challenge that the selected authenticator signs, along with other data, when producing an authentication assertion.
@@ -71,8 +71,6 @@ public static AssertionOptions Create(
{
return new AssertionOptions()
{
Status = "ok",
ErrorMessage = string.Empty,
Challenge = challenge,
Timeout = config.Timeout,
RpId = config.ServerDomain,
4 changes: 1 addition & 3 deletions Src/Fido2.Models/CredentialCreateOptions.cs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@

namespace Fido2NetLib;

public sealed class CredentialCreateOptions : Fido2ResponseBase
public sealed class CredentialCreateOptions
{
/// <summary>
///
@@ -117,8 +117,6 @@ public static CredentialCreateOptions Create(
{
return new CredentialCreateOptions
{
Status = "ok",
ErrorMessage = string.Empty,
Challenge = challenge,
Rp = new PublicKeyCredentialRpEntity(config.ServerDomain, config.ServerName, config.ServerIcon),
Timeout = config.Timeout,
14 changes: 0 additions & 14 deletions Src/Fido2.Models/Fido2ResponseBase.cs

This file was deleted.

20 changes: 0 additions & 20 deletions Src/Fido2.Models/Objects/MakeNewCredentialResult.cs

This file was deleted.

2 changes: 1 addition & 1 deletion Src/Fido2.Models/Objects/RegisteredPublicKeyCredential.cs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ namespace Fido2NetLib.Objects;
/// <summary>
/// Holds parsed credential data
/// </summary>
public class RegisteredPublicKeyCredential : Fido2ResponseBase
public class RegisteredPublicKeyCredential
{
/// <summary>
/// The type of the public key credential source.
2 changes: 1 addition & 1 deletion Src/Fido2.Models/Objects/VerifyAssertionResult.cs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
/// <summary>
/// Result of the MakeAssertion verification
/// </summary>
public class VerifyAssertionResult : Fido2ResponseBase
public class VerifyAssertionResult
{
public byte[] CredentialId { get; init; }

1 change: 0 additions & 1 deletion Src/Fido2/AuthenticatorAssertionResponse.cs
Original file line number Diff line number Diff line change
@@ -176,7 +176,6 @@ public async Task<VerifyAssertionResult> VerifyAsync(

return new VerifyAssertionResult
{
Status = "ok",
CredentialId = Raw.Id,
SignCount = authData.SignCount,
IsBackedUp = authData.IsBackedUp,
13 changes: 4 additions & 9 deletions Src/Fido2/Fido2.cs
Original file line number Diff line number Diff line change
@@ -67,21 +67,16 @@ public CredentialCreateOptions RequestNewCredential(
/// <param name="isCredentialIdUniqueToUser">The delegate used to validate that the CredentialID is unique to this user.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns></returns>
public async Task<MakeNewCredentialResult> MakeNewCredentialAsync(
public async Task<RegisteredPublicKeyCredential> MakeNewCredentialAsync(
AuthenticatorAttestationRawResponse attestationResponse,
CredentialCreateOptions originalOptions,
IsCredentialIdUniqueToUserAsyncDelegate isCredentialIdUniqueToUser,
CancellationToken cancellationToken = default)
{
var parsedResponse = AuthenticatorAttestationResponse.Parse(attestationResponse);
var success = await parsedResponse.VerifyAsync(originalOptions, _config, isCredentialIdUniqueToUser, _metadataService, cancellationToken);

// todo: Set Errormessage etc.
return new MakeNewCredentialResult(
status: "ok",
errorMessage: string.Empty,
result: success
);
var credential = await parsedResponse.VerifyAsync(originalOptions, _config, isCredentialIdUniqueToUser, _metadataService, cancellationToken);

return credential;
}

/// <summary>
2 changes: 1 addition & 1 deletion Src/Fido2/IFido2.cs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ Task<VerifyAssertionResult> MakeAssertionAsync(
IsUserHandleOwnerOfCredentialIdAsync isUserHandleOwnerOfCredentialIdCallback,
CancellationToken cancellationToken = default);

Task<MakeNewCredentialResult> MakeNewCredentialAsync(
Task<RegisteredPublicKeyCredential> MakeNewCredentialAsync(
AuthenticatorAttestationRawResponse attestationResponse,
CredentialCreateOptions originalOptions,
IsCredentialIdUniqueToUserAsyncDelegate isCredentialIdUniqueToUser,
24 changes: 10 additions & 14 deletions Test/Attestation/AndroidKey.cs
Original file line number Diff line number Diff line change
@@ -63,20 +63,16 @@ public AndroidKey()
[Fact]
public async Task TestAndroidKey()
{
var res = await MakeAttestationResponseAsync();
Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("android-key", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
Assert.Equal(new[] { AuthenticatorTransport.Internal }, res.Result.Transports);
var credential = await MakeAttestationResponseAsync();
Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("android-key", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
Assert.Equal(new[] { AuthenticatorTransport.Internal }, credential.Transports);
}

[Fact]
46 changes: 19 additions & 27 deletions Test/Attestation/AndroidSafetyNet.cs
Original file line number Diff line number Diff line change
@@ -99,20 +99,16 @@ public AndroidSafetyNet()
[Fact]
public async Task TestAndroidSafetyNet()
{
var res = await MakeAttestationResponseAsync();
Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("android-safetynet", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
Assert.Equal([AuthenticatorTransport.Internal], res.Result.Transports);
var credential = await MakeAttestationResponseAsync();
Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("android-safetynet", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
Assert.Equal([AuthenticatorTransport.Internal], credential.Transports);
}

[Fact]
@@ -187,19 +183,15 @@ public async Task TestAndroidSafetyNetRSA()
{ "response", Encoding.UTF8.GetBytes(securityToken) }
});

var res = await MakeAttestationResponseAsync();
Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("android-safetynet", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
var credential = await MakeAttestationResponseAsync();
Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("android-safetynet", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
}
}

2 changes: 0 additions & 2 deletions Test/Attestation/Apple.cs
Original file line number Diff line number Diff line change
@@ -243,13 +243,11 @@ public async Task TestApplePublicKeyMismatch()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = _challenge,
ErrorMessage = "",
PubKeyCredParams =
[
PubKeyCredParam.ES256
],
Rp = new PublicKeyCredentialRpEntity("https://www.passwordless.dev", "6cc3c9e7967a.ngrok.io", ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
24 changes: 10 additions & 14 deletions Test/Attestation/FidoU2f.cs
Original file line number Diff line number Diff line change
@@ -55,20 +55,16 @@ .. publicKeyU2F
[Fact]
public async Task TestU2f()
{
var res = await MakeAttestationResponseAsync();
Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("fido-u2f", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
Assert.Equal(new[] { AuthenticatorTransport.Internal }, res.Result.Transports);
var credential = await MakeAttestationResponseAsync();
Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("fido-u2f", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
Assert.Equal(new[] { AuthenticatorTransport.Internal }, credential.Transports);
}

[Fact]
28 changes: 12 additions & 16 deletions Test/Attestation/None.cs
Original file line number Diff line number Diff line change
@@ -25,22 +25,18 @@ public async Task TestNone()

_attestationObject.Add("attStmt", new CborMap());
_credentialPublicKey = Fido2Tests.MakeCredentialPublicKey((keyType, alg, crv));
MakeNewCredentialResult res;

res = await MakeAttestationResponseAsync();

Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("none", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);


var credential = await MakeAttestationResponseAsync();

Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("none", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
_attestationObject = new CborMap { { "fmt", "none" } };
}
}
59 changes: 24 additions & 35 deletions Test/Attestation/Packed.cs
Original file line number Diff line number Diff line change
@@ -33,22 +33,18 @@ public async Task TestSelf()
{ "sig", signature }
});

var res = await MakeAttestationResponseAsync();

Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("packed", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
var credential = await MakeAttestationResponseAsync();

Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("packed", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
_attestationObject = new CborMap { { "fmt", "packed" } };
Assert.Equal(new[] { AuthenticatorTransport.Internal }, res.Result.Transports);
Assert.Equal(new[] { AuthenticatorTransport.Internal }, credential.Transports);
}
}

@@ -203,7 +199,7 @@ public async Task TestFull()
DateTimeOffset notAfter = notBefore.AddDays(2);
var attDN = new X500DistinguishedName("CN=Testing, OU=Authenticator Attestation, O=FIDO2-NET-LIB, C=US");

MakeNewCredentialResult res = null;
RegisteredPublicKeyCredential credential = null;

switch (type)
{
@@ -262,7 +258,7 @@ public async Task TestFull()
{ "x5c", x5c }
});

res = await MakeAttestationResponseAsync();
credential = await MakeAttestationResponseAsync();
}
break;
case COSE.KeyType.RSA:
@@ -306,32 +302,26 @@ public async Task TestFull()
{ "x5c", x5c }
});

res = await MakeAttestationResponseAsync();
credential = await MakeAttestationResponseAsync();
}
break;
case COSE.KeyType.OKP:
{
var avr = new VerifyAssertionResult
{
CredentialId = [0xf1, 0xd0],
ErrorMessage = string.Empty,
Status = "ok",
};
}
break;
}
Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("packed", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("packed", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
_attestationObject = new CborMap { { "fmt", "packed" } };
}
}
@@ -879,9 +869,8 @@ public async Task TestAttCertSubjectCommaAsync()
{ "x5c", x5c },
});

var res = await MakeAttestationResponseAsync();
Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
var credential = await MakeAttestationResponseAsync();
Assert.NotEmpty(credential.Id);
}

[Fact]
78 changes: 33 additions & 45 deletions Test/Attestation/Tpm.cs
Original file line number Diff line number Diff line change
@@ -289,22 +289,18 @@ .. y

break;
}
var res = await MakeAttestationResponseAsync();

Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("tpm", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
var credential = await MakeAttestationResponseAsync();

Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("tpm", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
_attestationObject = new CborMap { { "fmt", "tpm" } };
Assert.Equal([AuthenticatorTransport.Internal], res.Result.Transports);
Assert.Equal([AuthenticatorTransport.Internal], credential.Transports);
}
}

@@ -408,21 +404,17 @@ public async Task TestTPMAikCertSANTCGConformant()
{ "pubArea", pubArea }
});

var res = await MakeAttestationResponseAsync();

Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("tpm", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8, res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
Assert.Equal([AuthenticatorTransport.Internal], res.Result.Transports);
var credential = await MakeAttestationResponseAsync();

Assert.Equal(_aaguid, credential.AaGuid);
Assert.Equal(_signCount, credential.SignCount);
Assert.Equal("tpm", credential.AttestationFormat);
Assert.Equal(_credentialID, credential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), credential.PublicKey);
Assert.Equal("Test User", credential.User.DisplayName);
Assert.Equal("testuser"u8, credential.User.Id);
Assert.Equal("testuser", credential.User.Name);
Assert.Equal([AuthenticatorTransport.Internal], credential.Transports);
}

[Fact]
@@ -5054,21 +5046,17 @@ public async Task TestTPMAikCertMisingAAGUID()
{ "pubArea", pubArea }
});

var res = await MakeAttestationResponseAsync();

Assert.Equal(string.Empty, res.ErrorMessage);
Assert.Equal("ok", res.Status);
Assert.Equal(_aaguid, res.Result.AaGuid);
Assert.Equal(_signCount, res.Result.SignCount);
Assert.Equal("tpm", res.Result.AttestationFormat);
Assert.Equal(_credentialID, res.Result.Id);
Assert.Null(res.Result.ErrorMessage);
Assert.Equal(_credentialPublicKey.GetBytes(), res.Result.PublicKey);
Assert.Null(res.Result.Status);
Assert.Equal("Test User", res.Result.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), res.Result.User.Id);
Assert.Equal("testuser", res.Result.User.Name);
Assert.Equal([AuthenticatorTransport.Internal], res.Result.Transports);
var crendential = await MakeAttestationResponseAsync();

Assert.Equal(_aaguid, crendential.AaGuid);
Assert.Equal(_signCount, crendential.SignCount);
Assert.Equal("tpm", crendential.AttestationFormat);
Assert.Equal(_credentialID, crendential.Id);
Assert.Equal(_credentialPublicKey.GetBytes(), crendential.PublicKey);
Assert.Equal("Test User", crendential.User.DisplayName);
Assert.Equal("testuser"u8.ToArray(), crendential.User.Id);
Assert.Equal("testuser", crendential.User.Name);
Assert.Equal([AuthenticatorTransport.Internal], crendential.Transports);
}

[Fact]
26 changes: 0 additions & 26 deletions Test/AuthenticatorResponse.cs
Original file line number Diff line number Diff line change
@@ -97,13 +97,11 @@ public async Task TestAuthenticatorOriginsAsync(string origin, string expectedOr
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
PubKeyCredParam.ES256
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -200,13 +198,11 @@ public async Task TestAuthenticatorOriginsFail(string origin, string expectedOri
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -411,13 +407,11 @@ public async Task TestAuthenticatorAttestationResponseInvalidType()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -483,13 +477,11 @@ public async Task TestAuthenticatorAttestationResponseInvalidRawId(byte[] value)
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -553,13 +545,11 @@ public async Task TestAuthenticatorAttestationResponseInvalidRawType()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -630,13 +620,11 @@ public async Task TestAuthenticatorAttestationResponseRpidMismatch()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -709,13 +697,11 @@ public async Task TestAuthenticatorAttestationResponseNotUserPresentAsync()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -788,13 +774,11 @@ public async Task TestAuthenticatorAttestationResponseBackupEligiblePolicyRequir
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -866,13 +850,11 @@ public async Task TestAuthenticatorAttestationResponseBackupEligiblePolicyDisall
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -944,13 +926,11 @@ public async Task TestAuthenticatorAttestationResponseNoAttestedCredentialData()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -1022,13 +1002,11 @@ public async Task TestAuthenticatorAttestationResponseUnknownAttestationType()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -1100,13 +1078,11 @@ public async Task TestAuthenticatorAttestationResponseNotUniqueCredId()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -1177,13 +1153,11 @@ public async Task TestAuthenticatorAttestationResponseUVRequired()
UserVerification = UserVerificationRequirement.Required,
},
Challenge = challenge,
ErrorMessage = "",
PubKeyCredParams =
[
new PubKeyCredParam(COSE.Algorithm.ES256)
],
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
4 changes: 2 additions & 2 deletions Test/ExistingU2fRegistrationDataTests.cs
Original file line number Diff line number Diff line change
@@ -55,9 +55,9 @@ public async Task TestFido2AssertionWithExistingU2fRegistrationWithAppId()
Origins = new HashSet<string> { "https://localhost:44336" } //data was generated with this origin
});

var res = await fido2.MakeAssertionAsync(authResponse, options, publicKey.Encode(), null, 0, null);
var credential = await fido2.MakeAssertionAsync(authResponse, options, publicKey.Encode(), null, 0, null);

Assert.Equal("ok", res.Status);
Assert.NotEmpty(credential.CredentialId);
}

public static CborMap CreatePublicKeyFromU2fRegistrationData(byte[] keyHandleData, byte[] publicKeyData)
6 changes: 1 addition & 5 deletions Test/Fido2Tests.cs
Original file line number Diff line number Diff line change
@@ -149,7 +149,7 @@ public Attestation()
idFidoGenCeAaGuidExt = new X509Extension(oidIdFidoGenCeAaGuid, _asnEncodedAaguid, false);
}

public async Task<MakeNewCredentialResult> MakeAttestationResponseAsync()
public async Task<RegisteredPublicKeyCredential> MakeAttestationResponseAsync()
{
_attestationObject.Set("authData", new CborByteString(_authData.ToByteArray()));

@@ -189,7 +189,6 @@ public async Task<MakeNewCredentialResult> MakeAttestationResponseAsync()
UserVerification = UserVerificationRequirement.Discouraged,
},
Challenge = _challenge,
ErrorMessage = "",
PubKeyCredParams = new List<PubKeyCredParam>()
{
new(COSE.Algorithm.ES256),
@@ -206,7 +205,6 @@ public async Task<MakeNewCredentialResult> MakeAttestationResponseAsync()
new(COSE.Algorithm.ES256K),
},
Rp = new PublicKeyCredentialRpEntity(rp, rp, ""),
Status = "ok",
User = new Fido2User
{
Name = "testuser",
@@ -814,8 +812,6 @@ public async Task TestAssertionResponse()
avr = await MakeAssertionResponseAsync(type, alg);
}

Assert.Null(avr.ErrorMessage);
Assert.Equal("ok", avr.Status);
Assert.Equal([0xf1, 0xd0], avr.CredentialId);
Assert.Equal("1", avr.SignCount.ToString("X"));
}

0 comments on commit cb71a15

Please sign in to comment.