Creating one IAuthenticatedEncryptor per IKey

This commit is contained in:
Ajay Bhargav Baaskaran 2017-04-05 21:00:39 -07:00
parent ff3ff939c3
commit c959795a64
21 changed files with 180 additions and 181 deletions

View File

@ -29,8 +29,6 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
private readonly ILogger _logger;
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
/// <summary>
/// The maximum skew that is allowed between servers.
/// This is used to allow newly-created keys to be used across servers even though
@ -46,7 +44,6 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
_keyPropagationWindow = keyManagementOptions.Value.KeyPropagationWindow;
_maxServerToServerClockSkew = keyManagementOptions.Value.MaxServerClockSkew;
_encryptorFactories = keyManagementOptions.Value.AuthenticatedEncryptorFactories;
_logger = loggerFactory.CreateLogger<DefaultKeyResolver>();
}
@ -54,16 +51,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
try
{
IAuthenticatedEncryptor encryptorInstance = null;
foreach (var factory in _encryptorFactories)
{
encryptorInstance = factory.CreateEncryptorInstance(key);
if (encryptorInstance != null)
{
break;
}
}
var encryptorInstance = key.CreateEncryptor();
if (encryptorInstance == null)
{
CryptoUtil.Fail<IAuthenticatedEncryptor>("CreateEncryptorInstance returned null.");
@ -73,7 +61,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
}
catch (Exception ex)
{
_logger.KeyIsIneligibleToBeTheDefaultKeyBecauseItsMethodFailed(key.KeyId, nameof(IAuthenticatedEncryptorFactory.CreateEncryptorInstance), ex);
_logger.KeyIsIneligibleToBeTheDefaultKeyBecauseItsMethodFailed(key.KeyId, nameof(IKey.CreateEncryptor), ex);
return false;
}
}

View File

@ -2,7 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
@ -21,8 +23,14 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
DateTimeOffset activationDate,
DateTimeOffset expirationDate,
IInternalXmlKeyManager keyManager,
XElement keyElement)
: base(keyId, creationDate, activationDate, expirationDate, new Lazy<IAuthenticatedEncryptorDescriptor>(GetLazyDescriptorDelegate(keyManager, keyElement)))
XElement keyElement,
IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
: base(keyId,
creationDate,
activationDate,
expirationDate,
new Lazy<IAuthenticatedEncryptorDescriptor>(GetLazyDescriptorDelegate(keyManager, keyElement)),
encryptorFactories)
{
}

View File

@ -49,5 +49,12 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
/// Gets the <see cref="IAuthenticatedEncryptorDescriptor"/> instance associated with this key.
/// </summary>
IAuthenticatedEncryptorDescriptor Descriptor { get; }
/// <summary>
/// Creates an <see cref="IAuthenticatedEncryptor"/> instance that can be used to encrypt data
/// to and decrypt data from this key.
/// </summary>
/// <returns>An <see cref="IAuthenticatedEncryptor"/>.</returns>
IAuthenticatedEncryptor CreateEncryptor();
}
}

View File

@ -15,8 +15,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal
{
private readonly CancellationToken _expirationToken;
internal CacheableKeyRing(CancellationToken expirationToken, DateTimeOffset expirationTime, IKey defaultKey, IEnumerable<IKey> allKeys, IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
: this(expirationToken, expirationTime, keyRing: new KeyRing(defaultKey, allKeys, encryptorFactories))
internal CacheableKeyRing(CancellationToken expirationToken, DateTimeOffset expirationTime, IKey defaultKey, IEnumerable<IKey> allKeys)
: this(expirationToken, expirationTime, keyRing: new KeyRing(defaultKey, allKeys))
{
}

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal
/// The default key, may be null if no key is a good default candidate.
/// </summary>
/// <remarks>
/// If this property is non-null, its <see cref="IAuthenticatedEncryptorFactory.CreateEncryptorInstance(IKey)"/> method will succeed
/// If this property is non-null, its <see cref="IKey.CreateEncryptor()"/> method will succeed
/// so is appropriate for use with deferred keys.
/// </remarks>
public IKey DefaultKey;
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal
/// be null if there is no viable fallback key.
/// </summary>
/// <remarks>
/// If this property is non-null, its <see cref="IAuthenticatedEncryptorFactory.CreateEncryptorInstance(IKey)"/> method will succeed
/// If this property is non-null, its <see cref="IKey.CreateEncryptor()"/> method will succeed
/// so is appropriate for use with deferred keys.
/// </remarks>
public IKey FallbackKey;

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
@ -13,8 +14,19 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
/// </summary>
internal sealed class Key : KeyBase
{
public Key(Guid keyId, DateTimeOffset creationDate, DateTimeOffset activationDate, DateTimeOffset expirationDate, IAuthenticatedEncryptorDescriptor descriptor)
: base(keyId, creationDate, activationDate, expirationDate, new Lazy<IAuthenticatedEncryptorDescriptor>(() => descriptor))
public Key(
Guid keyId,
DateTimeOffset creationDate,
DateTimeOffset activationDate,
DateTimeOffset expirationDate,
IAuthenticatedEncryptorDescriptor descriptor,
IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
: base(keyId,
creationDate,
activationDate,
expirationDate,
new Lazy<IAuthenticatedEncryptorDescriptor>(() => descriptor),
encryptorFactories)
{
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
@ -13,14 +14,24 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
internal abstract class KeyBase : IKey
{
private readonly Lazy<IAuthenticatedEncryptorDescriptor> _lazyDescriptor;
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
public KeyBase(Guid keyId, DateTimeOffset creationDate, DateTimeOffset activationDate, DateTimeOffset expirationDate, Lazy<IAuthenticatedEncryptorDescriptor> lazyDescriptor)
private IAuthenticatedEncryptor _encryptor;
public KeyBase(
Guid keyId,
DateTimeOffset creationDate,
DateTimeOffset activationDate,
DateTimeOffset expirationDate,
Lazy<IAuthenticatedEncryptorDescriptor> lazyDescriptor,
IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
{
KeyId = keyId;
CreationDate = creationDate;
ActivationDate = activationDate;
ExpirationDate = expirationDate;
_lazyDescriptor = lazyDescriptor;
_encryptorFactories = encryptorFactories;
}
public DateTimeOffset ActivationDate { get; }
@ -41,6 +52,24 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
}
}
public IAuthenticatedEncryptor CreateEncryptor()
{
if (_encryptor == null)
{
foreach (var factory in _encryptorFactories)
{
var encryptor = factory.CreateEncryptorInstance(this);
if (encryptor != null)
{
_encryptor = encryptor;
break;
}
}
}
return _encryptor;
}
internal void SetRevoked()
{
IsRevoked = true;

View File

@ -17,12 +17,12 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
private readonly KeyHolder _defaultKeyHolder;
private readonly Dictionary<Guid, KeyHolder> _keyIdToKeyHolderMap;
public KeyRing(IKey defaultKey, IEnumerable<IKey> allKeys, IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
public KeyRing(IKey defaultKey, IEnumerable<IKey> allKeys)
{
_keyIdToKeyHolderMap = new Dictionary<Guid, KeyHolder>();
foreach (IKey key in allKeys)
{
_keyIdToKeyHolderMap.Add(key.KeyId, new KeyHolder(key, encryptorFactories));
_keyIdToKeyHolderMap.Add(key.KeyId, new KeyHolder(key));
}
// It's possible under some circumstances that the default key won't be part of 'allKeys',
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
// wasn't in the underlying repository. In this case, we just add it now.
if (!_keyIdToKeyHolderMap.ContainsKey(defaultKey.KeyId))
{
_keyIdToKeyHolderMap.Add(defaultKey.KeyId, new KeyHolder(defaultKey, encryptorFactories));
_keyIdToKeyHolderMap.Add(defaultKey.KeyId, new KeyHolder(defaultKey));
}
DefaultKeyId = defaultKey.KeyId;
@ -61,12 +61,10 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
private readonly IKey _key;
private IAuthenticatedEncryptor _encryptor;
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
internal KeyHolder(IKey key, IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
internal KeyHolder(IKey key)
{
_key = key;
_encryptorFactories = encryptorFactories;
}
internal IAuthenticatedEncryptor GetEncryptorInstance(out bool isRevoked)
@ -81,14 +79,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
encryptor = Volatile.Read(ref _encryptor);
if (encryptor == null)
{
foreach (var factory in _encryptorFactories)
{
encryptor = factory.CreateEncryptorInstance(_key);
if (encryptor != null)
{
break;
}
}
encryptor = _key.CreateEncryptor();
Volatile.Write(ref _encryptor, encryptor);
}
}

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Microsoft.AspNetCore.Cryptography;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -118,7 +117,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
Debug.Assert(defaultKey != null);
// Invariant: our caller ensures that CreateEncryptorInstance succeeded at least once
Debug.Assert(CreateEncryptorForKey(defaultKey) != null);
Debug.Assert(defaultKey.CreateEncryptor() != null);
_logger.UsingKeyAsDefaultKey(defaultKey.KeyId);
@ -135,8 +134,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
expirationToken: cacheExpirationToken,
expirationTime: (defaultKey.ExpirationDate <= now) ? nextAutoRefreshTime : Min(defaultKey.ExpirationDate, nextAutoRefreshTime),
defaultKey: defaultKey,
allKeys: allKeys,
encryptorFactories: _keyManagementOptions.AuthenticatedEncryptorFactories);
allKeys: allKeys);
}
public IKeyRing GetCurrentKeyRing()
@ -236,20 +234,6 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
}
}
private IAuthenticatedEncryptor CreateEncryptorForKey(IKey key)
{
foreach (var factory in _keyManagementOptions.AuthenticatedEncryptorFactories)
{
var encryptor = factory.CreateEncryptorInstance(key);
if (encryptor != null)
{
return encryptor;
}
}
return null;
}
private static TimeSpan GetRefreshPeriodWithJitter(TimeSpan refreshPeriod)
{
// We'll fudge the refresh period up to -20% so that multiple applications don't try to

View File

@ -12,6 +12,7 @@ using System.Xml;
using System.Xml.Linq;
using Microsoft.AspNetCore.Cryptography;
using Microsoft.AspNetCore.Cryptography.Cng;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNetCore.DataProtection.Cng;
using Microsoft.AspNetCore.DataProtection.Internal;
@ -50,6 +51,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
private readonly IInternalXmlKeyManager _internalKeyManager;
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger _logger;
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
private CancellationTokenSource _cacheExpirationTokenSource;
@ -88,6 +90,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
_activator = activator;
TriggerAndResetCacheExpirationToken(suppressLogging: true);
_internalKeyManager = _internalKeyManager ?? this;
_encryptorFactories = keyManagementOptions.Value.AuthenticatedEncryptorFactories;
}
// Internal for testing.
@ -240,7 +243,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
activationDate: activationDate,
expirationDate: expirationDate,
keyManager: this,
keyElement: keyElement);
keyElement: keyElement,
encryptorFactories: _encryptorFactories);
}
catch (Exception ex)
{
@ -400,7 +404,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
creationDate: creationDate,
activationDate: activationDate,
expirationDate: expirationDate,
descriptor: newDescriptor);
descriptor: newDescriptor,
encryptorFactories: _encryptorFactories);
}
IAuthenticatedEncryptorDescriptor IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)

View File

@ -43,16 +43,17 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(AuthenticatedEncryptorDescriptor descriptor)
{
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
var key = new Key(
Guid.NewGuid(),
DateTimeOffset.Now,
DateTimeOffset.Now + TimeSpan.FromHours(1),
DateTimeOffset.Now + TimeSpan.FromDays(30),
descriptor);
descriptor,
new[] { encryptorFactory });
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
return encryptorFactory.CreateEncryptorInstance(key);
return key.CreateEncryptor();
}
}
}

View File

@ -171,17 +171,19 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(AuthenticatedEncryptorDescriptor descriptor)
{
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
// Dummy key with the specified descriptor.
var key = new Key(
Guid.NewGuid(),
DateTimeOffset.Now,
DateTimeOffset.Now + TimeSpan.FromHours(1),
DateTimeOffset.Now + TimeSpan.FromDays(30),
descriptor);
descriptor,
new[] { encryptorFactory });
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
return encryptorFactory.CreateEncryptorInstance(key);
return key.CreateEncryptor();
}
}
}

View File

@ -50,16 +50,17 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(CngCbcAuthenticatedEncryptorDescriptor descriptor)
{
var encryptorFactory = new CngCbcAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
var key = new Key(
Guid.NewGuid(),
DateTimeOffset.Now,
DateTimeOffset.Now + TimeSpan.FromHours(1),
DateTimeOffset.Now + TimeSpan.FromDays(30),
descriptor);
descriptor,
new[] { encryptorFactory });
var encryptorFactory = new CngCbcAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
return encryptorFactory.CreateEncryptorInstance(key);
return key.CreateEncryptor();
}
}
}

View File

@ -47,16 +47,17 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(CngGcmAuthenticatedEncryptorDescriptor descriptor)
{
var encryptorFactory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
var key = new Key(
keyId: Guid.NewGuid(),
creationDate: DateTimeOffset.Now,
activationDate: DateTimeOffset.Now + TimeSpan.FromHours(1),
expirationDate: DateTimeOffset.Now + TimeSpan.FromDays(30),
descriptor: descriptor);
descriptor: descriptor,
encryptorFactories: new[] { encryptorFactory });
var encryptorFactory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
return encryptorFactory.CreateEncryptorInstance(key);
return key.CreateEncryptor();
}
}
}

View File

@ -86,16 +86,16 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(ManagedAuthenticatedEncryptorDescriptor descriptor)
{
var encryptorFactory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
var key = new Key(
Guid.NewGuid(),
DateTimeOffset.Now,
DateTimeOffset.Now + TimeSpan.FromHours(1),
DateTimeOffset.Now + TimeSpan.FromDays(30),
descriptor);
descriptor,
new[] { encryptorFactory });
var encryptorFactory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
return encryptorFactory.CreateEncryptorInstance(key);
return key.CreateEncryptor();
}
}
}

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
using Microsoft.Extensions.Logging.Abstractions;
@ -20,7 +19,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_EmptyKeyRing_ReturnsNullDefaultKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
// Act
var resolution = resolver.ResolveDefaultKeyPolicy(DateTimeOffset.Now, new IKey[0]);
@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_ValidExistingKey_ReturnsExistingKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
var key2 = CreateKey("2016-03-01 00:00:00Z", "2017-03-01 00:00:00Z");
@ -50,7 +49,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_ValidExistingKey_AllowsForClockSkew_KeysStraddleSkewLine_ReturnsExistingKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
var key2 = CreateKey("2016-03-01 00:00:00Z", "2017-03-01 00:00:00Z");
@ -66,7 +65,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_ValidExistingKey_AllowsForClockSkew_AllKeysInFuture_ReturnsExistingKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2016-03-01 00:00:00Z", "2017-03-01 00:00:00Z");
// Act
@ -81,7 +80,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_ValidExistingKey_NoSuccessor_ReturnsExistingKey_SignalsGenerateNewKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
// Act
@ -96,7 +95,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_ValidExistingKey_NoLegitimateSuccessor_ReturnsExistingKey_SignalsGenerateNewKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
var key2 = CreateKey("2016-03-01 00:00:00Z", "2017-03-01 00:00:00Z", isRevoked: true);
var key3 = CreateKey("2016-03-01 00:00:00Z", "2016-03-02 00:00:00Z"); // key expires too soon
@ -113,7 +112,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_MostRecentKeyIsInvalid_BecauseOfRevocation_ReturnsNull()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
var key2 = CreateKey("2015-03-02 00:00:00Z", "2016-03-01 00:00:00Z", isRevoked: true);
@ -130,8 +129,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
// Arrange
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
var key2 = CreateKey("2015-03-02 00:00:00Z", "2016-03-01 00:00:00Z");
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory(throwForKeys: key2));
var key2 = CreateKey("2015-03-02 00:00:00Z", "2016-03-01 00:00:00Z", createEncryptorThrows: true);
var resolver = CreateDefaultKeyResolver();
// Act
var resolution = resolver.ResolveDefaultKeyPolicy("2015-04-01 00:00:00Z", key1, key2);
@ -145,7 +144,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_FutureKeyIsValidAndWithinClockSkew_ReturnsFutureKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
// Act
@ -160,7 +159,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_FutureKeyIsValidButNotWithinClockSkew_ReturnsNull()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
// Act
@ -175,7 +174,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_IgnoresExpiredOrRevokedFutureKeys()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2015-03-01 00:00:00Z", "2014-03-01 00:00:00Z"); // expiration before activation should never occur
var key2 = CreateKey("2015-03-01 00:01:00Z", "2015-04-01 00:00:00Z", isRevoked: true);
var key3 = CreateKey("2015-03-01 00:02:00Z", "2015-04-01 00:00:00Z");
@ -192,7 +191,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_FallbackKey_SelectsLatestBeforePriorPropagationWindow_IgnoresRevokedKeys()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-01 00:00:00Z");
var key2 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-02 00:00:00Z");
var key3 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-03 00:00:00Z", isRevoked: true);
@ -212,9 +211,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
// Arrange
var key1 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-01 00:00:00Z");
var key2 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-02 00:00:00Z");
var key3 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-03 00:00:00Z");
var key3 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-03 00:00:00Z", createEncryptorThrows: true);
var key4 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-04 00:00:00Z");
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory(throwForKeys: key3));
var resolver = CreateDefaultKeyResolver();
// Act
var resolution = resolver.ResolveDefaultKeyPolicy("2000-01-05 00:00:00Z", key1, key2, key3, key4);
@ -228,7 +227,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public void ResolveDefaultKeyPolicy_FallbackKey_NoNonRevokedKeysBeforePriorPropagationWindow_SelectsEarliestNonRevokedKey()
{
// Arrange
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
var resolver = CreateDefaultKeyResolver();
var key1 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-03 00:00:00Z", isRevoked: true);
var key2 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-04 00:00:00Z");
var key3 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-05 00:00:00Z");
@ -241,14 +240,13 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
Assert.True(resolution.ShouldGenerateNewKey);
}
private static IDefaultKeyResolver CreateDefaultKeyResolver(IAuthenticatedEncryptorFactory encryptorFactory)
private static IDefaultKeyResolver CreateDefaultKeyResolver()
{
var options = Options.Create(new KeyManagementOptions());
options.Value.AuthenticatedEncryptorFactories.Add(encryptorFactory);
return new DefaultKeyResolver(options, NullLoggerFactory.Instance);
}
private static IKey CreateKey(string activationDate, string expirationDate, string creationDate = null, bool isRevoked = false)
private static IKey CreateKey(string activationDate, string expirationDate, string creationDate = null, bool isRevoked = false, bool createEncryptorThrows = false)
{
var mockKey = new Mock<IKey>();
mockKey.Setup(o => o.KeyId).Returns(Guid.NewGuid());
@ -256,31 +254,17 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
mockKey.Setup(o => o.ActivationDate).Returns(DateTimeOffset.ParseExact(activationDate, "u", CultureInfo.InvariantCulture));
mockKey.Setup(o => o.ExpirationDate).Returns(DateTimeOffset.ParseExact(expirationDate, "u", CultureInfo.InvariantCulture));
mockKey.Setup(o => o.IsRevoked).Returns(isRevoked);
if (createEncryptorThrows)
{
mockKey.Setup(o => o.CreateEncryptor()).Throws(new Exception("This method fails."));
}
else
{
mockKey.Setup(o => o.CreateEncryptor()).Returns(Mock.Of<IAuthenticatedEncryptor>());
}
return mockKey.Object;
}
private class MyEncryptorFactory : IAuthenticatedEncryptorFactory
{
private IReadOnlyList<IKey> _throwForKeys;
public MyEncryptorFactory(params IKey[] throwForKeys)
{
_throwForKeys = throwForKeys;
}
public IAuthenticatedEncryptor CreateEncryptorInstance(IKey key)
{
if (_throwForKeys.Contains(key))
{
throw new Exception("This method fails.");
}
else
{
return new Mock<IAuthenticatedEncryptor>().Object;
}
}
}
}
internal static class DefaultKeyResolverExtensions

View File

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
@ -30,10 +31,10 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
XmlAssert.Equal(@"<node />", element);
return mockDescriptor;
});
var options = Options.Create(new KeyManagementOptions());
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
// Act
var key = new DeferredKey(keyId, creationDate, activationDate, expirationDate, mockInternalKeyManager.Object, XElement.Parse(@"<node />"));
var key = new DeferredKey(keyId, creationDate, activationDate, expirationDate, mockInternalKeyManager.Object, XElement.Parse(@"<node />"), new[] { encryptorFactory });
// Assert
Assert.Equal(keyId, key.KeyId);
@ -48,8 +49,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
// Arrange
var now = DateTimeOffset.UtcNow;
var options = Options.Create(new KeyManagementOptions());
var key = new DeferredKey(Guid.Empty, now, now, now, new Mock<IInternalXmlKeyManager>().Object, XElement.Parse(@"<node />"));
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
var key = new DeferredKey(Guid.Empty, now, now, now, new Mock<IInternalXmlKeyManager>().Object, XElement.Parse(@"<node />"), new[] { encryptorFactory });
// Act & assert
Assert.False(key.IsRevoked);
@ -71,7 +72,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
});
var now = DateTimeOffset.UtcNow;
var key = new DeferredKey(Guid.Empty, now, now, now, mockKeyManager.Object, XElement.Parse(@"<node />"));
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
var key = new DeferredKey(Guid.Empty, now, now, now, mockKeyManager.Object, XElement.Parse(@"<node />"), new[] { encryptorFactory });
// Act & assert
ExceptionAssert.Throws<Exception>(() => key.Descriptor, "How exceptional.");

View File

@ -208,8 +208,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
// the keyring has only one key
Key key = new Key(Guid.Empty, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object);
var keyRing = new KeyRing(key, new[] { key }, new[] { mockEncryptorFactory.Object });
Key key = new Key(Guid.Empty, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object, new[] { mockEncryptorFactory.Object });
var keyRing = new KeyRing(key, new[] { key });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
@ -238,9 +238,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(new Mock<IAuthenticatedEncryptor>().Object);
// the keyring has only one key
Key key = new Key(keyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object);
Key key = new Key(keyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object, new[] { mockEncryptorFactory.Object });
key.SetRevoked();
var keyRing = new KeyRing(key, new[] { key }, new[] { mockEncryptorFactory.Object });
var keyRing = new KeyRing(key, new[] { key });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
@ -278,9 +278,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(mockEncryptor.Object);
Key defaultKey = new Key(defaultKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object);
Key defaultKey = new Key(defaultKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object, new[] { mockEncryptorFactory.Object });
defaultKey.SetRevoked();
var keyRing = new KeyRing(defaultKey, new[] { defaultKey }, new[] { mockEncryptorFactory.Object });
var keyRing = new KeyRing(defaultKey, new[] { defaultKey });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
@ -326,8 +326,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(mockEncryptor.Object);
Key defaultKey = new Key(defaultKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object);
var keyRing = new KeyRing(defaultKey, new[] { defaultKey }, new[] { mockEncryptorFactory.Object });
Key defaultKey = new Key(defaultKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object, new[] { mockEncryptorFactory.Object });
var keyRing = new KeyRing(defaultKey, new[] { defaultKey });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
@ -376,9 +376,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(mockEncryptor.Object);
Key defaultKey = new Key(defaultKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, new Mock<IAuthenticatedEncryptorDescriptor>().Object);
Key embeddedKey = new Key(embeddedKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object);
var keyRing = new KeyRing(defaultKey, new[] { defaultKey, embeddedKey }, new[] { mockEncryptorFactory.Object });
Key defaultKey = new Key(defaultKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, new Mock<IAuthenticatedEncryptorDescriptor>().Object, new[] { mockEncryptorFactory.Object });
Key embeddedKey = new Key(embeddedKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object, new[] { mockEncryptorFactory.Object });
var keyRing = new KeyRing(defaultKey, new[] { defaultKey, embeddedKey });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
@ -408,9 +408,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
// Arrange
byte[] plaintext = new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50 };
Key key = new Key(Guid.NewGuid(), DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, new AuthenticatedEncryptorConfiguration().CreateNewDescriptor());
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
var keyRing = new KeyRing(key, new[] { key }, new[] { encryptorFactory });
Key key = new Key(Guid.NewGuid(), DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, new AuthenticatedEncryptorConfiguration().CreateNewDescriptor(), new[] { encryptorFactory });
var keyRing = new KeyRing(key, new[] { key });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);

View File

@ -644,6 +644,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
mockKey.Setup(o => o.ExpirationDate).Returns(DateTimeOffset.ParseExact(expirationDate, "u", CultureInfo.InvariantCulture));
mockKey.Setup(o => o.IsRevoked).Returns(isRevoked);
mockKey.Setup(o => o.Descriptor).Returns(new Mock<IAuthenticatedEncryptorDescriptor>().Object);
mockKey.Setup(o => o.CreateEncryptor()).Returns(new Mock<IAuthenticatedEncryptor>().Object);
return mockKey.Object;
}
}

View File

@ -16,20 +16,19 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
// Arrange
var expectedEncryptorInstance = new Mock<IAuthenticatedEncryptor>().Object;
var encryptorFactory = new MyEncryptorFactory(expectedEncryptorInstance);
var key1 = new MyKey();
var key1 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance);
var key2 = new MyKey();
// Act
var keyRing = new KeyRing(key1, new[] { key1, key2 }, new[] { encryptorFactory });
var keyRing = new KeyRing(key1, new[] { key1, key2 });
// Assert
Assert.Equal(0, encryptorFactory.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(0, key1.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
Assert.Equal(1, encryptorFactory.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
Assert.Equal(1, encryptorFactory.NumTimesCreateEncryptorInstanceCalled); // should've been cached
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled); // should've been cached
}
[Fact]
@ -38,10 +37,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
// Arrange
var key1 = new MyKey();
var key2 = new MyKey();
var encryptorFactory = new MyEncryptorFactory();
// Act
var keyRing = new KeyRing(key2, new[] { key1, key2 }, new[] { encryptorFactory });
var keyRing = new KeyRing(key2, new[] { key1, key2 });
// Assert
Assert.Equal(key2.KeyId, keyRing.DefaultKeyId);
@ -53,16 +51,15 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
// Arrange
var key1 = new MyKey();
var key2 = new MyKey();
var key3 = new MyKey();
var encryptorFactory = new MyEncryptorFactory(expectedEncryptorInstance: new Mock<IAuthenticatedEncryptor>().Object);
var key3 = new MyKey(expectedEncryptorInstance: new Mock<IAuthenticatedEncryptor>().Object);
// Act
var keyRing = new KeyRing(key3, new[] { key1, key2 }, new[] { encryptorFactory });
var keyRing = new KeyRing(key3, new[] { key1, key2 });
// Assert
bool unused;
Assert.Equal(key3.KeyId, keyRing.DefaultKeyId);
Assert.Equal(encryptorFactory.CreateEncryptorInstance(key3), keyRing.GetAuthenticatedEncryptorByKeyId(key3.KeyId, out unused));
Assert.Equal(key3.CreateEncryptor(), keyRing.GetAuthenticatedEncryptorByKeyId(key3.KeyId, out unused));
}
[Fact]
@ -72,44 +69,46 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
var expectedEncryptorInstance1 = new Mock<IAuthenticatedEncryptor>().Object;
var expectedEncryptorInstance2 = new Mock<IAuthenticatedEncryptor>().Object;
var key1 = new MyKey(isRevoked: true);
var key2 = new MyKey();
var key1 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance1, isRevoked: true);
var key2 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance2);
var encryptorFactory1 = new MyEncryptorFactory(expectedEncryptorInstance: expectedEncryptorInstance1, associatedKey: key1);
var encryptorFactory2 = new MyEncryptorFactory(expectedEncryptorInstance: expectedEncryptorInstance2, associatedKey: key2);
// Act
var keyRing = new KeyRing(key2, new[] { key1, key2 }, new[] { encryptorFactory1, encryptorFactory2 });
var keyRing = new KeyRing(key2, new[] { key1, key2 });
// Assert
bool isRevoked;
Assert.Equal(0, encryptorFactory1.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(0, key1.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
Assert.True(isRevoked);
Assert.Equal(1, encryptorFactory1.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
Assert.True(isRevoked);
Assert.Equal(1, encryptorFactory1.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(0, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(0, key2.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
Assert.False(isRevoked);
Assert.Equal(1, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
Assert.False(isRevoked);
Assert.Equal(1, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
Assert.Same(expectedEncryptorInstance2, keyRing.DefaultAuthenticatedEncryptor);
Assert.Equal(1, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
}
private sealed class MyKey : IKey
{
public MyKey(bool isRevoked = false)
public int NumTimesCreateEncryptorInstanceCalled;
private readonly Func<IAuthenticatedEncryptor> _encryptorFactory;
public MyKey(bool isRevoked = false, IAuthenticatedEncryptor expectedEncryptorInstance = null)
{
CreationDate = DateTimeOffset.Now;
ActivationDate = CreationDate + TimeSpan.FromHours(1);
ExpirationDate = CreationDate + TimeSpan.FromDays(30);
IsRevoked = isRevoked;
KeyId = Guid.NewGuid();
_encryptorFactory = () => expectedEncryptorInstance ?? new Mock<IAuthenticatedEncryptor>().Object;
}
public DateTimeOffset ActivationDate { get; }
@ -118,30 +117,11 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
public bool IsRevoked { get; }
public Guid KeyId { get; }
public IAuthenticatedEncryptorDescriptor Descriptor => throw new NotImplementedException();
}
private sealed class MyEncryptorFactory : IAuthenticatedEncryptorFactory
{
public int NumTimesCreateEncryptorInstanceCalled;
private IAuthenticatedEncryptor _expectedEncryptorInstance;
private IKey _associatedKey;
public MyEncryptorFactory(IAuthenticatedEncryptor expectedEncryptorInstance = null, IKey associatedKey = null)
public IAuthenticatedEncryptor CreateEncryptor()
{
_expectedEncryptorInstance = expectedEncryptorInstance;
_associatedKey = associatedKey;
}
public IAuthenticatedEncryptor CreateEncryptorInstance(IKey key)
{
if (_associatedKey != null && key != _associatedKey)
{
return null;
}
NumTimesCreateEncryptorInstanceCalled++;
return _expectedEncryptorInstance ?? new Mock<IAuthenticatedEncryptor>().Object;
return _encryptorFactory();
}
}
}

View File

@ -5,6 +5,7 @@ using System;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Moq;
using Xunit;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
@ -19,9 +20,10 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
var activationDate = creationDate.AddDays(2);
var expirationDate = creationDate.AddDays(90);
var descriptor = Mock.Of<IAuthenticatedEncryptorDescriptor>();
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
// Act
var key = new Key(keyId, creationDate, activationDate, expirationDate, descriptor);
var key = new Key(keyId, creationDate, activationDate, expirationDate, descriptor, new[] { encryptorFactory });
// Assert
Assert.Equal(keyId, key.KeyId);
@ -36,7 +38,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
{
// Arrange
var now = DateTimeOffset.UtcNow;
var key = new Key(Guid.Empty, now, now, now, new Mock<IAuthenticatedEncryptorDescriptor>().Object);
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
var key = new Key(Guid.Empty, now, now, now, new Mock<IAuthenticatedEncryptorDescriptor>().Object, new[] { encryptorFactory });
// Act & assert
Assert.False(key.IsRevoked);