Public Access
59 lines
2.1 KiB
C#
59 lines
2.1 KiB
C#
namespace DodoSSH.Client.Session.Tests;
|
|
|
|
/// A device key store that keeps its key in a field.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Stands in for whatever guards the key on a real machine. The gesture is the entire security value of the
|
|
/// real thing, so what this fake models is the two ways the gesture ends: it hands the key over, or it does
|
|
/// not. <see cref="Decline"/> is a cancelled prompt and an invalidated key at once, which is exactly how much
|
|
/// the caller is allowed to know.
|
|
/// </remarks>
|
|
internal sealed class FakeDeviceKeyStore : IDeviceKeyStore
|
|
{
|
|
private byte[]? key;
|
|
|
|
/// <summary>When set, the next load refuses, as a cancelled gesture does.</summary>
|
|
internal bool Decline { get; set; }
|
|
|
|
/// <summary>Whether this machine can keep a key at all.</summary>
|
|
internal bool IsAvailable { get; set; } = true;
|
|
|
|
/// <summary>Reads the stored key without a gesture, for assertions only.</summary>
|
|
internal byte[]? Peek() => key;
|
|
|
|
/// <summary>Replaces the stored key, standing in for a rotated or corrupted keystore entry.</summary>
|
|
internal void Overwrite(byte[] replacement) => key = replacement;
|
|
|
|
/// <inheritdoc />
|
|
public async ValueTask<bool> IsAvailableAsync(CancellationToken cancellationToken)
|
|
{
|
|
if (HoldAvailability is { } hold)
|
|
{
|
|
await hold.WaitAsync(cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
return IsAvailable;
|
|
}
|
|
|
|
/// <summary>When set, availability is not answered until it completes: an unlock held part-way.</summary>
|
|
internal Task? HoldAvailability { get; set; }
|
|
|
|
/// <inheritdoc />
|
|
public ValueTask SaveAsync(ReadOnlyMemory<byte> devicePrivateKey, CancellationToken cancellationToken)
|
|
{
|
|
key = devicePrivateKey.ToArray();
|
|
return ValueTask.CompletedTask;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public ValueTask<byte[]?> TryLoadAsync(CancellationToken cancellationToken) =>
|
|
ValueTask.FromResult(Decline ? null : key?.ToArray());
|
|
|
|
/// <inheritdoc />
|
|
public ValueTask ForgetAsync(CancellationToken cancellationToken)
|
|
{
|
|
key = null;
|
|
return ValueTask.CompletedTask;
|
|
}
|
|
}
|