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 ILogger _logger;
|
||||||
|
|
||||||
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum skew that is allowed between servers.
|
/// The maximum skew that is allowed between servers.
|
||||||
/// This is used to allow newly-created keys to be used across servers even though
|
/// 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;
|
_keyPropagationWindow = keyManagementOptions.Value.KeyPropagationWindow;
|
||||||
_maxServerToServerClockSkew = keyManagementOptions.Value.MaxServerClockSkew;
|
_maxServerToServerClockSkew = keyManagementOptions.Value.MaxServerClockSkew;
|
||||||
_encryptorFactories = keyManagementOptions.Value.AuthenticatedEncryptorFactories;
|
|
||||||
_logger = loggerFactory.CreateLogger<DefaultKeyResolver>();
|
_logger = loggerFactory.CreateLogger<DefaultKeyResolver>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,16 +51,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IAuthenticatedEncryptor encryptorInstance = null;
|
var encryptorInstance = key.CreateEncryptor();
|
||||||
foreach (var factory in _encryptorFactories)
|
|
||||||
{
|
|
||||||
encryptorInstance = factory.CreateEncryptorInstance(key);
|
|
||||||
if (encryptorInstance != null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encryptorInstance == null)
|
if (encryptorInstance == null)
|
||||||
{
|
{
|
||||||
CryptoUtil.Fail<IAuthenticatedEncryptor>("CreateEncryptorInstance returned null.");
|
CryptoUtil.Fail<IAuthenticatedEncryptor>("CreateEncryptorInstance returned null.");
|
||||||
|
|
@ -73,7 +61,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.KeyIsIneligibleToBeTheDefaultKeyBecauseItsMethodFailed(key.KeyId, nameof(IAuthenticatedEncryptorFactory.CreateEncryptorInstance), ex);
|
_logger.KeyIsIneligibleToBeTheDefaultKeyBecauseItsMethodFailed(key.KeyId, nameof(IKey.CreateEncryptor), ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
||||||
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
|
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
|
||||||
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
|
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
|
||||||
|
|
@ -21,8 +23,14 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
DateTimeOffset activationDate,
|
DateTimeOffset activationDate,
|
||||||
DateTimeOffset expirationDate,
|
DateTimeOffset expirationDate,
|
||||||
IInternalXmlKeyManager keyManager,
|
IInternalXmlKeyManager keyManager,
|
||||||
XElement keyElement)
|
XElement keyElement,
|
||||||
: base(keyId, creationDate, activationDate, expirationDate, new Lazy<IAuthenticatedEncryptorDescriptor>(GetLazyDescriptorDelegate(keyManager, 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.
|
/// Gets the <see cref="IAuthenticatedEncryptorDescriptor"/> instance associated with this key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IAuthenticatedEncryptorDescriptor Descriptor { get; }
|
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;
|
private readonly CancellationToken _expirationToken;
|
||||||
|
|
||||||
internal CacheableKeyRing(CancellationToken expirationToken, DateTimeOffset expirationTime, IKey defaultKey, IEnumerable<IKey> allKeys, IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
|
internal CacheableKeyRing(CancellationToken expirationToken, DateTimeOffset expirationTime, IKey defaultKey, IEnumerable<IKey> allKeys)
|
||||||
: this(expirationToken, expirationTime, keyRing: new KeyRing(defaultKey, allKeys, encryptorFactories))
|
: 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.
|
/// The default key, may be null if no key is a good default candidate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <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.
|
/// so is appropriate for use with deferred keys.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IKey DefaultKey;
|
public IKey DefaultKey;
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal
|
||||||
/// be null if there is no viable fallback key.
|
/// be null if there is no viable fallback key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <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.
|
/// so is appropriate for use with deferred keys.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IKey FallbackKey;
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
||||||
|
|
||||||
|
|
@ -13,8 +14,19 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed class Key : KeyBase
|
internal sealed class Key : KeyBase
|
||||||
{
|
{
|
||||||
public Key(Guid keyId, DateTimeOffset creationDate, DateTimeOffset activationDate, DateTimeOffset expirationDate, IAuthenticatedEncryptorDescriptor descriptor)
|
public Key(
|
||||||
: base(keyId, creationDate, activationDate, expirationDate, new Lazy<IAuthenticatedEncryptorDescriptor>(() => descriptor))
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
||||||
|
|
||||||
|
|
@ -13,14 +14,24 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
internal abstract class KeyBase : IKey
|
internal abstract class KeyBase : IKey
|
||||||
{
|
{
|
||||||
private readonly Lazy<IAuthenticatedEncryptorDescriptor> _lazyDescriptor;
|
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;
|
KeyId = keyId;
|
||||||
CreationDate = creationDate;
|
CreationDate = creationDate;
|
||||||
ActivationDate = activationDate;
|
ActivationDate = activationDate;
|
||||||
ExpirationDate = expirationDate;
|
ExpirationDate = expirationDate;
|
||||||
_lazyDescriptor = lazyDescriptor;
|
_lazyDescriptor = lazyDescriptor;
|
||||||
|
_encryptorFactories = encryptorFactories;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTimeOffset ActivationDate { get; }
|
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()
|
internal void SetRevoked()
|
||||||
{
|
{
|
||||||
IsRevoked = true;
|
IsRevoked = true;
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
private readonly KeyHolder _defaultKeyHolder;
|
private readonly KeyHolder _defaultKeyHolder;
|
||||||
private readonly Dictionary<Guid, KeyHolder> _keyIdToKeyHolderMap;
|
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>();
|
_keyIdToKeyHolderMap = new Dictionary<Guid, KeyHolder>();
|
||||||
foreach (IKey key in allKeys)
|
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',
|
// 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.
|
// wasn't in the underlying repository. In this case, we just add it now.
|
||||||
if (!_keyIdToKeyHolderMap.ContainsKey(defaultKey.KeyId))
|
if (!_keyIdToKeyHolderMap.ContainsKey(defaultKey.KeyId))
|
||||||
{
|
{
|
||||||
_keyIdToKeyHolderMap.Add(defaultKey.KeyId, new KeyHolder(defaultKey, encryptorFactories));
|
_keyIdToKeyHolderMap.Add(defaultKey.KeyId, new KeyHolder(defaultKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultKeyId = defaultKey.KeyId;
|
DefaultKeyId = defaultKey.KeyId;
|
||||||
|
|
@ -61,12 +61,10 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
private readonly IKey _key;
|
private readonly IKey _key;
|
||||||
private IAuthenticatedEncryptor _encryptor;
|
private IAuthenticatedEncryptor _encryptor;
|
||||||
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
|
|
||||||
|
|
||||||
internal KeyHolder(IKey key, IEnumerable<IAuthenticatedEncryptorFactory> encryptorFactories)
|
internal KeyHolder(IKey key)
|
||||||
{
|
{
|
||||||
_key = key;
|
_key = key;
|
||||||
_encryptorFactories = encryptorFactories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IAuthenticatedEncryptor GetEncryptorInstance(out bool isRevoked)
|
internal IAuthenticatedEncryptor GetEncryptorInstance(out bool isRevoked)
|
||||||
|
|
@ -81,14 +79,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
encryptor = Volatile.Read(ref _encryptor);
|
encryptor = Volatile.Read(ref _encryptor);
|
||||||
if (encryptor == null)
|
if (encryptor == null)
|
||||||
{
|
{
|
||||||
foreach (var factory in _encryptorFactories)
|
encryptor = _key.CreateEncryptor();
|
||||||
{
|
|
||||||
encryptor = factory.CreateEncryptorInstance(_key);
|
|
||||||
if (encryptor != null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Volatile.Write(ref _encryptor, encryptor);
|
Volatile.Write(ref _encryptor, encryptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.AspNetCore.Cryptography;
|
using Microsoft.AspNetCore.Cryptography;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
|
||||||
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
|
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
@ -118,7 +117,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
Debug.Assert(defaultKey != null);
|
Debug.Assert(defaultKey != null);
|
||||||
|
|
||||||
// Invariant: our caller ensures that CreateEncryptorInstance succeeded at least once
|
// Invariant: our caller ensures that CreateEncryptorInstance succeeded at least once
|
||||||
Debug.Assert(CreateEncryptorForKey(defaultKey) != null);
|
Debug.Assert(defaultKey.CreateEncryptor() != null);
|
||||||
|
|
||||||
_logger.UsingKeyAsDefaultKey(defaultKey.KeyId);
|
_logger.UsingKeyAsDefaultKey(defaultKey.KeyId);
|
||||||
|
|
||||||
|
|
@ -135,8 +134,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
expirationToken: cacheExpirationToken,
|
expirationToken: cacheExpirationToken,
|
||||||
expirationTime: (defaultKey.ExpirationDate <= now) ? nextAutoRefreshTime : Min(defaultKey.ExpirationDate, nextAutoRefreshTime),
|
expirationTime: (defaultKey.ExpirationDate <= now) ? nextAutoRefreshTime : Min(defaultKey.ExpirationDate, nextAutoRefreshTime),
|
||||||
defaultKey: defaultKey,
|
defaultKey: defaultKey,
|
||||||
allKeys: allKeys,
|
allKeys: allKeys);
|
||||||
encryptorFactories: _keyManagementOptions.AuthenticatedEncryptorFactories);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IKeyRing GetCurrentKeyRing()
|
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)
|
private static TimeSpan GetRefreshPeriodWithJitter(TimeSpan refreshPeriod)
|
||||||
{
|
{
|
||||||
// We'll fudge the refresh period up to -20% so that multiple applications don't try to
|
// 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 System.Xml.Linq;
|
||||||
using Microsoft.AspNetCore.Cryptography;
|
using Microsoft.AspNetCore.Cryptography;
|
||||||
using Microsoft.AspNetCore.Cryptography.Cng;
|
using Microsoft.AspNetCore.Cryptography.Cng;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
||||||
using Microsoft.AspNetCore.DataProtection.Cng;
|
using Microsoft.AspNetCore.DataProtection.Cng;
|
||||||
using Microsoft.AspNetCore.DataProtection.Internal;
|
using Microsoft.AspNetCore.DataProtection.Internal;
|
||||||
|
|
@ -50,6 +51,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
private readonly IInternalXmlKeyManager _internalKeyManager;
|
private readonly IInternalXmlKeyManager _internalKeyManager;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IEnumerable<IAuthenticatedEncryptorFactory> _encryptorFactories;
|
||||||
|
|
||||||
private CancellationTokenSource _cacheExpirationTokenSource;
|
private CancellationTokenSource _cacheExpirationTokenSource;
|
||||||
|
|
||||||
|
|
@ -88,6 +90,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
_activator = activator;
|
_activator = activator;
|
||||||
TriggerAndResetCacheExpirationToken(suppressLogging: true);
|
TriggerAndResetCacheExpirationToken(suppressLogging: true);
|
||||||
_internalKeyManager = _internalKeyManager ?? this;
|
_internalKeyManager = _internalKeyManager ?? this;
|
||||||
|
_encryptorFactories = keyManagementOptions.Value.AuthenticatedEncryptorFactories;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal for testing.
|
// Internal for testing.
|
||||||
|
|
@ -240,7 +243,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
activationDate: activationDate,
|
activationDate: activationDate,
|
||||||
expirationDate: expirationDate,
|
expirationDate: expirationDate,
|
||||||
keyManager: this,
|
keyManager: this,
|
||||||
keyElement: keyElement);
|
keyElement: keyElement,
|
||||||
|
encryptorFactories: _encryptorFactories);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -400,7 +404,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
creationDate: creationDate,
|
creationDate: creationDate,
|
||||||
activationDate: activationDate,
|
activationDate: activationDate,
|
||||||
expirationDate: expirationDate,
|
expirationDate: expirationDate,
|
||||||
descriptor: newDescriptor);
|
descriptor: newDescriptor,
|
||||||
|
encryptorFactories: _encryptorFactories);
|
||||||
}
|
}
|
||||||
|
|
||||||
IAuthenticatedEncryptorDescriptor IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
|
IAuthenticatedEncryptorDescriptor IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
|
||||||
|
|
|
||||||
|
|
@ -43,16 +43,17 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
|
||||||
|
|
||||||
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(AuthenticatedEncryptorDescriptor descriptor)
|
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(AuthenticatedEncryptorDescriptor descriptor)
|
||||||
{
|
{
|
||||||
|
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
||||||
var key = new Key(
|
var key = new Key(
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
||||||
DateTimeOffset.Now + TimeSpan.FromDays(30),
|
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)
|
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(AuthenticatedEncryptorDescriptor descriptor)
|
||||||
{
|
{
|
||||||
|
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
||||||
|
|
||||||
// Dummy key with the specified descriptor.
|
// Dummy key with the specified descriptor.
|
||||||
var key = new Key(
|
var key = new Key(
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
||||||
DateTimeOffset.Now + TimeSpan.FromDays(30),
|
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)
|
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(CngCbcAuthenticatedEncryptorDescriptor descriptor)
|
||||||
{
|
{
|
||||||
|
var encryptorFactory = new CngCbcAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
||||||
var key = new Key(
|
var key = new Key(
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
||||||
DateTimeOffset.Now + TimeSpan.FromDays(30),
|
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)
|
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(CngGcmAuthenticatedEncryptorDescriptor descriptor)
|
||||||
{
|
{
|
||||||
|
var encryptorFactory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
||||||
var key = new Key(
|
var key = new Key(
|
||||||
keyId: Guid.NewGuid(),
|
keyId: Guid.NewGuid(),
|
||||||
creationDate: DateTimeOffset.Now,
|
creationDate: DateTimeOffset.Now,
|
||||||
activationDate: DateTimeOffset.Now + TimeSpan.FromHours(1),
|
activationDate: DateTimeOffset.Now + TimeSpan.FromHours(1),
|
||||||
expirationDate: DateTimeOffset.Now + TimeSpan.FromDays(30),
|
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)
|
private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(ManagedAuthenticatedEncryptorDescriptor descriptor)
|
||||||
{
|
{
|
||||||
|
var encryptorFactory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
||||||
var key = new Key(
|
var key = new Key(
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
DateTimeOffset.Now + TimeSpan.FromHours(1),
|
||||||
DateTimeOffset.Now + TimeSpan.FromDays(30),
|
DateTimeOffset.Now + TimeSpan.FromDays(30),
|
||||||
descriptor);
|
descriptor,
|
||||||
|
new[] { encryptorFactory });
|
||||||
|
|
||||||
var encryptorFactory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
return key.CreateEncryptor();
|
||||||
|
|
||||||
return encryptorFactory.CreateEncryptorInstance(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
|
using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
|
@ -20,7 +19,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public void ResolveDefaultKeyPolicy_EmptyKeyRing_ReturnsNullDefaultKey()
|
public void ResolveDefaultKeyPolicy_EmptyKeyRing_ReturnsNullDefaultKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
|
var resolver = CreateDefaultKeyResolver();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var resolution = resolver.ResolveDefaultKeyPolicy(DateTimeOffset.Now, new IKey[0]);
|
var resolution = resolver.ResolveDefaultKeyPolicy(DateTimeOffset.Now, new IKey[0]);
|
||||||
|
|
@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public void ResolveDefaultKeyPolicy_ValidExistingKey_ReturnsExistingKey()
|
public void ResolveDefaultKeyPolicy_ValidExistingKey_ReturnsExistingKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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");
|
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()
|
public void ResolveDefaultKeyPolicy_ValidExistingKey_AllowsForClockSkew_KeysStraddleSkewLine_ReturnsExistingKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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");
|
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()
|
public void ResolveDefaultKeyPolicy_ValidExistingKey_AllowsForClockSkew_AllKeysInFuture_ReturnsExistingKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory());
|
var resolver = CreateDefaultKeyResolver();
|
||||||
var key1 = CreateKey("2016-03-01 00:00:00Z", "2017-03-01 00:00:00Z");
|
var key1 = CreateKey("2016-03-01 00:00:00Z", "2017-03-01 00:00:00Z");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -81,7 +80,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public void ResolveDefaultKeyPolicy_ValidExistingKey_NoSuccessor_ReturnsExistingKey_SignalsGenerateNewKey()
|
public void ResolveDefaultKeyPolicy_ValidExistingKey_NoSuccessor_ReturnsExistingKey_SignalsGenerateNewKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -96,7 +95,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public void ResolveDefaultKeyPolicy_ValidExistingKey_NoLegitimateSuccessor_ReturnsExistingKey_SignalsGenerateNewKey()
|
public void ResolveDefaultKeyPolicy_ValidExistingKey_NoLegitimateSuccessor_ReturnsExistingKey_SignalsGenerateNewKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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 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
|
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()
|
public void ResolveDefaultKeyPolicy_MostRecentKeyIsInvalid_BecauseOfRevocation_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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);
|
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
|
// Arrange
|
||||||
var key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
|
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 key2 = CreateKey("2015-03-02 00:00:00Z", "2016-03-01 00:00:00Z", createEncryptorThrows: true);
|
||||||
var resolver = CreateDefaultKeyResolver(new MyEncryptorFactory(throwForKeys: key2));
|
var resolver = CreateDefaultKeyResolver();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var resolution = resolver.ResolveDefaultKeyPolicy("2015-04-01 00:00:00Z", key1, key2);
|
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()
|
public void ResolveDefaultKeyPolicy_FutureKeyIsValidAndWithinClockSkew_ReturnsFutureKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -160,7 +159,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public void ResolveDefaultKeyPolicy_FutureKeyIsValidButNotWithinClockSkew_ReturnsNull()
|
public void ResolveDefaultKeyPolicy_FutureKeyIsValidButNotWithinClockSkew_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 key1 = CreateKey("2015-03-01 00:00:00Z", "2016-03-01 00:00:00Z");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -175,7 +174,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public void ResolveDefaultKeyPolicy_IgnoresExpiredOrRevokedFutureKeys()
|
public void ResolveDefaultKeyPolicy_IgnoresExpiredOrRevokedFutureKeys()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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 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");
|
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()
|
public void ResolveDefaultKeyPolicy_FallbackKey_SelectsLatestBeforePriorPropagationWindow_IgnoresRevokedKeys()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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 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);
|
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
|
// Arrange
|
||||||
var key1 = CreateKey("2010-01-01 00:00:00Z", "2010-01-01 00:00:00Z", creationDate: "2000-01-01 00:00:00Z");
|
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 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 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
|
// Act
|
||||||
var resolution = resolver.ResolveDefaultKeyPolicy("2000-01-05 00:00:00Z", key1, key2, key3, key4);
|
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()
|
public void ResolveDefaultKeyPolicy_FallbackKey_NoNonRevokedKeysBeforePriorPropagationWindow_SelectsEarliestNonRevokedKey()
|
||||||
{
|
{
|
||||||
// Arrange
|
// 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 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 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");
|
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);
|
Assert.True(resolution.ShouldGenerateNewKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IDefaultKeyResolver CreateDefaultKeyResolver(IAuthenticatedEncryptorFactory encryptorFactory)
|
private static IDefaultKeyResolver CreateDefaultKeyResolver()
|
||||||
{
|
{
|
||||||
var options = Options.Create(new KeyManagementOptions());
|
var options = Options.Create(new KeyManagementOptions());
|
||||||
options.Value.AuthenticatedEncryptorFactories.Add(encryptorFactory);
|
|
||||||
return new DefaultKeyResolver(options, NullLoggerFactory.Instance);
|
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>();
|
var mockKey = new Mock<IKey>();
|
||||||
mockKey.Setup(o => o.KeyId).Returns(Guid.NewGuid());
|
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.ActivationDate).Returns(DateTimeOffset.ParseExact(activationDate, "u", CultureInfo.InvariantCulture));
|
||||||
mockKey.Setup(o => o.ExpirationDate).Returns(DateTimeOffset.ParseExact(expirationDate, "u", CultureInfo.InvariantCulture));
|
mockKey.Setup(o => o.ExpirationDate).Returns(DateTimeOffset.ParseExact(expirationDate, "u", CultureInfo.InvariantCulture));
|
||||||
mockKey.Setup(o => o.IsRevoked).Returns(isRevoked);
|
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;
|
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
|
internal static class DefaultKeyResolverExtensions
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
|
|
@ -30,10 +31,10 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
XmlAssert.Equal(@"<node />", element);
|
XmlAssert.Equal(@"<node />", element);
|
||||||
return mockDescriptor;
|
return mockDescriptor;
|
||||||
});
|
});
|
||||||
var options = Options.Create(new KeyManagementOptions());
|
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
|
||||||
|
|
||||||
// Act
|
// 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
|
||||||
Assert.Equal(keyId, key.KeyId);
|
Assert.Equal(keyId, key.KeyId);
|
||||||
|
|
@ -48,8 +49,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var now = DateTimeOffset.UtcNow;
|
var now = DateTimeOffset.UtcNow;
|
||||||
var options = Options.Create(new KeyManagementOptions());
|
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
|
||||||
var key = new DeferredKey(Guid.Empty, now, now, now, new Mock<IInternalXmlKeyManager>().Object, XElement.Parse(@"<node />"));
|
var key = new DeferredKey(Guid.Empty, now, now, now, new Mock<IInternalXmlKeyManager>().Object, XElement.Parse(@"<node />"), new[] { encryptorFactory });
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
Assert.False(key.IsRevoked);
|
Assert.False(key.IsRevoked);
|
||||||
|
|
@ -71,7 +72,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
});
|
});
|
||||||
|
|
||||||
var now = DateTimeOffset.UtcNow;
|
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
|
// Act & assert
|
||||||
ExceptionAssert.Throws<Exception>(() => key.Descriptor, "How exceptional.");
|
ExceptionAssert.Throws<Exception>(() => key.Descriptor, "How exceptional.");
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
var encryptorFactory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
|
||||||
|
|
||||||
// the keyring has only one key
|
// the keyring has only one key
|
||||||
Key key = new Key(Guid.Empty, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.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 }, new[] { mockEncryptorFactory.Object });
|
var keyRing = new KeyRing(key, new[] { key });
|
||||||
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
||||||
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
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);
|
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(new Mock<IAuthenticatedEncryptor>().Object);
|
||||||
|
|
||||||
// the keyring has only one key
|
// 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();
|
key.SetRevoked();
|
||||||
var keyRing = new KeyRing(key, new[] { key }, new[] { mockEncryptorFactory.Object });
|
var keyRing = new KeyRing(key, new[] { key });
|
||||||
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
||||||
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
||||||
|
|
||||||
|
|
@ -278,9 +278,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
|
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
|
||||||
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(mockEncryptor.Object);
|
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();
|
defaultKey.SetRevoked();
|
||||||
var keyRing = new KeyRing(defaultKey, new[] { defaultKey }, new[] { mockEncryptorFactory.Object });
|
var keyRing = new KeyRing(defaultKey, new[] { defaultKey });
|
||||||
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
||||||
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
||||||
|
|
||||||
|
|
@ -326,8 +326,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
|
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
|
||||||
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(mockEncryptor.Object);
|
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 });
|
||||||
var keyRing = new KeyRing(defaultKey, new[] { defaultKey }, new[] { mockEncryptorFactory.Object });
|
var keyRing = new KeyRing(defaultKey, new[] { defaultKey });
|
||||||
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
||||||
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
||||||
|
|
||||||
|
|
@ -376,9 +376,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
|
var mockEncryptorFactory = new Mock<IAuthenticatedEncryptorFactory>();
|
||||||
mockEncryptorFactory.Setup(o => o.CreateEncryptorInstance(It.IsAny<IKey>())).Returns(mockEncryptor.Object);
|
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 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);
|
Key embeddedKey = new Key(embeddedKeyId, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, mockDescriptor.Object, new[] { mockEncryptorFactory.Object });
|
||||||
var keyRing = new KeyRing(defaultKey, new[] { defaultKey, embeddedKey }, new[] { mockEncryptorFactory.Object });
|
var keyRing = new KeyRing(defaultKey, new[] { defaultKey, embeddedKey });
|
||||||
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
||||||
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
||||||
|
|
||||||
|
|
@ -408,9 +408,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
byte[] plaintext = new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50 };
|
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 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>();
|
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
|
||||||
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);
|
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.ExpirationDate).Returns(DateTimeOffset.ParseExact(expirationDate, "u", CultureInfo.InvariantCulture));
|
||||||
mockKey.Setup(o => o.IsRevoked).Returns(isRevoked);
|
mockKey.Setup(o => o.IsRevoked).Returns(isRevoked);
|
||||||
mockKey.Setup(o => o.Descriptor).Returns(new Mock<IAuthenticatedEncryptorDescriptor>().Object);
|
mockKey.Setup(o => o.Descriptor).Returns(new Mock<IAuthenticatedEncryptorDescriptor>().Object);
|
||||||
|
mockKey.Setup(o => o.CreateEncryptor()).Returns(new Mock<IAuthenticatedEncryptor>().Object);
|
||||||
return mockKey.Object;
|
return mockKey.Object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,19 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expectedEncryptorInstance = new Mock<IAuthenticatedEncryptor>().Object;
|
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();
|
var key2 = new MyKey();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var keyRing = new KeyRing(key1, new[] { key1, key2 }, new[] { encryptorFactory });
|
var keyRing = new KeyRing(key1, new[] { key1, key2 });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(0, encryptorFactory.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(0, key1.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
|
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
|
||||||
Assert.Equal(1, encryptorFactory.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
|
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
|
||||||
Assert.Equal(1, encryptorFactory.NumTimesCreateEncryptorInstanceCalled); // should've been cached
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled); // should've been cached
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -38,10 +37,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
// Arrange
|
// Arrange
|
||||||
var key1 = new MyKey();
|
var key1 = new MyKey();
|
||||||
var key2 = new MyKey();
|
var key2 = new MyKey();
|
||||||
var encryptorFactory = new MyEncryptorFactory();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var keyRing = new KeyRing(key2, new[] { key1, key2 }, new[] { encryptorFactory });
|
var keyRing = new KeyRing(key2, new[] { key1, key2 });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(key2.KeyId, keyRing.DefaultKeyId);
|
Assert.Equal(key2.KeyId, keyRing.DefaultKeyId);
|
||||||
|
|
@ -53,16 +51,15 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
// Arrange
|
// Arrange
|
||||||
var key1 = new MyKey();
|
var key1 = new MyKey();
|
||||||
var key2 = new MyKey();
|
var key2 = new MyKey();
|
||||||
var key3 = new MyKey();
|
var key3 = new MyKey(expectedEncryptorInstance: new Mock<IAuthenticatedEncryptor>().Object);
|
||||||
var encryptorFactory = new MyEncryptorFactory(expectedEncryptorInstance: new Mock<IAuthenticatedEncryptor>().Object);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var keyRing = new KeyRing(key3, new[] { key1, key2 }, new[] { encryptorFactory });
|
var keyRing = new KeyRing(key3, new[] { key1, key2 });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
bool unused;
|
bool unused;
|
||||||
Assert.Equal(key3.KeyId, keyRing.DefaultKeyId);
|
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]
|
[Fact]
|
||||||
|
|
@ -72,44 +69,46 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
var expectedEncryptorInstance1 = new Mock<IAuthenticatedEncryptor>().Object;
|
var expectedEncryptorInstance1 = new Mock<IAuthenticatedEncryptor>().Object;
|
||||||
var expectedEncryptorInstance2 = new Mock<IAuthenticatedEncryptor>().Object;
|
var expectedEncryptorInstance2 = new Mock<IAuthenticatedEncryptor>().Object;
|
||||||
|
|
||||||
var key1 = new MyKey(isRevoked: true);
|
var key1 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance1, isRevoked: true);
|
||||||
var key2 = new MyKey();
|
var key2 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance2);
|
||||||
|
|
||||||
var encryptorFactory1 = new MyEncryptorFactory(expectedEncryptorInstance: expectedEncryptorInstance1, associatedKey: key1);
|
|
||||||
var encryptorFactory2 = new MyEncryptorFactory(expectedEncryptorInstance: expectedEncryptorInstance2, associatedKey: key2);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var keyRing = new KeyRing(key2, new[] { key1, key2 }, new[] { encryptorFactory1, encryptorFactory2 });
|
var keyRing = new KeyRing(key2, new[] { key1, key2 });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
bool isRevoked;
|
bool isRevoked;
|
||||||
Assert.Equal(0, encryptorFactory1.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(0, key1.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
|
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
|
||||||
Assert.True(isRevoked);
|
Assert.True(isRevoked);
|
||||||
Assert.Equal(1, encryptorFactory1.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
|
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
|
||||||
Assert.True(isRevoked);
|
Assert.True(isRevoked);
|
||||||
Assert.Equal(1, encryptorFactory1.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Equal(0, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(0, key2.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
|
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
|
||||||
Assert.False(isRevoked);
|
Assert.False(isRevoked);
|
||||||
Assert.Equal(1, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
|
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
|
||||||
Assert.False(isRevoked);
|
Assert.False(isRevoked);
|
||||||
Assert.Equal(1, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
|
||||||
Assert.Same(expectedEncryptorInstance2, keyRing.DefaultAuthenticatedEncryptor);
|
Assert.Same(expectedEncryptorInstance2, keyRing.DefaultAuthenticatedEncryptor);
|
||||||
Assert.Equal(1, encryptorFactory2.NumTimesCreateEncryptorInstanceCalled);
|
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class MyKey : IKey
|
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;
|
CreationDate = DateTimeOffset.Now;
|
||||||
ActivationDate = CreationDate + TimeSpan.FromHours(1);
|
ActivationDate = CreationDate + TimeSpan.FromHours(1);
|
||||||
ExpirationDate = CreationDate + TimeSpan.FromDays(30);
|
ExpirationDate = CreationDate + TimeSpan.FromDays(30);
|
||||||
IsRevoked = isRevoked;
|
IsRevoked = isRevoked;
|
||||||
KeyId = Guid.NewGuid();
|
KeyId = Guid.NewGuid();
|
||||||
|
_encryptorFactory = () => expectedEncryptorInstance ?? new Mock<IAuthenticatedEncryptor>().Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTimeOffset ActivationDate { get; }
|
public DateTimeOffset ActivationDate { get; }
|
||||||
|
|
@ -118,30 +117,11 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
public bool IsRevoked { get; }
|
public bool IsRevoked { get; }
|
||||||
public Guid KeyId { get; }
|
public Guid KeyId { get; }
|
||||||
public IAuthenticatedEncryptorDescriptor Descriptor => throw new NotImplementedException();
|
public IAuthenticatedEncryptorDescriptor Descriptor => throw new NotImplementedException();
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class MyEncryptorFactory : IAuthenticatedEncryptorFactory
|
public IAuthenticatedEncryptor CreateEncryptor()
|
||||||
{
|
|
||||||
public int NumTimesCreateEncryptorInstanceCalled;
|
|
||||||
private IAuthenticatedEncryptor _expectedEncryptorInstance;
|
|
||||||
private IKey _associatedKey;
|
|
||||||
|
|
||||||
public MyEncryptorFactory(IAuthenticatedEncryptor expectedEncryptorInstance = null, IKey associatedKey = null)
|
|
||||||
{
|
{
|
||||||
_expectedEncryptorInstance = expectedEncryptorInstance;
|
|
||||||
_associatedKey = associatedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IAuthenticatedEncryptor CreateEncryptorInstance(IKey key)
|
|
||||||
{
|
|
||||||
if (_associatedKey != null && key != _associatedKey)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
NumTimesCreateEncryptorInstanceCalled++;
|
NumTimesCreateEncryptorInstanceCalled++;
|
||||||
|
return _encryptorFactory();
|
||||||
return _expectedEncryptorInstance ?? new Mock<IAuthenticatedEncryptor>().Object;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
|
|
@ -19,9 +20,10 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
var activationDate = creationDate.AddDays(2);
|
var activationDate = creationDate.AddDays(2);
|
||||||
var expirationDate = creationDate.AddDays(90);
|
var expirationDate = creationDate.AddDays(90);
|
||||||
var descriptor = Mock.Of<IAuthenticatedEncryptorDescriptor>();
|
var descriptor = Mock.Of<IAuthenticatedEncryptorDescriptor>();
|
||||||
|
var encryptorFactory = Mock.Of<IAuthenticatedEncryptorFactory>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var key = new Key(keyId, creationDate, activationDate, expirationDate, descriptor);
|
var key = new Key(keyId, creationDate, activationDate, expirationDate, descriptor, new[] { encryptorFactory });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(keyId, key.KeyId);
|
Assert.Equal(keyId, key.KeyId);
|
||||||
|
|
@ -36,7 +38,8 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var now = DateTimeOffset.UtcNow;
|
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
|
// Act & assert
|
||||||
Assert.False(key.IsRevoked);
|
Assert.False(key.IsRevoked);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue