using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using ProtonVPN.OperatingSystems.WebAuthn.FIDO;
using ProtonVPN.OperatingSystems.WebAuthn.Interop.Marshalers;
using ProtonVPN.OperatingSystems.WebAuthn.Interop.StructVersions;
namespace ProtonVPN.OperatingSystems.WebAuthn.Interop.Structs;
///
/// Information about client data.
///
/// Corresponds to WEBAUTHN_CLIENT_DATA.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class ClientData : IDisposable
{
///
/// Version of this structure, to allow for modifications in the future.
///
private ClientDataVersion _version = ClientDataVersion.Current;
private int _clientDataLength;
private ByteArrayIn _clientData;
///
/// Hash algorithm ID used to hash the ClientDataJSON field.
///
public string HashAlgId { get; set; }
///
/// JSON serialization of the client data.
///
public string ClientDataJson
{
set
{
ClientDataRaw = value != null ? Encoding.UTF8.GetBytes(value) : null;
}
}
///
/// UTF-8 encoded JSON serialization of the client data.
///
public byte[] ClientDataRaw
{
get
{
return _clientData?.Read(_clientDataLength);
}
set
{
// Get rid of any previous data first
_clientData?.Dispose();
// Now replace the previous value with a new one
_clientDataLength = value?.Length ?? 0;
_clientData = new ByteArrayIn(value);
}
}
public ClientData(CollectedClientData clientData)
{
ClientDataJson = JsonSerializer.Serialize(clientData);
// Note that SHA-256 is currently hardcoded in Chromium and Firefox.
HashAlgId = ApiConstants.HashAlgorithmSha256;
}
public ClientData(byte[] clientDataJson)
{
ClientDataRaw = clientDataJson;
// Note that SHA-256 is currently hardcoded in Chromium and Firefox.
HashAlgId = ApiConstants.HashAlgorithmSha256;
}
public ClientData(string clientDataJson)
{
ClientDataJson = clientDataJson;
// Note that SHA-256 is currently hardcoded in Chromium and Firefox.
HashAlgId = ApiConstants.HashAlgorithmSha256;
}
public void Dispose()
{
if (_clientData != null)
{
_clientData.Dispose();
_clientData = null;
}
}
}