Skip to content

Remove base-class, Status and ErrorMessage #529

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

Merged
merged 10 commits into from
Jul 16, 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
5 changes: 0 additions & 5 deletions BlazorWasmDemo/Client/Shared/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
54 changes: 22 additions & 32 deletions BlazorWasmDemo/Server/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand All @@ -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
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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(
Expand Down
36 changes: 18 additions & 18 deletions Demo/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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) });
}
}

Expand All @@ -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) });
}
}

Expand Down Expand Up @@ -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) });
}
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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");
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down
4 changes: 1 addition & 3 deletions Src/Fido2.Models/AssertionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -71,8 +71,6 @@ public static AssertionOptions Create(
{
return new AssertionOptions()
{
Status = "ok",
ErrorMessage = string.Empty,
Challenge = challenge,
Timeout = config.Timeout,
RpId = config.ServerDomain,
Expand Down
4 changes: 1 addition & 3 deletions Src/Fido2.Models/CredentialCreateOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Fido2NetLib;

public sealed class CredentialCreateOptions : Fido2ResponseBase
public sealed class CredentialCreateOptions
{
/// <summary>
///
Expand Down Expand Up @@ -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,
Expand Down
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
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion Src/Fido2.Models/Objects/VerifyAssertionResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Result of the MakeAssertion verification
/// </summary>
public class VerifyAssertionResult : Fido2ResponseBase
public class VerifyAssertionResult
{
public byte[] CredentialId { get; init; }

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

return new VerifyAssertionResult
{
Status = "ok",
CredentialId = Raw.Id,
SignCount = authData.SignCount,
IsBackedUp = authData.IsBackedUp,
Expand Down
13 changes: 4 additions & 9 deletions Src/Fido2/Fido2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion Src/Fido2/IFido2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Task<VerifyAssertionResult> MakeAssertionAsync(
IsUserHandleOwnerOfCredentialIdAsync isUserHandleOwnerOfCredentialIdCallback,
CancellationToken cancellationToken = default);

Task<MakeNewCredentialResult> MakeNewCredentialAsync(
Task<RegisteredPublicKeyCredential> MakeNewCredentialAsync(
AuthenticatorAttestationRawResponse attestationResponse,
CredentialCreateOptions originalOptions,
IsCredentialIdUniqueToUserAsyncDelegate isCredentialIdUniqueToUser,
Expand Down
Loading
Loading