[Fixes #120, Fixes #121, Fixes #122] Make data protection follow the options model

* Add an IDataProtectionBuilder interface and move methods on DataProtectionConfiguration
  to extension methods on IDataProtectionBuilder.
* Make AddDataProtection return an IDataProtectionBuilder instance for further configuration.
* Make AddDataProtection take in an action with a GlobalConfigurationOptions parameter instead
  of a DataProtectionConfiguration parameter.
* Make DataProtectionProvider static
* Remove ConfigureGlobalOptions
* Change Option suffix in classes that are not actually options to Settings.
* Add extension method for configuring key management options.
* Cleanups.
This commit is contained in:
jacalvar 2016-02-25 09:09:01 -08:00
parent 64f7eff322
commit aa1495deb0
42 changed files with 911 additions and 724 deletions

View File

@ -8,21 +8,20 @@ using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.DataProtection
{
/// <summary>
/// A simple implementation of an <see cref="IDataProtectionProvider"/> where keys are stored
/// Contains factory methods for creating an <see cref="IDataProtectionProvider"/> where keys are stored
/// at a particular location on the file system.
/// </summary>
public sealed class DataProtectionProvider : IDataProtectionProvider
/// <remarks>Use these methods when not using dependency injection to provide the service to the application.</remarks>
public static class DataProtectionProvider
{
private readonly IDataProtectionProvider _innerProvider;
/// <summary>
/// Creates an <see cref="DataProtectionProvider"/> given a location at which to store keys.
/// </summary>
/// <param name="keyDirectory">The <see cref="DirectoryInfo"/> in which keys should be stored. This may
/// represent a directory on a local disk or a UNC share.</param>
public DataProtectionProvider(DirectoryInfo keyDirectory)
: this(keyDirectory, configure: null)
public static IDataProtectionProvider Create(DirectoryInfo keyDirectory)
{
return Create(keyDirectory, setupAction: builder => { });
}
/// <summary>
@ -31,38 +30,34 @@ namespace Microsoft.AspNetCore.DataProtection
/// </summary>
/// <param name="keyDirectory">The <see cref="DirectoryInfo"/> in which keys should be stored. This may
/// represent a directory on a local disk or a UNC share.</param>
/// <param name="configure">An optional callback which provides further configuration of the data protection
/// system. See <see cref="DataProtectionConfiguration"/> for more information.</param>
public DataProtectionProvider(DirectoryInfo keyDirectory, Action<DataProtectionConfiguration> configure)
/// <param name="setupAction">An optional callback which provides further configuration of the data protection
/// system. See <see cref="IDataProtectionBuilder"/> for more information.</param>
public static IDataProtectionProvider Create(
DirectoryInfo keyDirectory,
Action<IDataProtectionBuilder> setupAction)
{
if (keyDirectory == null)
{
throw new ArgumentNullException(nameof(keyDirectory));
}
// build the service collection
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection(configurationObject =>
if (setupAction == null)
{
configurationObject.PersistKeysToFileSystem(keyDirectory);
configure?.Invoke(configurationObject);
});
// extract the provider instance from the service collection
_innerProvider = serviceCollection.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
}
/// <summary>
/// Implements <see cref="IDataProtectionProvider.CreateProtector(string)"/>.
/// </summary>
public IDataProtector CreateProtector(string purpose)
{
if (purpose == null)
{
throw new ArgumentNullException(nameof(purpose));
throw new ArgumentNullException(nameof(setupAction));
}
return _innerProvider.CreateProtector(purpose);
// build the service collection
var serviceCollection = new ServiceCollection();
var builder = serviceCollection.AddDataProtection();
builder.PersistKeysToFileSystem(keyDirectory);
if (setupAction != null)
{
setupAction(builder);
}
// extract the provider instance from the service collection
return serviceCollection.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
}
}
}
}

View File

@ -11,9 +11,9 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
{
/// <summary>
/// Options for configuring authenticated encryption algorithms.
/// Settings for configuring authenticated encryption algorithms.
/// </summary>
public sealed class AuthenticatedEncryptionOptions : IInternalAuthenticatedEncryptionOptions
public sealed class AuthenticatedEncryptionSettings : IInternalAuthenticatedEncryptionSettings
{
/// <summary>
/// The algorithm to use for symmetric encryption (confidentiality).
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
public ValidationAlgorithm ValidationAlgorithm { get; set; } = ValidationAlgorithm.HMACSHA256;
/// <summary>
/// Validates that this <see cref="AuthenticatedEncryptionOptions"/> is well-formed, i.e.,
/// Validates that this <see cref="AuthenticatedEncryptionSettings"/> is well-formed, i.e.,
/// that the specified algorithms actually exist and that they can be instantiated properly.
/// An exception will be thrown if validation fails.
/// </summary>
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
.CreateEncryptorInstance();
}
private IInternalAuthenticatedEncryptionOptions CreateImplementationOptions()
private IInternalAuthenticatedEncryptionSettings CreateImplementationOptions()
{
if (IsGcmAlgorithm(EncryptionAlgorithm))
{
@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
{
throw new PlatformNotSupportedException(Resources.Platform_WindowsRequiredForGcm);
}
return new CngGcmAuthenticatedEncryptionOptions()
return new CngGcmAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = GetBCryptAlgorithmName(EncryptionAlgorithm),
EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(EncryptionAlgorithm)
@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
if (OSVersionUtil.IsWindows())
{
// CNG preferred over managed implementations if running on Windows
return new CngCbcAuthenticatedEncryptionOptions()
return new CngCbcAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = GetBCryptAlgorithmName(EncryptionAlgorithm),
EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(EncryptionAlgorithm),
@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
else
{
// Use managed implementations as a fallback
return new ManagedAuthenticatedEncryptionOptions()
return new ManagedAuthenticatedEncryptionSettings()
{
EncryptionAlgorithmType = GetManagedTypeForAlgorithm(EncryptionAlgorithm),
EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(EncryptionAlgorithm),
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
return (EncryptionAlgorithm.AES_128_GCM <= algorithm && algorithm <= EncryptionAlgorithm.AES_256_GCM);
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionSettings.ToConfiguration(IServiceProvider services)
{
return new AuthenticatedEncryptorConfiguration(this, services);
}

View File

@ -12,10 +12,10 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
{
/// <summary>
/// Options for configuring an authenticated encryption mechanism which uses
/// Settings for configuring an authenticated encryption mechanism which uses
/// Windows CNG algorithms in CBC encryption + HMAC authentication modes.
/// </summary>
public sealed class CngCbcAuthenticatedEncryptionOptions : IInternalAuthenticatedEncryptionOptions
public sealed class CngCbcAuthenticatedEncryptionSettings : IInternalAuthenticatedEncryptionSettings
{
/// <summary>
/// The name of the algorithm to use for symmetric encryption.
@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
public string HashAlgorithmProvider { get; set; } = null;
/// <summary>
/// Validates that this <see cref="CngCbcAuthenticatedEncryptionOptions"/> is well-formed, i.e.,
/// Validates that this <see cref="CngCbcAuthenticatedEncryptionSettings"/> is well-formed, i.e.,
/// that the specified algorithms actually exist and that they can be instantiated properly.
/// An exception will be thrown if validation fails.
/// </summary>
@ -176,7 +176,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
return algorithmHandle;
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionSettings.ToConfiguration(IServiceProvider services)
{
return new CngCbcAuthenticatedEncryptorConfiguration(this, services);
}

View File

@ -12,10 +12,10 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
{
/// <summary>
/// Options for configuring an authenticated encryption mechanism which uses
/// Settings for configuring an authenticated encryption mechanism which uses
/// Windows CNG algorithms in GCM encryption + authentication modes.
/// </summary>
public sealed class CngGcmAuthenticatedEncryptionOptions : IInternalAuthenticatedEncryptionOptions
public sealed class CngGcmAuthenticatedEncryptionSettings : IInternalAuthenticatedEncryptionSettings
{
/// <summary>
/// The name of the algorithm to use for symmetric encryption.
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
public int EncryptionAlgorithmKeySize { get; set; } = 256;
/// <summary>
/// Validates that this <see cref="CngGcmAuthenticatedEncryptionOptions"/> is well-formed, i.e.,
/// Validates that this <see cref="CngGcmAuthenticatedEncryptionSettings"/> is well-formed, i.e.,
/// that the specified algorithm actually exists and can be instantiated properly.
/// An exception will be thrown if validation fails.
/// </summary>
@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
return algorithmHandle;
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionSettings.ToConfiguration(IServiceProvider services)
{
return new CngGcmAuthenticatedEncryptorConfiguration(this, services);
}

View File

@ -12,23 +12,23 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
private readonly IServiceProvider _services;
public AuthenticatedEncryptorConfiguration(AuthenticatedEncryptionOptions options)
: this(options, services: null)
public AuthenticatedEncryptorConfiguration(AuthenticatedEncryptionSettings settings)
: this(settings, services: null)
{
}
public AuthenticatedEncryptorConfiguration(AuthenticatedEncryptionOptions options, IServiceProvider services)
public AuthenticatedEncryptorConfiguration(AuthenticatedEncryptionSettings settings, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
Options = options;
Settings = settings;
_services = services;
}
public AuthenticatedEncryptionOptions Options { get; }
public AuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new AuthenticatedEncryptorDescriptor(Options, secret, _services);
return new AuthenticatedEncryptorDescriptor(Settings, secret, _services);
}
}
}

View File

@ -8,22 +8,22 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
/// <summary>
/// A descriptor which can create an authenticated encryption system based upon the
/// configuration provided by an <see cref="AuthenticatedEncryptionOptions"/> object.
/// configuration provided by an <see cref="AuthenticatedEncryptionSettings"/> object.
/// </summary>
public sealed class AuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly IServiceProvider _services;
public AuthenticatedEncryptorDescriptor(AuthenticatedEncryptionOptions options, ISecret masterKey)
: this(options, masterKey, services: null)
public AuthenticatedEncryptorDescriptor(AuthenticatedEncryptionSettings settings, ISecret masterKey)
: this(settings, masterKey, services: null)
{
}
public AuthenticatedEncryptorDescriptor(AuthenticatedEncryptionOptions options, ISecret masterKey, IServiceProvider services)
public AuthenticatedEncryptorDescriptor(AuthenticatedEncryptionSettings settings, ISecret masterKey, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
if (masterKey == null)
@ -31,18 +31,18 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
throw new ArgumentNullException(nameof(masterKey));
}
Options = options;
Settings = settings;
MasterKey = masterKey;
_services = services;
}
internal ISecret MasterKey { get; }
internal AuthenticatedEncryptionOptions Options { get; }
internal AuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _services);
return Settings.CreateAuthenticatedEncryptorInstance(MasterKey, _services);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -54,12 +54,12 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// </descriptor>
var encryptionElement = new XElement("encryption",
new XAttribute("algorithm", Options.EncryptionAlgorithm));
new XAttribute("algorithm", Settings.EncryptionAlgorithm));
var validationElement = (AuthenticatedEncryptionOptions.IsGcmAlgorithm(Options.EncryptionAlgorithm))
var validationElement = (AuthenticatedEncryptionSettings.IsGcmAlgorithm(Settings.EncryptionAlgorithm))
? (object)new XComment(" AES-GCM includes a 128-bit authentication tag, no extra validation algorithm required. ")
: (object)new XElement("validation",
new XAttribute("algorithm", Options.ValidationAlgorithm));
new XAttribute("algorithm", Settings.ValidationAlgorithm));
var outerElement = new XElement("descriptor",
encryptionElement,

View File

@ -41,20 +41,20 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// <masterKey requiresEncryption="true">...</masterKey>
// </descriptor>
var options = new AuthenticatedEncryptionOptions();
var settings = new AuthenticatedEncryptionSettings();
var encryptionElement = element.Element("encryption");
options.EncryptionAlgorithm = (EncryptionAlgorithm)Enum.Parse(typeof(EncryptionAlgorithm), (string)encryptionElement.Attribute("algorithm"));
settings.EncryptionAlgorithm = (EncryptionAlgorithm)Enum.Parse(typeof(EncryptionAlgorithm), (string)encryptionElement.Attribute("algorithm"));
// only read <validation> if not GCM
if (!AuthenticatedEncryptionOptions.IsGcmAlgorithm(options.EncryptionAlgorithm))
if (!AuthenticatedEncryptionSettings.IsGcmAlgorithm(settings.EncryptionAlgorithm))
{
var validationElement = element.Element("validation");
options.ValidationAlgorithm = (ValidationAlgorithm)Enum.Parse(typeof(ValidationAlgorithm), (string)validationElement.Attribute("algorithm"));
settings.ValidationAlgorithm = (ValidationAlgorithm)Enum.Parse(typeof(ValidationAlgorithm), (string)validationElement.Attribute("algorithm"));
}
Secret masterKey = ((string)element.Elements("masterKey").Single()).ToSecret();
return new AuthenticatedEncryptorDescriptor(options, masterKey, _services);
return new AuthenticatedEncryptorDescriptor(settings, masterKey, _services);
}
}
}

View File

@ -13,23 +13,23 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
private readonly IServiceProvider _services;
public CngCbcAuthenticatedEncryptorConfiguration(CngCbcAuthenticatedEncryptionOptions options)
: this(options, services: null)
public CngCbcAuthenticatedEncryptorConfiguration(CngCbcAuthenticatedEncryptionSettings settings)
: this(settings, services: null)
{
}
public CngCbcAuthenticatedEncryptorConfiguration(CngCbcAuthenticatedEncryptionOptions options, IServiceProvider services)
public CngCbcAuthenticatedEncryptorConfiguration(CngCbcAuthenticatedEncryptionSettings settings, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
Options = options;
Settings = settings;
_services = services;
}
public CngCbcAuthenticatedEncryptionOptions Options { get; }
public CngCbcAuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new CngCbcAuthenticatedEncryptorDescriptor(Options, secret, _services);
return new CngCbcAuthenticatedEncryptorDescriptor(Settings, secret, _services);
}
}
}

View File

@ -9,22 +9,22 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
/// <summary>
/// A descriptor which can create an authenticated encryption system based upon the
/// configuration provided by an <see cref="CngCbcAuthenticatedEncryptionOptions"/> object.
/// configuration provided by an <see cref="CngCbcAuthenticatedEncryptionSettings"/> object.
/// </summary>
public sealed class CngCbcAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ILogger _log;
public CngCbcAuthenticatedEncryptorDescriptor(CngCbcAuthenticatedEncryptionOptions options, ISecret masterKey)
: this(options, masterKey, services: null)
public CngCbcAuthenticatedEncryptorDescriptor(CngCbcAuthenticatedEncryptionSettings settings, ISecret masterKey)
: this(settings, masterKey, services: null)
{
}
public CngCbcAuthenticatedEncryptorDescriptor(CngCbcAuthenticatedEncryptionOptions options, ISecret masterKey, IServiceProvider services)
public CngCbcAuthenticatedEncryptorDescriptor(CngCbcAuthenticatedEncryptionSettings settings, ISecret masterKey, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
if (masterKey == null)
@ -32,18 +32,18 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
throw new ArgumentNullException(nameof(masterKey));
}
Options = options;
Settings = settings;
MasterKey = masterKey;
_log = services.GetLogger<CngCbcAuthenticatedEncryptorDescriptor>();
}
internal ISecret MasterKey { get; }
internal CngCbcAuthenticatedEncryptionOptions Options { get; }
internal CngCbcAuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
return Settings.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -56,18 +56,18 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// </descriptor>
var encryptionElement = new XElement("encryption",
new XAttribute("algorithm", Options.EncryptionAlgorithm),
new XAttribute("keyLength", Options.EncryptionAlgorithmKeySize));
if (Options.EncryptionAlgorithmProvider != null)
new XAttribute("algorithm", Settings.EncryptionAlgorithm),
new XAttribute("keyLength", Settings.EncryptionAlgorithmKeySize));
if (Settings.EncryptionAlgorithmProvider != null)
{
encryptionElement.SetAttributeValue("provider", Options.EncryptionAlgorithmProvider);
encryptionElement.SetAttributeValue("provider", Settings.EncryptionAlgorithmProvider);
}
var hashElement = new XElement("hash",
new XAttribute("algorithm", Options.HashAlgorithm));
if (Options.HashAlgorithmProvider != null)
new XAttribute("algorithm", Settings.HashAlgorithm));
if (Settings.HashAlgorithmProvider != null)
{
hashElement.SetAttributeValue("provider", Options.HashAlgorithmProvider);
hashElement.SetAttributeValue("provider", Settings.HashAlgorithmProvider);
}
var rootElement = new XElement("descriptor",

View File

@ -41,20 +41,20 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// <masterKey>...</masterKey>
// </descriptor>
var options = new CngCbcAuthenticatedEncryptionOptions();
var settings = new CngCbcAuthenticatedEncryptionSettings();
var encryptionElement = element.Element("encryption");
options.EncryptionAlgorithm = (string)encryptionElement.Attribute("algorithm");
options.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength");
options.EncryptionAlgorithmProvider = (string)encryptionElement.Attribute("provider"); // could be null
settings.EncryptionAlgorithm = (string)encryptionElement.Attribute("algorithm");
settings.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength");
settings.EncryptionAlgorithmProvider = (string)encryptionElement.Attribute("provider"); // could be null
var hashElement = element.Element("hash");
options.HashAlgorithm = (string)hashElement.Attribute("algorithm");
options.HashAlgorithmProvider = (string)hashElement.Attribute("provider"); // could be null
settings.HashAlgorithm = (string)hashElement.Attribute("algorithm");
settings.HashAlgorithmProvider = (string)hashElement.Attribute("provider"); // could be null
Secret masterKey = ((string)element.Element("masterKey")).ToSecret();
return new CngCbcAuthenticatedEncryptorDescriptor(options, masterKey, _services);
return new CngCbcAuthenticatedEncryptorDescriptor(settings, masterKey, _services);
}
}
}

View File

@ -13,23 +13,23 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
private readonly IServiceProvider _services;
public CngGcmAuthenticatedEncryptorConfiguration(CngGcmAuthenticatedEncryptionOptions options)
: this(options, services: null)
public CngGcmAuthenticatedEncryptorConfiguration(CngGcmAuthenticatedEncryptionSettings settings)
: this(settings, services: null)
{
}
public CngGcmAuthenticatedEncryptorConfiguration(CngGcmAuthenticatedEncryptionOptions options, IServiceProvider services)
public CngGcmAuthenticatedEncryptorConfiguration(CngGcmAuthenticatedEncryptionSettings settings, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
Options = options;
Settings = settings;
_services = services;
}
public CngGcmAuthenticatedEncryptionOptions Options { get; }
public CngGcmAuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new CngGcmAuthenticatedEncryptorDescriptor(Options, secret, _services);
return new CngGcmAuthenticatedEncryptorDescriptor(Settings, secret, _services);
}
}
}

View File

@ -9,22 +9,22 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
/// <summary>
/// A descriptor which can create an authenticated encryption system based upon the
/// configuration provided by an <see cref="CngGcmAuthenticatedEncryptionOptions"/> object.
/// configuration provided by an <see cref="CngGcmAuthenticatedEncryptionSettings"/> object.
/// </summary>
public sealed class CngGcmAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ILogger _log;
public CngGcmAuthenticatedEncryptorDescriptor(CngGcmAuthenticatedEncryptionOptions options, ISecret masterKey)
: this(options, masterKey, services: null)
public CngGcmAuthenticatedEncryptorDescriptor(CngGcmAuthenticatedEncryptionSettings settings, ISecret masterKey)
: this(settings, masterKey, services: null)
{
}
public CngGcmAuthenticatedEncryptorDescriptor(CngGcmAuthenticatedEncryptionOptions options, ISecret masterKey, IServiceProvider services)
public CngGcmAuthenticatedEncryptorDescriptor(CngGcmAuthenticatedEncryptionSettings settings, ISecret masterKey, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
if (masterKey == null)
@ -32,18 +32,18 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
throw new ArgumentNullException(nameof(masterKey));
}
Options = options;
Settings = settings;
MasterKey = masterKey;
_log = services.GetLogger<CngGcmAuthenticatedEncryptorDescriptor>();
}
internal ISecret MasterKey { get; }
internal CngGcmAuthenticatedEncryptionOptions Options { get; }
internal CngGcmAuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
return Settings.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -55,11 +55,11 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// </descriptor>
var encryptionElement = new XElement("encryption",
new XAttribute("algorithm", Options.EncryptionAlgorithm),
new XAttribute("keyLength", Options.EncryptionAlgorithmKeySize));
if (Options.EncryptionAlgorithmProvider != null)
new XAttribute("algorithm", Settings.EncryptionAlgorithm),
new XAttribute("keyLength", Settings.EncryptionAlgorithmKeySize));
if (Settings.EncryptionAlgorithmProvider != null)
{
encryptionElement.SetAttributeValue("provider", Options.EncryptionAlgorithmProvider);
encryptionElement.SetAttributeValue("provider", Settings.EncryptionAlgorithmProvider);
}
var rootElement = new XElement("descriptor",

View File

@ -40,16 +40,16 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// <masterKey>...</masterKey>
// </descriptor>
var options = new CngGcmAuthenticatedEncryptionOptions();
var settings = new CngGcmAuthenticatedEncryptionSettings();
var encryptionElement = element.Element("encryption");
options.EncryptionAlgorithm = (string)encryptionElement.Attribute("algorithm");
options.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength");
options.EncryptionAlgorithmProvider = (string)encryptionElement.Attribute("provider"); // could be null
settings.EncryptionAlgorithm = (string)encryptionElement.Attribute("algorithm");
settings.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength");
settings.EncryptionAlgorithmProvider = (string)encryptionElement.Attribute("provider"); // could be null
Secret masterKey = ((string)element.Element("masterKey")).ToSecret();
return new CngGcmAuthenticatedEncryptorDescriptor(options, masterKey, _services);
return new CngGcmAuthenticatedEncryptorDescriptor(settings, masterKey, _services);
}
}
}

View File

@ -14,23 +14,23 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
private readonly IServiceProvider _services;
public ManagedAuthenticatedEncryptorConfiguration(ManagedAuthenticatedEncryptionOptions options)
: this(options, services: null)
public ManagedAuthenticatedEncryptorConfiguration(ManagedAuthenticatedEncryptionSettings settings)
: this(settings, services: null)
{
}
public ManagedAuthenticatedEncryptorConfiguration(ManagedAuthenticatedEncryptionOptions options, IServiceProvider services)
public ManagedAuthenticatedEncryptorConfiguration(ManagedAuthenticatedEncryptionSettings settings, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
Options = options;
Settings = settings;
_services = services;
}
public ManagedAuthenticatedEncryptionOptions Options { get; }
public ManagedAuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new ManagedAuthenticatedEncryptorDescriptor(Options, secret, _services);
return new ManagedAuthenticatedEncryptorDescriptor(Settings, secret, _services);
}
}
}

View File

@ -10,22 +10,22 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
/// <summary>
/// A descriptor which can create an authenticated encryption system based upon the
/// configuration provided by an <see cref="ManagedAuthenticatedEncryptionOptions"/> object.
/// configuration provided by an <see cref="ManagedAuthenticatedEncryptionSettings"/> object.
/// </summary>
public sealed class ManagedAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ILogger _log;
public ManagedAuthenticatedEncryptorDescriptor(ManagedAuthenticatedEncryptionOptions options, ISecret masterKey)
: this(options, masterKey, services: null)
public ManagedAuthenticatedEncryptorDescriptor(ManagedAuthenticatedEncryptionSettings settings, ISecret masterKey)
: this(settings, masterKey, services: null)
{
}
public ManagedAuthenticatedEncryptorDescriptor(ManagedAuthenticatedEncryptionOptions options, ISecret masterKey, IServiceProvider services)
public ManagedAuthenticatedEncryptorDescriptor(ManagedAuthenticatedEncryptionSettings settings, ISecret masterKey, IServiceProvider services)
{
if (options == null)
if (settings == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(settings));
}
if (masterKey == null)
@ -33,18 +33,18 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
throw new ArgumentNullException(nameof(masterKey));
}
Options = options;
Settings = settings;
MasterKey = masterKey;
_log = services.GetLogger<ManagedAuthenticatedEncryptorDescriptor>();
}
internal ISecret MasterKey { get; }
internal ManagedAuthenticatedEncryptionOptions Options { get; }
internal ManagedAuthenticatedEncryptionSettings Settings { get; }
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
return Settings.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -57,11 +57,11 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// </descriptor>
var encryptionElement = new XElement("encryption",
new XAttribute("algorithm", TypeToFriendlyName(Options.EncryptionAlgorithmType)),
new XAttribute("keyLength", Options.EncryptionAlgorithmKeySize));
new XAttribute("algorithm", TypeToFriendlyName(Settings.EncryptionAlgorithmType)),
new XAttribute("keyLength", Settings.EncryptionAlgorithmKeySize));
var validationElement = new XElement("validation",
new XAttribute("algorithm", TypeToFriendlyName(Options.ValidationAlgorithmType)));
new XAttribute("algorithm", TypeToFriendlyName(Settings.ValidationAlgorithmType)));
var rootElement = new XElement("descriptor",
new XComment(" Algorithms provided by specified SymmetricAlgorithm and KeyedHashAlgorithm "),

View File

@ -42,18 +42,18 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
// <masterKey>...</masterKey>
// </descriptor>
var options = new ManagedAuthenticatedEncryptionOptions();
var settings = new ManagedAuthenticatedEncryptionSettings();
var encryptionElement = element.Element("encryption");
options.EncryptionAlgorithmType = FriendlyNameToType((string)encryptionElement.Attribute("algorithm"));
options.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength");
settings.EncryptionAlgorithmType = FriendlyNameToType((string)encryptionElement.Attribute("algorithm"));
settings.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength");
var validationElement = element.Element("validation");
options.ValidationAlgorithmType = FriendlyNameToType((string)validationElement.Attribute("algorithm"));
settings.ValidationAlgorithmType = FriendlyNameToType((string)validationElement.Attribute("algorithm"));
Secret masterKey = ((string)element.Element("masterKey")).ToSecret();
return new ManagedAuthenticatedEncryptorDescriptor(options, masterKey, _services);
return new ManagedAuthenticatedEncryptorDescriptor(settings, masterKey, _services);
}
// Any changes to this method should also be be reflected

View File

@ -7,18 +7,18 @@ using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationM
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
{
/// <summary>
/// Implemented by our options classes to generalize creating configuration objects.
/// Implemented by our settings classes to generalize creating configuration objects.
/// </summary>
internal interface IInternalAuthenticatedEncryptionOptions
internal interface IInternalAuthenticatedEncryptionSettings
{
/// <summary>
/// Creates a <see cref="IInternalAuthenticatedEncryptorConfiguration"/> object
/// from the given options.
/// from the given settings.
/// </summary>
IInternalAuthenticatedEncryptorConfiguration ToConfiguration(IServiceProvider services);
/// <summary>
/// Performs a self-test of the algorithm specified by the options object.
/// Performs a self-test of the algorithm specified by the settings object.
/// </summary>
void Validate();
}

View File

@ -11,10 +11,10 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
{
/// <summary>
/// Options for configuring an authenticated encryption mechanism which uses
/// Settings for configuring an authenticated encryption mechanism which uses
/// managed SymmetricAlgorithm and KeyedHashAlgorithm implementations.
/// </summary>
public sealed class ManagedAuthenticatedEncryptionOptions : IInternalAuthenticatedEncryptionOptions
public sealed class ManagedAuthenticatedEncryptionSettings : IInternalAuthenticatedEncryptionSettings
{
/// <summary>
/// The type of the algorithm to use for symmetric encryption.
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
public Type ValidationAlgorithmType { get; set; } = typeof(HMACSHA256);
/// <summary>
/// Validates that this <see cref="ManagedAuthenticatedEncryptionOptions"/> is well-formed, i.e.,
/// Validates that this <see cref="ManagedAuthenticatedEncryptionSettings"/> is well-formed, i.e.,
/// that the specified algorithms actually exist and can be instantiated properly.
/// An exception will be thrown if validation fails.
/// </summary>
@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption
}
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionSettings.ToConfiguration(IServiceProvider services)
{
return new ManagedAuthenticatedEncryptorConfiguration(this, services);
}

View File

@ -0,0 +1,546 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel;
using System.IO;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Win32;
#if !NETSTANDARD1_3 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml
using System.Security.Cryptography.X509Certificates;
#endif
namespace Microsoft.AspNetCore.DataProtection
{
/// <summary>
/// Extensions for configuring data protection using an <see cref="IDataProtectionBuilder"/>.
/// </summary>
public static class DataProtectionBuilderExtensions
{
/// <summary>
/// Sets the unique name of this application within the data protection system.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="applicationName">The application name.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// This API corresponds to setting the <see cref="DataProtectionOptions.ApplicationDiscriminator"/> property
/// to the value of <paramref name="applicationName"/>.
/// </remarks>
public static IDataProtectionBuilder SetApplicationName(this IDataProtectionBuilder builder, string applicationName)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.Configure<DataProtectionOptions>(options =>
{
options.ApplicationDiscriminator = applicationName;
});
return builder;
}
/// <summary>
/// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="sink">The instance of the <see cref="IKeyEscrowSink"/> to register.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// Registrations are additive.
/// </remarks>
public static IDataProtectionBuilder AddKeyEscrowSink(this IDataProtectionBuilder builder, IKeyEscrowSink sink)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (sink == null)
{
throw new ArgumentNullException(nameof(sink));
}
builder.Services.AddSingleton<IKeyEscrowSink>(sink);
return builder;
}
/// <summary>
/// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage.
/// </summary>
/// <typeparam name="TImplementation">The concrete type of the <see cref="IKeyEscrowSink"/> to register.</typeparam>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// Registrations are additive. The factory is registered as <see cref="ServiceLifetime.Singleton"/>.
/// </remarks>
public static IDataProtectionBuilder AddKeyEscrowSink<TImplementation>(this IDataProtectionBuilder builder)
where TImplementation : class, IKeyEscrowSink
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.AddSingleton<IKeyEscrowSink, TImplementation>();
return builder;
}
/// <summary>
/// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="factory">A factory that creates the <see cref="IKeyEscrowSink"/> instance.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// Registrations are additive. The factory is registered as <see cref="ServiceLifetime.Singleton"/>.
/// </remarks>
public static IDataProtectionBuilder AddKeyEscrowSink(this IDataProtectionBuilder builder, Func<IServiceProvider, IKeyEscrowSink> factory)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
builder.Services.AddSingleton<IKeyEscrowSink>(factory);
return builder;
}
/// <summary>
/// Configures the key management options for the data protection system.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="setupAction">An <see cref="Action{KeyManagementOptions}"/> to configure the provided<see cref="KeyManagementOptions"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder AddKeyManagementOptions(this IDataProtectionBuilder builder, Action<KeyManagementOptions> setupAction)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (setupAction == null)
{
throw new ArgumentNullException(nameof(setupAction));
}
builder.Services.Configure(setupAction);
return builder;
}
/// <summary>
/// Configures the data protection system not to generate new keys automatically.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// Calling this API corresponds to setting <see cref="KeyManagementOptions.AutoGenerateKeys"/>
/// to 'false'. See that property's documentation for more information.
/// </remarks>
public static IDataProtectionBuilder DisableAutomaticKeyGeneration(this IDataProtectionBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.Configure<KeyManagementOptions>(options =>
{
options.AutoGenerateKeys = false;
});
return builder;
}
/// <summary>
/// Configures the data protection system to persist keys to the specified directory.
/// This path may be on the local machine or may point to a UNC share.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="directory">The directory in which to store keys.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder PersistKeysToFileSystem(this IDataProtectionBuilder builder, DirectoryInfo directory)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (directory == null)
{
throw new ArgumentNullException(nameof(directory));
}
Use(builder.Services, DataProtectionServiceDescriptors.IXmlRepository_FileSystem(directory));
return builder;
}
/// <summary>
/// Configures the data protection system to persist keys to the Windows registry.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="registryKey">The location in the registry where keys should be stored.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder PersistKeysToRegistry(this IDataProtectionBuilder builder, RegistryKey registryKey)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (registryKey == null)
{
throw new ArgumentNullException(nameof(registryKey));
}
Use(builder.Services, DataProtectionServiceDescriptors.IXmlRepository_Registry(registryKey));
return builder;
}
#if !NETSTANDARD1_3 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml
/// <summary>
/// Configures keys to be encrypted to a given certificate before being persisted to storage.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="certificate">The certificate to use when encrypting keys.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder ProtectKeysWithCertificate(this IDataProtectionBuilder builder, X509Certificate2 certificate)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (certificate == null)
{
throw new ArgumentNullException(nameof(certificate));
}
Use(builder.Services, DataProtectionServiceDescriptors.IXmlEncryptor_Certificate(certificate));
return builder;
}
/// <summary>
/// Configures keys to be encrypted to a given certificate before being persisted to storage.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="thumbprint">The thumbprint of the certificate to use when encrypting keys.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder ProtectKeysWithCertificate(this IDataProtectionBuilder builder, string thumbprint)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (thumbprint == null)
{
throw new ArgumentNullException(nameof(thumbprint));
}
// Make sure the thumbprint corresponds to a valid certificate.
if (new CertificateResolver().ResolveCertificate(thumbprint) == null)
{
throw Error.CertificateXmlEncryptor_CertificateNotFound(thumbprint);
}
var services = builder.Services;
// ICertificateResolver is necessary for this type to work correctly, so register it
// if it doesn't already exist.
services.TryAdd(DataProtectionServiceDescriptors.ICertificateResolver_Default());
Use(services, DataProtectionServiceDescriptors.IXmlEncryptor_Certificate(thumbprint));
return builder;
}
#endif
/// <summary>
/// Configures keys to be encrypted with Windows DPAPI before being persisted to
/// storage. The encrypted key will only be decryptable by the current Windows user account.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// This API is only supported on Windows platforms.
/// </remarks>
public static IDataProtectionBuilder ProtectKeysWithDpapi(this IDataProtectionBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
return builder.ProtectKeysWithDpapi(protectToLocalMachine: false);
}
/// <summary>
/// Configures keys to be encrypted with Windows DPAPI before being persisted to
/// storage.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="protectToLocalMachine">'true' if the key should be decryptable by any
/// use on the local machine, 'false' if the key should only be decryptable by the current
/// Windows user account.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// This API is only supported on Windows platforms.
/// </remarks>
public static IDataProtectionBuilder ProtectKeysWithDpapi(this IDataProtectionBuilder builder, bool protectToLocalMachine)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
Use(builder.Services, DataProtectionServiceDescriptors.IXmlEncryptor_Dpapi(protectToLocalMachine));
return builder;
}
/// <summary>
/// Configures keys to be encrypted with Windows CNG DPAPI before being persisted
/// to storage. The keys will be decryptable by the current Windows user account.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/hh706794(v=vs.85).aspx
/// for more information on DPAPI-NG. This API is only supported on Windows 8 / Windows Server 2012 and higher.
/// </remarks>
public static IDataProtectionBuilder ProtectKeysWithDpapiNG(this IDataProtectionBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
return builder.ProtectKeysWithDpapiNG(
protectionDescriptorRule: DpapiNGXmlEncryptor.GetDefaultProtectionDescriptorString(),
flags: DpapiNGProtectionDescriptorFlags.None);
}
/// <summary>
/// Configures keys to be encrypted with Windows CNG DPAPI before being persisted to storage.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="protectionDescriptorRule">The descriptor rule string with which to protect the key material.</param>
/// <param name="flags">Flags that should be passed to the call to 'NCryptCreateProtectionDescriptor'.
/// The default value of this parameter is <see cref="DpapiNGProtectionDescriptorFlags.None"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/hh769091(v=vs.85).aspx
/// and https://msdn.microsoft.com/en-us/library/windows/desktop/hh706800(v=vs.85).aspx
/// for more information on valid values for the the <paramref name="protectionDescriptorRule"/>
/// and <paramref name="flags"/> arguments.
/// This API is only supported on Windows 8 / Windows Server 2012 and higher.
/// </remarks>
public static IDataProtectionBuilder ProtectKeysWithDpapiNG(this IDataProtectionBuilder builder, string protectionDescriptorRule, DpapiNGProtectionDescriptorFlags flags)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (protectionDescriptorRule == null)
{
throw new ArgumentNullException(nameof(protectionDescriptorRule));
}
Use(builder.Services, DataProtectionServiceDescriptors.IXmlEncryptor_DpapiNG(protectionDescriptorRule, flags));
return builder;
}
/// <summary>
/// Sets the default lifetime of keys created by the data protection system.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="lifetime">The lifetime (time before expiration) for newly-created keys.
/// See <see cref="KeyManagementOptions.NewKeyLifetime"/> for more information and
/// usage notes.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder SetDefaultKeyLifetime(this IDataProtectionBuilder builder, TimeSpan lifetime)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (lifetime < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(Resources.FormatLifetimeMustNotBeNegative(nameof(lifetime)));
}
builder.Services.Configure<KeyManagementOptions>(options =>
{
options.NewKeyLifetime = lifetime;
});
return builder;
}
/// <summary>
/// Configures the data protection system to use the specified cryptographic algorithms
/// by default when generating protected payloads.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="settings">Information about what cryptographic algorithms should be used.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
public static IDataProtectionBuilder UseCryptographicAlgorithms(this IDataProtectionBuilder builder, AuthenticatedEncryptionSettings settings)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}
return UseCryptographicAlgorithmsCore(builder, settings);
}
/// <summary>
/// Configures the data protection system to use custom Windows CNG algorithms.
/// This API is intended for advanced scenarios where the developer cannot use the
/// algorithms specified in the <see cref="EncryptionAlgorithm"/> and
/// <see cref="ValidationAlgorithm"/> enumerations.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="settings">Information about what cryptographic algorithms should be used.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// This API is only available on Windows.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static IDataProtectionBuilder UseCustomCryptographicAlgorithms(this IDataProtectionBuilder builder, CngCbcAuthenticatedEncryptionSettings settings)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}
return UseCryptographicAlgorithmsCore(builder, settings);
}
/// <summary>
/// Configures the data protection system to use custom Windows CNG algorithms.
/// This API is intended for advanced scenarios where the developer cannot use the
/// algorithms specified in the <see cref="EncryptionAlgorithm"/> and
/// <see cref="ValidationAlgorithm"/> enumerations.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="settings">Information about what cryptographic algorithms should be used.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// This API is only available on Windows.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static IDataProtectionBuilder UseCustomCryptographicAlgorithms(this IDataProtectionBuilder builder, CngGcmAuthenticatedEncryptionSettings settings)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}
return UseCryptographicAlgorithmsCore(builder, settings);
}
/// <summary>
/// Configures the data protection system to use custom algorithms.
/// This API is intended for advanced scenarios where the developer cannot use the
/// algorithms specified in the <see cref="EncryptionAlgorithm"/> and
/// <see cref="ValidationAlgorithm"/> enumerations.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <param name="settings">Information about what cryptographic algorithms should be used.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static IDataProtectionBuilder UseCustomCryptographicAlgorithms(this IDataProtectionBuilder builder, ManagedAuthenticatedEncryptionSettings settings)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}
return UseCryptographicAlgorithmsCore(builder, settings);
}
private static IDataProtectionBuilder UseCryptographicAlgorithmsCore(IDataProtectionBuilder builder, IInternalAuthenticatedEncryptionSettings settings)
{
settings.Validate(); // perform self-test
Use(builder.Services, DataProtectionServiceDescriptors.IAuthenticatedEncryptorConfiguration_FromSettings(settings));
return builder;
}
/// <summary>
/// Configures the data protection system to use the <see cref="EphemeralDataProtectionProvider"/>
/// for data protection services.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
/// <remarks>
/// If this option is used, payloads protected by the data protection system will
/// be permanently undecipherable after the application exits.
/// </remarks>
public static IDataProtectionBuilder UseEphemeralDataProtectionProvider(this IDataProtectionBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
Use(builder.Services, DataProtectionServiceDescriptors.IDataProtectionProvider_Ephemeral());
return builder;
}
/*
* UTILITY ISERVICECOLLECTION METHODS
*/
private static void RemoveAllServicesOfType(IServiceCollection services, Type serviceType)
{
// We go backward since we're modifying the collection in-place.
for (int i = services.Count - 1; i >= 0; i--)
{
if (services[i]?.ServiceType == serviceType)
{
services.RemoveAt(i);
}
}
}
private static void Use(IServiceCollection services, ServiceDescriptor descriptor)
{
RemoveAllServicesOfType(services, descriptor.ServiceType);
services.Add(descriptor);
}
}
}

View File

@ -1,484 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel;
using System.IO;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Win32;
#if !NETSTANDARD1_3 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml
using System.Security.Cryptography.X509Certificates;
#endif
namespace Microsoft.AspNetCore.DataProtection
{
#if !NETSTANDARD1_3
/// <summary>
/// Provides access to configuration for the data protection system, which allows the
/// developer to configure default cryptographic algorithms, key storage locations,
/// and the mechanism by which keys are protected at rest.
/// </summary>
/// <remarks>
/// <para>
/// If the developer changes the at-rest key protection mechanism, it is intended that
/// he also change the key storage location, and vice versa. For instance, a call to
/// <see cref="ProtectKeysWithCertificate(string)" /> should generally be accompanied by
/// a call to <see cref="PersistKeysToFileSystem(DirectoryInfo)"/>, or exceptions may
/// occur at runtime due to the data protection system not knowing where to persist keys.
/// </para>
/// <para>
/// Similarly, when a developer modifies the default protected payload cryptographic
/// algorithms, it is intended that he also select an explitiy key storage location.
/// A call to <see cref="UseCryptographicAlgorithms(AuthenticatedEncryptionOptions)"/>
/// should therefore generally be paired with a call to <see cref="PersistKeysToFileSystem(DirectoryInfo)"/>,
/// for example.
/// </para>
/// <para>
/// When the default cryptographic algorithms or at-rest key protection mechanisms are
/// changed, they only affect <strong>new</strong> keys in the repository. The repository may
/// contain existing keys that use older algorithms or protection mechanisms.
/// </para>
/// </remarks>
#else
/// <summary>
/// Provides access to configuration for the data protection system, which allows the
/// developer to configure default cryptographic algorithms, key storage locations,
/// and the mechanism by which keys are protected at rest.
/// </summary>
/// <remarks>
/// <para>
/// If the developer changes the at-rest key protection mechanism, it is intended that
/// he also change the key storage location, and vice versa.
/// </para>
/// <para>
/// Similarly, when a developer modifies the default protected payload cryptographic
/// algorithms, it is intended that he also select an explitiy key storage location.
/// A call to <see cref="UseCryptographicAlgorithms(AuthenticatedEncryptionOptions)"/>
/// should therefore generally be paired with a call to <see cref="PersistKeysToFileSystem(DirectoryInfo)"/>,
/// for example.
/// </para>
/// <para>
/// When the default cryptographic algorithms or at-rest key protection mechanisms are
/// changed, they only affect <strong>new</strong> keys in the repository. The repository may
/// contain existing keys that use older algorithms or protection mechanisms.
/// </para>
/// </remarks>
#endif
public class DataProtectionConfiguration
{
/// <summary>
/// Creates a new configuration object linked to a <see cref="IServiceCollection"/>.
/// </summary>
public DataProtectionConfiguration(IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
Services = services;
}
/// <summary>
/// Provides access to the <see cref="IServiceCollection"/> passed to this object's constructor.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public IServiceCollection Services { get; }
/// <summary>
/// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage.
/// </summary>
/// <param name="sink">The instance of the <see cref="IKeyEscrowSink"/> to register.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// Registrations are additive.
/// </remarks>
public DataProtectionConfiguration AddKeyEscrowSink(IKeyEscrowSink sink)
{
if (sink == null)
{
throw new ArgumentNullException(nameof(sink));
}
Services.AddSingleton<IKeyEscrowSink>(sink);
return this;
}
/// <summary>
/// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage.
/// </summary>
/// <typeparam name="TImplementation">The concrete type of the <see cref="IKeyEscrowSink"/> to register.</typeparam>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// Registrations are additive. The factory is registered as <see cref="ServiceLifetime.Singleton"/>.
/// </remarks>
public DataProtectionConfiguration AddKeyEscrowSink<TImplementation>()
where TImplementation : class, IKeyEscrowSink
{
Services.AddSingleton<IKeyEscrowSink, TImplementation>();
return this;
}
/// <summary>
/// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage.
/// </summary>
/// <param name="factory">A factory that creates the <see cref="IKeyEscrowSink"/> instance.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// Registrations are additive. The factory is registered as <see cref="ServiceLifetime.Singleton"/>.
/// </remarks>
public DataProtectionConfiguration AddKeyEscrowSink(Func<IServiceProvider, IKeyEscrowSink> factory)
{
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
Services.AddSingleton<IKeyEscrowSink>(factory);
return this;
}
/// <summary>
/// Configures miscellaneous global options.
/// </summary>
/// <param name="setupAction">A callback that configures the global options.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration ConfigureGlobalOptions(Action<DataProtectionOptions> setupAction)
{
if (setupAction == null)
{
throw new ArgumentNullException(nameof(setupAction));
}
Services.Configure(setupAction);
return this;
}
/// <summary>
/// Configures the data protection system not to generate new keys automatically.
/// </summary>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// Calling this API corresponds to setting <see cref="KeyManagementOptions.AutoGenerateKeys"/>
/// to 'false'. See that property's documentation for more information.
/// </remarks>
public DataProtectionConfiguration DisableAutomaticKeyGeneration()
{
Services.Configure<KeyManagementOptions>(options =>
{
options.AutoGenerateKeys = false;
});
return this;
}
/// <summary>
/// Configures the data protection system to persist keys to the specified directory.
/// This path may be on the local machine or may point to a UNC share.
/// </summary>
/// <param name="directory">The directory in which to store keys.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration PersistKeysToFileSystem(DirectoryInfo directory)
{
if (directory == null)
{
throw new ArgumentNullException(nameof(directory));
}
Use(DataProtectionServiceDescriptors.IXmlRepository_FileSystem(directory));
return this;
}
/// <summary>
/// Configures the data protection system to persist keys to the Windows registry.
/// </summary>
/// <param name="registryKey">The location in the registry where keys should be stored.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration PersistKeysToRegistry(RegistryKey registryKey)
{
if (registryKey == null)
{
throw new ArgumentNullException(nameof(registryKey));
}
Use(DataProtectionServiceDescriptors.IXmlRepository_Registry(registryKey));
return this;
}
#if !NETSTANDARD1_3 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml
/// <summary>
/// Configures keys to be encrypted to a given certificate before being persisted to storage.
/// </summary>
/// <param name="certificate">The certificate to use when encrypting keys.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration ProtectKeysWithCertificate(X509Certificate2 certificate)
{
if (certificate == null)
{
throw new ArgumentNullException(nameof(certificate));
}
Use(DataProtectionServiceDescriptors.IXmlEncryptor_Certificate(certificate));
return this;
}
/// <summary>
/// Configures keys to be encrypted to a given certificate before being persisted to storage.
/// </summary>
/// <param name="thumbprint">The thumbprint of the certificate to use when encrypting keys.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration ProtectKeysWithCertificate(string thumbprint)
{
if (thumbprint == null)
{
throw new ArgumentNullException(nameof(thumbprint));
}
// Make sure the thumbprint corresponds to a valid certificate.
if (new CertificateResolver().ResolveCertificate(thumbprint) == null)
{
throw Error.CertificateXmlEncryptor_CertificateNotFound(thumbprint);
}
// ICertificateResolver is necessary for this type to work correctly, so register it
// if it doesn't already exist.
Services.TryAdd(DataProtectionServiceDescriptors.ICertificateResolver_Default());
Use(DataProtectionServiceDescriptors.IXmlEncryptor_Certificate(thumbprint));
return this;
}
#endif
/// <summary>
/// Configures keys to be encrypted with Windows DPAPI before being persisted to
/// storage. The encrypted key will only be decryptable by the current Windows user account.
/// </summary>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// This API is only supported on Windows platforms.
/// </remarks>
public DataProtectionConfiguration ProtectKeysWithDpapi()
{
return ProtectKeysWithDpapi(protectToLocalMachine: false);
}
/// <summary>
/// Configures keys to be encrypted with Windows DPAPI before being persisted to
/// storage.
/// </summary>
/// <param name="protectToLocalMachine">'true' if the key should be decryptable by any
/// use on the local machine, 'false' if the key should only be decryptable by the current
/// Windows user account.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// This API is only supported on Windows platforms.
/// </remarks>
public DataProtectionConfiguration ProtectKeysWithDpapi(bool protectToLocalMachine)
{
Use(DataProtectionServiceDescriptors.IXmlEncryptor_Dpapi(protectToLocalMachine));
return this;
}
/// <summary>
/// Configures keys to be encrypted with Windows CNG DPAPI before being persisted
/// to storage. The keys will be decryptable by the current Windows user account.
/// </summary>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/hh706794(v=vs.85).aspx
/// for more information on DPAPI-NG. This API is only supported on Windows 8 / Windows Server 2012 and higher.
/// </remarks>
public DataProtectionConfiguration ProtectKeysWithDpapiNG()
{
return ProtectKeysWithDpapiNG(
protectionDescriptorRule: DpapiNGXmlEncryptor.GetDefaultProtectionDescriptorString(),
flags: DpapiNGProtectionDescriptorFlags.None);
}
/// <summary>
/// Configures keys to be encrypted with Windows CNG DPAPI before being persisted to storage.
/// </summary>
/// <param name="protectionDescriptorRule">The descriptor rule string with which to protect the key material.</param>
/// <param name="flags">Flags that should be passed to the call to 'NCryptCreateProtectionDescriptor'.
/// The default value of this parameter is <see cref="DpapiNGProtectionDescriptorFlags.None"/>.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/hh769091(v=vs.85).aspx
/// and https://msdn.microsoft.com/en-us/library/windows/desktop/hh706800(v=vs.85).aspx
/// for more information on valid values for the the <paramref name="protectionDescriptorRule"/>
/// and <paramref name="flags"/> arguments.
/// This API is only supported on Windows 8 / Windows Server 2012 and higher.
/// </remarks>
public DataProtectionConfiguration ProtectKeysWithDpapiNG(string protectionDescriptorRule, DpapiNGProtectionDescriptorFlags flags)
{
if (protectionDescriptorRule == null)
{
throw new ArgumentNullException(nameof(protectionDescriptorRule));
}
Use(DataProtectionServiceDescriptors.IXmlEncryptor_DpapiNG(protectionDescriptorRule, flags));
return this;
}
/// <summary>
/// Sets the unique name of this application within the data protection system.
/// </summary>
/// <param name="applicationName">The application name.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// This API corresponds to setting the <see cref="DataProtectionOptions.ApplicationDiscriminator"/> property
/// to the value of <paramref name="applicationName"/>.
/// </remarks>
public DataProtectionConfiguration SetApplicationName(string applicationName)
{
return ConfigureGlobalOptions(options =>
{
options.ApplicationDiscriminator = applicationName;
});
}
/// <summary>
/// Sets the default lifetime of keys created by the data protection system.
/// </summary>
/// <param name="lifetime">The lifetime (time before expiration) for newly-created keys.
/// See <see cref="KeyManagementOptions.NewKeyLifetime"/> for more information and
/// usage notes.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration SetDefaultKeyLifetime(TimeSpan lifetime)
{
Services.Configure<KeyManagementOptions>(options =>
{
options.NewKeyLifetime = lifetime;
});
return this;
}
/// <summary>
/// Configures the data protection system to use the specified cryptographic algorithms
/// by default when generating protected payloads.
/// </summary>
/// <param name="options">Information about what cryptographic algorithms should be used.</param>
/// <returns>The 'this' instance.</returns>
public DataProtectionConfiguration UseCryptographicAlgorithms(AuthenticatedEncryptionOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return UseCryptographicAlgorithmsCore(options);
}
/// <summary>
/// Configures the data protection system to use custom Windows CNG algorithms.
/// This API is intended for advanced scenarios where the developer cannot use the
/// algorithms specified in the <see cref="EncryptionAlgorithm"/> and
/// <see cref="ValidationAlgorithm"/> enumerations.
/// </summary>
/// <param name="options">Information about what cryptographic algorithms should be used.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// This API is only available on Windows.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public DataProtectionConfiguration UseCustomCryptographicAlgorithms(CngCbcAuthenticatedEncryptionOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return UseCryptographicAlgorithmsCore(options);
}
/// <summary>
/// Configures the data protection system to use custom Windows CNG algorithms.
/// This API is intended for advanced scenarios where the developer cannot use the
/// algorithms specified in the <see cref="EncryptionAlgorithm"/> and
/// <see cref="ValidationAlgorithm"/> enumerations.
/// </summary>
/// <param name="options">Information about what cryptographic algorithms should be used.</param>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// This API is only available on Windows.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public DataProtectionConfiguration UseCustomCryptographicAlgorithms(CngGcmAuthenticatedEncryptionOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return UseCryptographicAlgorithmsCore(options);
}
/// <summary>
/// Configures the data protection system to use custom algorithms.
/// This API is intended for advanced scenarios where the developer cannot use the
/// algorithms specified in the <see cref="EncryptionAlgorithm"/> and
/// <see cref="ValidationAlgorithm"/> enumerations.
/// </summary>
/// <param name="options">Information about what cryptographic algorithms should be used.</param>
/// <returns>The 'this' instance.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public DataProtectionConfiguration UseCustomCryptographicAlgorithms(ManagedAuthenticatedEncryptionOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return UseCryptographicAlgorithmsCore(options);
}
private DataProtectionConfiguration UseCryptographicAlgorithmsCore(IInternalAuthenticatedEncryptionOptions options)
{
options.Validate(); // perform self-test
Use(DataProtectionServiceDescriptors.IAuthenticatedEncryptorConfiguration_FromOptions(options));
return this;
}
/// <summary>
/// Configures the data protection system to use the <see cref="EphemeralDataProtectionProvider"/>
/// for data protection services.
/// </summary>
/// <returns>The 'this' instance.</returns>
/// <remarks>
/// If this option is used, payloads protected by the data protection system will
/// be permanently undecipherable after the application exits.
/// </remarks>
public DataProtectionConfiguration UseEphemeralDataProtectionProvider()
{
Use(DataProtectionServiceDescriptors.IDataProtectionProvider_Ephemeral());
return this;
}
/*
* UTILITY ISERVICECOLLECTION METHODS
*/
private void RemoveAllServicesOfType(Type serviceType)
{
// We go backward since we're modifying the collection in-place.
for (int i = Services.Count - 1; i >= 0; i--)
{
if (Services[i]?.ServiceType == serviceType)
{
Services.RemoveAt(i);
}
}
}
private void Use(ServiceDescriptor descriptor)
{
RemoveAllServicesOfType(descriptor.ServiceType);
Services.Add(descriptor);
}
}
}

View File

@ -3,21 +3,21 @@
using System;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.Internal;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Allows registering and configuring Data Protection in the application.
/// Extension methods for setting up data protection services in an <see cref="IServiceCollection" />.
/// </summary>
public static class DataProtectionServiceCollectionExtensions
{
/// <summary>
/// Adds default Data Protection services to an <see cref="IServiceCollection"/>.
/// Adds data protection services to the specified <see cref="IServiceCollection" />.
/// </summary>
/// <param name="services">The service collection to which to add DataProtection services.</param>
/// <returns>The <paramref name="services"/> instance.</returns>
public static IServiceCollection AddDataProtection(this IServiceCollection services)
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
public static IDataProtectionBuilder AddDataProtection(this IServiceCollection services)
{
if (services == null)
{
@ -26,30 +26,31 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddOptions();
services.TryAdd(DataProtectionServices.GetDefaultServices());
return services;
return new DataProtectionBuilder(services);
}
/// <summary>
/// Adds default Data Protection services to an <see cref="IServiceCollection"/> and configures the behavior of the Data Protection system.
/// Adds data protection services to the specified <see cref="IServiceCollection" />.
/// </summary>
/// <param name="services">A service collection to which Data Protection has already been added.</param>
/// <param name="configure">A callback which takes a <see cref="DataProtectionConfiguration"/> parameter.
/// This callback will be responsible for configuring the system.</param>
/// <returns>The <paramref name="services"/> instance.</returns>
public static IServiceCollection AddDataProtection(this IServiceCollection services, Action<DataProtectionConfiguration> configure)
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
/// <param name="setupAction">An <see cref="Action{DataProtectionOptions}"/> to configure the provided <see cref="DataProtectionOptions"/>.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IDataProtectionBuilder AddDataProtection(this IServiceCollection services, Action<DataProtectionOptions> setupAction)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (configure == null)
if (setupAction == null)
{
throw new ArgumentNullException(nameof(configure));
throw new ArgumentNullException(nameof(setupAction));
}
configure(new DataProtectionConfiguration(services));
return services.AddDataProtection();
var builder = services.AddDataProtection();
services.Configure(setupAction);
return builder;
}
}
}

View File

@ -58,13 +58,13 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
public static ServiceDescriptor IAuthenticatedEncryptorConfiguration_Default()
{
return IAuthenticatedEncryptorConfiguration_FromOptions(new AuthenticatedEncryptionOptions());
return IAuthenticatedEncryptorConfiguration_FromSettings(new AuthenticatedEncryptionSettings());
}
/// <summary>
/// An <see cref="IAuthenticatedEncryptorConfiguration"/> backed by an <see cref="IInternalAuthenticatedEncryptionOptions"/>.
/// An <see cref="IAuthenticatedEncryptorConfiguration"/> backed by an <see cref="IInternalAuthenticatedEncryptionSettings"/>.
/// </summary>
public static ServiceDescriptor IAuthenticatedEncryptorConfiguration_FromOptions(IInternalAuthenticatedEncryptionOptions options)
public static ServiceDescriptor IAuthenticatedEncryptorConfiguration_FromSettings(IInternalAuthenticatedEncryptionSettings options)
{
return ServiceDescriptor.Singleton<IAuthenticatedEncryptorConfiguration>(options.ToConfiguration);
}

View File

@ -40,12 +40,12 @@ namespace Microsoft.AspNetCore.DataProtection
if (OSVersionUtil.IsWindows())
{
// Fastest implementation: AES-256-GCM [CNG]
keyringProvider = new EphemeralKeyRing<CngGcmAuthenticatedEncryptionOptions>();
keyringProvider = new EphemeralKeyRing<CngGcmAuthenticatedEncryptionSettings>();
}
else
{
// Slowest implementation: AES-256-CBC + HMACSHA256 [Managed]
keyringProvider = new EphemeralKeyRing<ManagedAuthenticatedEncryptionOptions>();
keyringProvider = new EphemeralKeyRing<ManagedAuthenticatedEncryptionSettings>();
}
var logger = services.GetLogger<EphemeralDataProtectionProvider>();
@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.DataProtection
}
private sealed class EphemeralKeyRing<T> : IKeyRing, IKeyRingProvider
where T : IInternalAuthenticatedEncryptionOptions, new()
where T : IInternalAuthenticatedEncryptionSettings, new()
{
// Currently hardcoded to a 512-bit KDK.
private const int NUM_BYTES_IN_KDK = 512 / 8;

View File

@ -0,0 +1,69 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using System.IO;
namespace Microsoft.AspNetCore.DataProtection
{
#if !NETSTANDARD1_3
/// <summary>
/// Provides access to configuration for the data protection system, which allows the
/// developer to configure default cryptographic algorithms, key storage locations,
/// and the mechanism by which keys are protected at rest.
/// </summary>
/// <remarks>
/// <para>
/// If the developer changes the at-rest key protection mechanism, it is intended that
/// he also change the key storage location, and vice versa. For instance, a call to
/// <see cref="DataProtectionBuilderExtensions.ProtectKeysWithCertificate(IDataProtectionBuilder,string)" /> should generally be accompanied by
/// a call to <see cref="DataProtectionBuilderExtensions.PersistKeysToFileSystem(IDataProtectionBuilder,DirectoryInfo)"/>, or exceptions may
/// occur at runtime due to the data protection system not knowing where to persist keys.
/// </para>
/// <para>
/// Similarly, when a developer modifies the default protected payload cryptographic
/// algorithms, it is intended that he also select an explitiy key storage location.
/// A call to <see cref="DataProtectionBuilderExtensions.UseCryptographicAlgorithms(IDataProtectionBuilder,AuthenticatedEncryptionSettings)"/>
/// should therefore generally be paired with a call to <see cref="DataProtectionBuilderExtensions.PersistKeysToFileSystem(IDataProtectionBuilder,DirectoryInfo)"/>,
/// for example.
/// </para>
/// <para>
/// When the default cryptographic algorithms or at-rest key protection mechanisms are
/// changed, they only affect <strong>new</strong> keys in the repository. The repository may
/// contain existing keys that use older algorithms or protection mechanisms.
/// </para>
/// </remarks>
#else
/// <summary>
/// Provides access to configuration for the data protection system, which allows the
/// developer to configure default cryptographic algorithms, key storage locations,
/// and the mechanism by which keys are protected at rest.
/// </summary>
/// <remarks>
/// <para>
/// If the developer changes the at-rest key protection mechanism, it is intended that
/// he also change the key storage location, and vice versa.
/// </para>
/// <para>
/// Similarly, when a developer modifies the default protected payload cryptographic
/// algorithms, it is intended that he also select an explitiy key storage location.
/// A call to <see cref="DataProtectionBuilderExtensions.UseCryptographicAlgorithms(IDataProtectionBuilder,AuthenticatedEncryptionSettings)"/>
/// should therefore generally be paired with a call to <see cref="DataProtectionBuilderExtensions.PersistKeysToFileSystem(IDataProtectionBuilder,DirectoryInfo)"/>,
/// for example.
/// </para>
/// <para>
/// When the default cryptographic algorithms or at-rest key protection mechanisms are
/// changed, they only affect <strong>new</strong> keys in the repository. The repository may
/// contain existing keys that use older algorithms or protection mechanisms.
/// </para>
/// </remarks>
#endif
public interface IDataProtectionBuilder
{
/// <summary>
/// Provides access to the <see cref="IServiceCollection"/> passed to this object's constructor.
/// </summary>
IServiceCollection Services { get; }
}
}

View File

@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel;
using System.IO;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Win32;
#if !DOTNET5_4 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml
using System.Security.Cryptography.X509Certificates;
#endif
namespace Microsoft.AspNetCore.DataProtection.Internal
{
/// <summary>
/// Default implementation of <see cref="IDataProtectionBuilder"/>.
/// </summary>
public class DataProtectionBuilder : IDataProtectionBuilder
{
/// <summary>
/// Creates a new configuration object linked to a <see cref="IServiceCollection"/>.
/// </summary>
public DataProtectionBuilder(IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
Services = services;
}
/// <inheritdoc />
public IServiceCollection Services { get; }
}
}

View File

@ -378,6 +378,22 @@ namespace Microsoft.AspNetCore.DataProtection
return GetString("KeyRingProvider_NoDefaultKey_AutoGenerateDisabled");
}
/// <summary>
/// {0} must not be negative
/// </summary>
internal static string LifetimeMustNotBeNegative
{
get { return GetString("LifetimeMustNotBeNegative"); }
}
/// <summary>
/// {0} must not be negative
/// </summary>
internal static string FormatLifetimeMustNotBeNegative(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("LifetimeMustNotBeNegative"), p0);
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -107,19 +107,19 @@ namespace Microsoft.AspNetCore.DataProtection
private IEnumerable<ServiceDescriptor> ResolvePolicyCore()
{
// Read the encryption options type: CNG-CBC, CNG-GCM, Managed
IInternalAuthenticatedEncryptionOptions options = null;
IInternalAuthenticatedEncryptionSettings options = null;
string encryptionType = (string)_policyRegKey.GetValue("EncryptionType");
if (String.Equals(encryptionType, "CNG-CBC", StringComparison.OrdinalIgnoreCase))
{
options = new CngCbcAuthenticatedEncryptionOptions();
options = new CngCbcAuthenticatedEncryptionSettings();
}
else if (String.Equals(encryptionType, "CNG-GCM", StringComparison.OrdinalIgnoreCase))
{
options = new CngGcmAuthenticatedEncryptionOptions();
options = new CngGcmAuthenticatedEncryptionSettings();
}
else if (String.Equals(encryptionType, "Managed", StringComparison.OrdinalIgnoreCase))
{
options = new ManagedAuthenticatedEncryptionOptions();
options = new ManagedAuthenticatedEncryptionSettings();
}
else if (!String.IsNullOrEmpty(encryptionType))
{
@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.DataProtection
if (options != null)
{
PopulateOptions(options, _policyRegKey);
yield return DataProtectionServiceDescriptors.IAuthenticatedEncryptorConfiguration_FromOptions(options);
yield return DataProtectionServiceDescriptors.IAuthenticatedEncryptorConfiguration_FromSettings(options);
}
// Read ancillary data

View File

@ -186,4 +186,7 @@
<data name="KeyRingProvider_NoDefaultKey_AutoGenerateDisabled" xml:space="preserve">
<value>The key ring does not contain a valid default protection key. The data protection system cannot create a new key because auto-generation of keys is disabled.</value>
</data>
<data name="LifetimeMustNotBeNegative" xml:space="preserve">
<value>{0} must not be negative</value>
</data>
</root>

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.DataProtection
Assert.Empty(directory.GetFiles());
// Step 2: instantiate the system and round-trip a payload
var protector = new DataProtectionProvider(directory).CreateProtector("purpose");
var protector = DataProtectionProvider.Create(directory).CreateProtector("purpose");
Assert.Equal("payload", protector.Unprotect(protector.Protect("payload")));
// Step 3: validate that there's now a single key in the directory and that it's not protected
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.DataProtection
Assert.Empty(directory.GetFiles());
// Step 2: instantiate the system and round-trip a payload
var protector = new DataProtectionProvider(directory, configure =>
var protector = DataProtectionProvider.Create(directory, configure =>
{
configure.ProtectKeysWithDpapi();
}).CreateProtector("purpose");

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var control = new AuthenticatedEncryptorDescriptor(
new AuthenticatedEncryptionOptions()
new AuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_192_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA512

View File

@ -160,7 +160,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
private static AuthenticatedEncryptorDescriptor CreateDescriptor(EncryptionAlgorithm encryptionAlgorithm, ValidationAlgorithm validationAlgorithm, ISecret masterKey)
{
return new AuthenticatedEncryptorDescriptor(new AuthenticatedEncryptionOptions()
return new AuthenticatedEncryptorDescriptor(new AuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = encryptionAlgorithm,
ValidationAlgorithm = validationAlgorithm

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey()
{
// Arrange
var configuration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionOptions());
var configuration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionSettings());
// Act
var masterKey1 = ((CngCbcAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey;
@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void CreateNewDescriptor_PropagatesOptions()
{
// Arrange
var configuration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionOptions());
var configuration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionSettings());
// Act
var descriptor = (CngCbcAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor();
// Assert
Assert.Equal(configuration.Options, descriptor.Options);
Assert.Equal(configuration.Settings, descriptor.Settings);
}
}
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var control = new CngCbcAuthenticatedEncryptorDescriptor(
new CngCbcAuthenticatedEncryptionOptions()
new CngCbcAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = Constants.BCRYPT_AES_ALGORITHM,
EncryptionAlgorithmKeySize = 192,

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(new CngCbcAuthenticatedEncryptionOptions()
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(new CngCbcAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(new CngCbcAuthenticatedEncryptionOptions()
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(new CngCbcAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey()
{
// Arrange
var configuration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionOptions());
var configuration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionSettings());
// Act
var masterKey1 = ((CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey;
@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void CreateNewDescriptor_PropagatesOptions()
{
// Arrange
var configuration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionOptions());
var configuration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionSettings());
// Act
var descriptor = (CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor();
// Assert
Assert.Equal(configuration.Options, descriptor.Options);
Assert.Equal(configuration.Settings, descriptor.Settings);
}
}
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var control = new CngGcmAuthenticatedEncryptorDescriptor(
new CngGcmAuthenticatedEncryptionOptions()
new CngGcmAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = Constants.BCRYPT_AES_ALGORITHM,
EncryptionAlgorithmKeySize = 192,

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(new CngGcmAuthenticatedEncryptionOptions()
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(new CngGcmAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(new CngGcmAuthenticatedEncryptionOptions()
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(new CngGcmAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey()
{
// Arrange
var configuration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionOptions());
var configuration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionSettings());
// Act
var masterKey1 = ((ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey;
@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void CreateNewDescriptor_PropagatesOptions()
{
// Arrange
var configuration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionOptions());
var configuration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionSettings());
// Act
var descriptor = (ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor();
// Assert
Assert.Equal(configuration.Options, descriptor.Options);
Assert.Equal(configuration.Settings, descriptor.Settings);
}
}
}

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var control = new ManagedAuthenticatedEncryptorDescriptor(
new ManagedAuthenticatedEncryptionOptions()
new ManagedAuthenticatedEncryptionSettings()
{
EncryptionAlgorithmType = encryptionAlgorithmType,
EncryptionAlgorithmKeySize = 192,
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var control = new ManagedAuthenticatedEncryptorDescriptor(
new ManagedAuthenticatedEncryptionOptions()
new ManagedAuthenticatedEncryptionSettings()
{
EncryptionAlgorithmType = typeof(Aes),
EncryptionAlgorithmKeySize = 192,

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(new ManagedAuthenticatedEncryptionOptions()
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(new ManagedAuthenticatedEncryptionSettings()
{
EncryptionAlgorithmType = typeof(MySymmetricAlgorithm),
EncryptionAlgorithmKeySize = 2048,
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(new ManagedAuthenticatedEncryptionOptions()
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(new ManagedAuthenticatedEncryptionSettings()
{
EncryptionAlgorithmType = encryptionAlgorithmType,
EncryptionAlgorithmKeySize = 2048,

View File

@ -400,7 +400,7 @@ 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(new AuthenticatedEncryptionOptions()).CreateNewDescriptor());
Key key = new Key(Guid.NewGuid(), DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, new AuthenticatedEncryptorConfiguration(new AuthenticatedEncryptionSettings()).CreateNewDescriptor());
var keyRing = new KeyRing(key, new[] { key });
var mockKeyRingProvider = new Mock<IKeyRingProvider>();
mockKeyRingProvider.Setup(o => o.GetCurrentKeyRing()).Returns(keyRing);

View File

@ -78,14 +78,14 @@ namespace Microsoft.AspNetCore.DataProtection
});
var services = serviceCollection.BuildServiceProvider();
var expectedConfiguration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionOptions());
var expectedConfiguration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionSettings());
var actualConfiguration = (CngCbcAuthenticatedEncryptorConfiguration)services.GetService<IAuthenticatedEncryptorConfiguration>();
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithm, actualConfiguration.Options.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmProvider, actualConfiguration.Options.EncryptionAlgorithmProvider);
Assert.Equal(expectedConfiguration.Options.HashAlgorithm, actualConfiguration.Options.HashAlgorithm);
Assert.Equal(expectedConfiguration.Options.HashAlgorithmProvider, actualConfiguration.Options.HashAlgorithmProvider);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithm, actualConfiguration.Settings.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmKeySize, actualConfiguration.Settings.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmProvider, actualConfiguration.Settings.EncryptionAlgorithmProvider);
Assert.Equal(expectedConfiguration.Settings.HashAlgorithm, actualConfiguration.Settings.HashAlgorithm);
Assert.Equal(expectedConfiguration.Settings.HashAlgorithmProvider, actualConfiguration.Settings.HashAlgorithmProvider);
}
[ConditionalFact]
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.DataProtection
});
var services = serviceCollection.BuildServiceProvider();
var expectedConfiguration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionOptions()
var expectedConfiguration = new CngCbcAuthenticatedEncryptorConfiguration(new CngCbcAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,
@ -114,11 +114,11 @@ namespace Microsoft.AspNetCore.DataProtection
});
var actualConfiguration = (CngCbcAuthenticatedEncryptorConfiguration)services.GetService<IAuthenticatedEncryptorConfiguration>();
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithm, actualConfiguration.Options.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmProvider, actualConfiguration.Options.EncryptionAlgorithmProvider);
Assert.Equal(expectedConfiguration.Options.HashAlgorithm, actualConfiguration.Options.HashAlgorithm);
Assert.Equal(expectedConfiguration.Options.HashAlgorithmProvider, actualConfiguration.Options.HashAlgorithmProvider);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithm, actualConfiguration.Settings.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmKeySize, actualConfiguration.Settings.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmProvider, actualConfiguration.Settings.EncryptionAlgorithmProvider);
Assert.Equal(expectedConfiguration.Settings.HashAlgorithm, actualConfiguration.Settings.HashAlgorithm);
Assert.Equal(expectedConfiguration.Settings.HashAlgorithmProvider, actualConfiguration.Settings.HashAlgorithmProvider);
}
[ConditionalFact]
@ -132,12 +132,12 @@ namespace Microsoft.AspNetCore.DataProtection
});
var services = serviceCollection.BuildServiceProvider();
var expectedConfiguration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionOptions());
var expectedConfiguration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionSettings());
var actualConfiguration = (CngGcmAuthenticatedEncryptorConfiguration)services.GetService<IAuthenticatedEncryptorConfiguration>();
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithm, actualConfiguration.Options.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmProvider, actualConfiguration.Options.EncryptionAlgorithmProvider);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithm, actualConfiguration.Settings.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmKeySize, actualConfiguration.Settings.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmProvider, actualConfiguration.Settings.EncryptionAlgorithmProvider);
}
[ConditionalFact]
@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.DataProtection
});
var services = serviceCollection.BuildServiceProvider();
var expectedConfiguration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionOptions()
var expectedConfiguration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionSettings()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,
@ -162,9 +162,9 @@ namespace Microsoft.AspNetCore.DataProtection
});
var actualConfiguration = (CngGcmAuthenticatedEncryptorConfiguration)services.GetService<IAuthenticatedEncryptorConfiguration>();
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithm, actualConfiguration.Options.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmProvider, actualConfiguration.Options.EncryptionAlgorithmProvider);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithm, actualConfiguration.Settings.EncryptionAlgorithm);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmKeySize, actualConfiguration.Settings.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmProvider, actualConfiguration.Settings.EncryptionAlgorithmProvider);
}
[ConditionalFact]
@ -178,12 +178,12 @@ namespace Microsoft.AspNetCore.DataProtection
});
var services = serviceCollection.BuildServiceProvider();
var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionOptions());
var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionSettings());
var actualConfiguration = (ManagedAuthenticatedEncryptorConfiguration)services.GetService<IAuthenticatedEncryptorConfiguration>();
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmType, actualConfiguration.Options.EncryptionAlgorithmType);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Options.ValidationAlgorithmType, actualConfiguration.Options.ValidationAlgorithmType);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmType, actualConfiguration.Settings.EncryptionAlgorithmType);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmKeySize, actualConfiguration.Settings.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Settings.ValidationAlgorithmType, actualConfiguration.Settings.ValidationAlgorithmType);
}
[ConditionalFact]
@ -200,7 +200,7 @@ namespace Microsoft.AspNetCore.DataProtection
});
var services = serviceCollection.BuildServiceProvider();
var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionOptions()
var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionSettings()
{
EncryptionAlgorithmType = typeof(TripleDES),
EncryptionAlgorithmKeySize = 2048,
@ -208,9 +208,9 @@ namespace Microsoft.AspNetCore.DataProtection
});
var actualConfiguration = (ManagedAuthenticatedEncryptorConfiguration)services.GetService<IAuthenticatedEncryptorConfiguration>();
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmType, actualConfiguration.Options.EncryptionAlgorithmType);
Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Options.ValidationAlgorithmType, actualConfiguration.Options.ValidationAlgorithmType);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmType, actualConfiguration.Settings.EncryptionAlgorithmType);
Assert.Equal(expectedConfiguration.Settings.EncryptionAlgorithmKeySize, actualConfiguration.Settings.EncryptionAlgorithmKeySize);
Assert.Equal(expectedConfiguration.Settings.ValidationAlgorithmType, actualConfiguration.Settings.ValidationAlgorithmType);
}
private static void RunTestWithRegValues(IServiceCollection services, Dictionary<string, object> regValues)