Creating one IAuthenticatedEncryptor per IKey
This commit is contained in:
parent
ff3ff939c3
commit
c959795a64
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue