Make CT required in ISigningKeyStore, flow through implementations and tests

This commit is contained in:
Damian Hickey 2026-02-20 19:55:25 +01:00
parent 20879f18a9
commit 0789fff7ee
6 changed files with 76 additions and 65 deletions

View file

@ -52,14 +52,15 @@ public class SigningKeyStore : ISigningKeyStore
/// <summary>
/// Loads all keys from store.
/// </summary>
/// <param name="ct"></param>
/// <returns></returns>
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync()
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct)
{
using var activity = Tracing.StoreActivitySource.StartActivity("SigningKeyStore.LoadKeys");
var entities = await Context.Keys.Where(x => x.Use == Use)
.AsNoTracking()
.ToArrayAsync(CancellationTokenProvider.CancellationToken);
.ToArrayAsync(ct);
return entities.Select(key => new SerializedKey
{
Id = key.Id,
@ -76,8 +77,9 @@ public class SigningKeyStore : ISigningKeyStore
/// Persists new key in store.
/// </summary>
/// <param name="key"></param>
/// <param name="ct"></param>
/// <returns></returns>
public async Task StoreKeyAsync(SerializedKey key)
public async Task StoreKeyAsync(SerializedKey key, CT ct)
{
using var activity = Tracing.StoreActivitySource.StartActivity("SigningKeyStore.StoreKey");
@ -93,26 +95,27 @@ public class SigningKeyStore : ISigningKeyStore
IsX509Certificate = key.IsX509Certificate
};
Context.Keys.Add(entity);
await Context.SaveChangesAsync(CancellationTokenProvider.CancellationToken);
await Context.SaveChangesAsync(ct);
}
/// <summary>
/// Deletes key from storage.
/// </summary>
/// <param name="id"></param>
/// <param name="ct"></param>
/// <returns></returns>
public async Task DeleteKeyAsync(string id)
public async Task DeleteKeyAsync(string id, CT ct)
{
using var activity = Tracing.StoreActivitySource.StartActivity("SigningKeyStore.DeleteKey");
var item = await Context.Keys.Where(x => x.Use == Use && x.Id == id)
.FirstOrDefaultAsync(CancellationTokenProvider.CancellationToken);
.FirstOrDefaultAsync(ct);
if (item != null)
{
try
{
Context.Keys.Remove(item);
await Context.SaveChangesAsync(CancellationTokenProvider.CancellationToken);
await Context.SaveChangesAsync(ct);
}
catch (DbUpdateConcurrencyException ex)
{

View file

@ -44,8 +44,9 @@ public class FileSystemKeyStore : ISigningKeyStore
/// <summary>
/// Returns all the keys in storage.
/// </summary>
/// <param name="ct"></param>
/// <returns></returns>
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync()
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct)
{
var list = new List<SerializedKey>();
@ -62,7 +63,7 @@ public class FileSystemKeyStore : ISigningKeyStore
{
using (var reader = new StreamReader(file.OpenRead()))
{
var json = await reader.ReadToEndAsync();
var json = await reader.ReadToEndAsync(ct);
var item = KeySerializer.Deserialize<SerializedKey>(json);
list.Add(item);
}
@ -80,8 +81,9 @@ public class FileSystemKeyStore : ISigningKeyStore
/// Persists new key in storage.
/// </summary>
/// <param name="key"></param>
/// <param name="ct"></param>
/// <returns></returns>
public async Task StoreKeyAsync(SerializedKey key)
public async Task StoreKeyAsync(SerializedKey key, CT ct)
{
if (!_directory.Exists)
{
@ -91,15 +93,16 @@ public class FileSystemKeyStore : ISigningKeyStore
var json = KeySerializer.Serialize(key);
var path = Path.Combine(_directory.FullName, KeyFilePrefix + key.Id + KeyFileExtension);
await File.WriteAllTextAsync(path, json, Encoding.UTF8);
await File.WriteAllTextAsync(path, json, Encoding.UTF8, ct);
}
/// <summary>
/// Deletes key from storage.
/// </summary>
/// <param name="id"></param>
/// <param name="ct"></param>
/// <returns></returns>
public Task DeleteKeyAsync(string id)
public Task DeleteKeyAsync(string id, CT ct)
{
var path = Path.Combine(_directory.FullName, KeyFilePrefix + id + KeyFileExtension);
try

View file

@ -66,7 +66,7 @@ public class KeyManager : IKeyManager
_logger.LogTrace("Getting the current key.");
var (_, currentKeys) = await GetAllKeysInternalAsync();
var (_, currentKeys) = await GetAllKeysInternalAsync(default);
if (_logger.IsEnabled(LogLevel.Debug))
{
@ -89,20 +89,20 @@ public class KeyManager : IKeyManager
_logger.LogTrace("Getting all the keys.");
var (keys, _) = await GetAllKeysInternalAsync();
var (keys, _) = await GetAllKeysInternalAsync(default);
return keys;
}
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> signingKeys)> GetAllKeysInternalAsync()
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> signingKeys)> GetAllKeysInternalAsync(CT ct = default)
{
var cached = true;
var keys = await GetAllKeysFromCacheAsync();
if (!keys.Any())
{
cached = false;
keys = await GetAllKeysFromStoreAsync();
keys = await GetAllKeysFromStoreAsync(ct: ct);
}
// ensure we have all of our active signing keys
@ -154,7 +154,7 @@ public class KeyManager : IKeyManager
if (!signingKeysSuccess || rotationRequired)
{
// still need to do the work, but check if another server did the work already
keys = await GetAllKeysFromStoreAsync();
keys = await GetAllKeysFromStoreAsync(ct: ct);
if (!signingKeysSuccess)
{
@ -177,7 +177,7 @@ public class KeyManager : IKeyManager
}
// now we know we need to create new keys
(keys, signingKeys) = await CreateNewKeysAndAddToCacheAsync();
(keys, signingKeys) = await CreateNewKeysAndAddToCacheAsync(ct);
}
else
{
@ -265,7 +265,7 @@ public class KeyManager : IKeyManager
return false;
}
internal async Task<KeyContainer> CreateAndStoreNewKeyAsync(SigningAlgorithmOptions alg)
internal async Task<KeyContainer> CreateAndStoreNewKeyAsync(SigningAlgorithmOptions alg, CT ct = default)
{
_logger.LogTrace("Creating new key.");
@ -300,7 +300,7 @@ public class KeyManager : IKeyManager
}
var key = _protector.Protect(container);
await _store.StoreKeyAsync(key);
await _store.StoreKeyAsync(key, ct);
_logger.LogDebug("Created and stored new key with kid {kid}.", container.Id);
@ -340,7 +340,7 @@ public class KeyManager : IKeyManager
return result;
}
internal async Task<IEnumerable<SerializedKey>> FilterAndDeleteRetiredKeysAsync(IEnumerable<SerializedKey> keys)
internal async Task<IEnumerable<SerializedKey>> FilterAndDeleteRetiredKeysAsync(IEnumerable<SerializedKey> keys, CT ct = default)
{
var retired = keys
.Where(x =>
@ -365,7 +365,7 @@ public class KeyManager : IKeyManager
{
_logger.LogDebug("Deleting retired keys from store: {kids}", ids.Aggregate((x, y) => $"{x},{y}"));
}
await DeleteKeysAsync(ids);
await DeleteKeysAsync(ids, ct);
}
}
@ -373,7 +373,7 @@ public class KeyManager : IKeyManager
return result;
}
internal async Task DeleteKeysAsync(IEnumerable<string> keys)
internal async Task DeleteKeysAsync(IEnumerable<string> keys, CT ct = default)
{
if (keys == null || !keys.Any())
{
@ -382,7 +382,7 @@ public class KeyManager : IKeyManager
foreach (var key in keys)
{
await _store.DeleteKeyAsync(key);
await _store.DeleteKeyAsync(key, ct);
}
}
@ -428,15 +428,15 @@ public class KeyManager : IKeyManager
}
}
internal async Task<IEnumerable<KeyContainer>> GetAllKeysFromStoreAsync(bool cache = true)
internal async Task<IEnumerable<KeyContainer>> GetAllKeysFromStoreAsync(bool cache = true, CT ct = default)
{
_logger.LogTrace("Loading keys from store.");
var protectedKeys = await _store.LoadKeysAsync();
var protectedKeys = await _store.LoadKeysAsync(ct);
if (protectedKeys != null && protectedKeys.Any())
{
// retired keys are those that are beyond inclusion, thus we act as if they don't exist.
protectedKeys = await FilterAndDeleteRetiredKeysAsync(protectedKeys);
protectedKeys = await FilterAndDeleteRetiredKeysAsync(protectedKeys, ct);
var keys = protectedKeys.Select(x =>
{
@ -505,14 +505,14 @@ public class KeyManager : IKeyManager
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> activeKeys)> CreateNewKeysAndAddToCacheAsync()
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> activeKeys)> CreateNewKeysAndAddToCacheAsync(CT ct = default)
{
var keys = new List<KeyContainer>();
keys.AddRange(await _cache.GetKeysAsync() ?? Enumerable.Empty<KeyContainer>());
foreach (var alg in _options.KeyManagement.SigningAlgorithms)
{
var newKey = await CreateAndStoreNewKeyAsync(alg);
var newKey = await CreateAndStoreNewKeyAsync(alg, ct);
keys.Add(newKey);
}
@ -527,7 +527,7 @@ public class KeyManager : IKeyManager
if (_options.KeyManagement.InitializationSynchronizationDelay > TimeSpan.Zero)
{
_logger.LogTrace("All keys are new; delaying before reloading keys from store by InitializationSynchronizationDelay for {InitializationSynchronizationDelay}.", _options.KeyManagement.InitializationSynchronizationDelay);
await Task.Delay(_options.KeyManagement.InitializationSynchronizationDelay);
await Task.Delay(_options.KeyManagement.InitializationSynchronizationDelay, ct);
}
else
{
@ -535,7 +535,7 @@ public class KeyManager : IKeyManager
}
// reload in case other new keys were recently created
keys = new List<KeyContainer>(await GetAllKeysFromStoreAsync(false));
keys = new List<KeyContainer>(await GetAllKeysFromStoreAsync(false, ct));
}
// explicitly cache here since we didn't when we loaded above

View file

@ -16,20 +16,23 @@ public interface ISigningKeyStore
/// <summary>
/// Returns all the keys in storage.
/// </summary>
/// <param name="ct"></param>
/// <returns></returns>
Task<IEnumerable<SerializedKey>> LoadKeysAsync();
Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct);
/// <summary>
/// Persists new key in storage.
/// </summary>
/// <param name="key"></param>
/// <param name="ct"></param>
/// <returns></returns>
Task StoreKeyAsync(SerializedKey key);
Task StoreKeyAsync(SerializedKey key, CT ct);
/// <summary>
/// Deletes key from storage.
/// </summary>
/// <param name="id"></param>
/// <param name="ct"></param>
/// <returns></returns>
Task DeleteKeyAsync(string id);
Task DeleteKeyAsync(string id, CT ct);
}

View file

@ -18,6 +18,8 @@ public class KeyManagerTests
{
private KeyManager _subject;
private readonly CT _ct = TestContext.Current.CancellationToken;
private SigningAlgorithmOptions _rsaOptions = new SigningAlgorithmOptions("RS256");
private IdentityServerOptions _options = new IdentityServerOptions();
@ -131,7 +133,7 @@ public class KeyManagerTests
{
var id = CreateAndStoreKey(_options.KeyManagement.PropagationTime.Add(TimeSpan.FromHours(1)));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
key.Id.ShouldBe(id);
@ -142,7 +144,7 @@ public class KeyManagerTests
{
var id = CreateAndStoreKey(TimeSpan.FromSeconds(5));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -156,7 +158,7 @@ public class KeyManagerTests
{
var id = CreateAndStoreKey(-TimeSpan.FromSeconds(5));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -168,7 +170,7 @@ public class KeyManagerTests
[Fact]
public async Task GetAllKeysInternalAsync_when_no_keys_should_create_key()
{
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -182,7 +184,7 @@ public class KeyManagerTests
{
_mockKeyStore.Keys = null;
var (keys, key) = await _subject.GetAllKeysInternalAsync();
var (keys, key) = await _subject.GetAllKeysInternalAsync(_ct);
keys.ShouldNotBeEmpty();
}
@ -192,7 +194,7 @@ public class KeyManagerTests
{
var id = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -207,7 +209,7 @@ public class KeyManagerTests
var id1 = CreateCacheAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
var id2 = CreateAndStoreKey();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -223,7 +225,7 @@ public class KeyManagerTests
var key3 = CreateAndStoreKey(-TimeSpan.FromSeconds(5));
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -238,7 +240,7 @@ public class KeyManagerTests
var key1 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(TimeSpan.FromSeconds(10)));
var key2 = CreateAndStoreKey(-TimeSpan.FromSeconds(5));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -256,7 +258,7 @@ public class KeyManagerTests
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
var key5 = CreateAndStoreKey(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
allKeys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
}
@ -272,7 +274,7 @@ public class KeyManagerTests
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
var key5 = CreateAndStoreKey(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
allKeys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
}
@ -282,7 +284,7 @@ public class KeyManagerTests
{
var key = CreateAndStoreKey();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
allKeys.Count().ShouldBe(1);
allKeys.Single().Id.ShouldBe(key);
@ -300,7 +302,7 @@ public class KeyManagerTests
key
};
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
allKeys.Count().ShouldBe(1);
allKeys.Single().Id.ShouldBe(key.Id);
@ -312,7 +314,7 @@ public class KeyManagerTests
{
var key1 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(TimeSpan.FromSeconds(1)));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -327,7 +329,7 @@ public class KeyManagerTests
var key1 = CreateCacheAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(TimeSpan.FromSeconds(1)));
var key2 = CreateAndStoreKey();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
_mockKeyStore.Keys.Count.ShouldBe(2);
}
@ -337,7 +339,7 @@ public class KeyManagerTests
{
var key1 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(_options.KeyManagement.PropagationTime.Add(TimeSpan.FromSeconds(1))));
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
var key = signgingKeys.Single();
@ -477,7 +479,7 @@ public class KeyManagerTests
var key5 = CreateSerializedKey(_options.KeyManagement.PropagationTime);
var key6 = CreateSerializedKey(_options.KeyManagement.PropagationTime.Subtract(TimeSpan.FromSeconds(1)));
var result = await _subject.FilterAndDeleteRetiredKeysAsync([key1, key2, key3, key4, key5, key6]);
var result = await _subject.FilterAndDeleteRetiredKeysAsync([key1, key2, key3, key4, key5, key6], _ct);
result.Select(x => x.Id).ShouldBe([key3.Id, key4.Id, key5.Id, key6.Id]);
}
@ -585,7 +587,7 @@ public class KeyManagerTests
{
var key = CreateAndStoreKey();
var keys = await _subject.GetAllKeysFromStoreAsync();
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
keys.ShouldNotBeNull();
keys.Single().Id.ShouldBe(key);
@ -601,7 +603,7 @@ public class KeyManagerTests
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(1)));
var key5 = CreateAndStoreKey(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
var keys = await _subject.GetAllKeysFromStoreAsync();
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
keys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
}
@ -615,12 +617,12 @@ public class KeyManagerTests
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(1)));
var key5 = CreateAndStoreKeyThatCannotBeUnprotected(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
var keys = await _subject.GetAllKeysFromStoreAsync();
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
keys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
_mockKeyStore.DeleteWasCalled.ShouldBeTrue();
var keysInStore = await _mockKeyStore.LoadKeysAsync();
var keysInStore = await _mockKeyStore.LoadKeysAsync(_ct);
keysInStore.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
}
@ -630,7 +632,7 @@ public class KeyManagerTests
var key1 = CreateAndStoreKey(TimeSpan.FromSeconds(10));
_mockKeyStore.Keys.Add(null);
var keys = await _subject.GetAllKeysFromStoreAsync();
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
keys.Select(x => x.Id).ShouldBe([key1]);
}
@ -640,7 +642,7 @@ public class KeyManagerTests
[Fact]
public async Task CreateNewKeyAndAddToCacheAsync_when_no_keys_should_store_and_return_new_key()
{
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
var key = signingKeys.Single();
_mockKeyStore.Keys.Single().Id.ShouldBe(key.Id);
}
@ -650,7 +652,7 @@ public class KeyManagerTests
{
var key1 = CreateCacheAndStoreKey(_options.KeyManagement.PropagationTime.Add(TimeSpan.FromSeconds(1)));
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
var key = signingKeys.Single();
allKeys.Count().ShouldBe(2);
@ -664,7 +666,7 @@ public class KeyManagerTests
{
var key1 = CreateCacheAndStoreKey();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
allKeys.Select(x => x.Id).ShouldBe(_mockKeyStore.Keys.Select(x => x.Id));
}
@ -678,7 +680,7 @@ public class KeyManagerTests
var sw = new Stopwatch();
sw.Start();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
sw.Stop();
sw.Elapsed.ShouldBeGreaterThanOrEqualTo(_options.KeyManagement.InitializationSynchronizationDelay);
@ -695,7 +697,7 @@ public class KeyManagerTests
var sw = new Stopwatch();
sw.Start();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
sw.Stop();
sw.Elapsed.ShouldBeLessThan(_options.KeyManagement.InitializationSynchronizationDelay);
@ -925,7 +927,7 @@ public class KeyManagerTests
[Fact]
public async Task CreateAndStoreNewKeyAsync_should_create_and_store_and_return_key()
{
var result = await _subject.CreateAndStoreNewKeyAsync(_rsaOptions);
var result = await _subject.CreateAndStoreNewKeyAsync(_rsaOptions, _ct);
_mockKeyProtector.ProtectWasCalled.ShouldBeTrue();
_mockKeyStore.Keys.Count.ShouldBe(1);

View file

@ -13,7 +13,7 @@ internal class MockSigningKeyStore : ISigningKeyStore
public bool LoadKeysAsyncWasCalled { get; set; }
public bool DeleteWasCalled { get; set; }
public Task DeleteKeyAsync(string id)
public Task DeleteKeyAsync(string id, CT ct)
{
DeleteWasCalled = true;
if (Keys != null)
@ -23,13 +23,13 @@ internal class MockSigningKeyStore : ISigningKeyStore
return Task.CompletedTask;
}
public Task<IEnumerable<SerializedKey>> LoadKeysAsync()
public Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct)
{
LoadKeysAsyncWasCalled = true;
return Task.FromResult<IEnumerable<SerializedKey>>(Keys);
}
public Task StoreKeyAsync(SerializedKey key)
public Task StoreKeyAsync(SerializedKey key, CT ct)
{
if (Keys == null)
{