Преглед изворни кода

[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.
jacalvar пре 10 година
родитељ
комит
aa1495deb0
42 измењених фајлова са 908 додато и 721 уклоњено
  1. 22 27
      src/Microsoft.AspNetCore.DataProtection.Extensions/DataProtectionProvider.cs
  2. 8 8
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/AuthenticatedEncryptionSettings.cs
  3. 4 4
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/CngCbcAuthenticatedEncryptionSettings.cs
  4. 4 4
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/CngGcmAuthenticatedEncryptionSettings.cs
  5. 8 8
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorConfiguration.cs
  6. 12 12
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptor.cs
  7. 5 5
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializer.cs
  8. 8 8
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfiguration.cs
  9. 16 16
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptor.cs
  10. 7 7
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializer.cs
  11. 8 8
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfiguration.cs
  12. 13 13
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptor.cs
  13. 5 5
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializer.cs
  14. 8 8
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfiguration.cs
  15. 12 12
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptor.cs
  16. 5 5
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializer.cs
  17. 4 4
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/IInternalAuthenticatedEncryptionSettings.cs
  18. 4 4
      src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ManagedAuthenticatedEncryptionSettings.cs
  19. 546 0
      src/Microsoft.AspNetCore.DataProtection/DataProtectionBuilderExtensions.cs
  20. 0 484
      src/Microsoft.AspNetCore.DataProtection/DataProtectionConfiguration.cs
  21. 17 16
      src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs
  22. 3 3
      src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceDescriptors.cs
  23. 3 3
      src/Microsoft.AspNetCore.DataProtection/EphemeralDataProtectionProvider.cs
  24. 69 0
      src/Microsoft.AspNetCore.DataProtection/IDataProtectionBuilder.cs
  25. 41 0
      src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionBuilder.cs
  26. 16 0
      src/Microsoft.AspNetCore.DataProtection/Properties/Resources.Designer.cs
  27. 5 5
      src/Microsoft.AspNetCore.DataProtection/RegistryPolicyResolver.cs
  28. 3 0
      src/Microsoft.AspNetCore.DataProtection/Resources.resx
  29. 2 2
      test/Microsoft.AspNetCore.DataProtection.Extensions.Test/DataProtectionProviderTests.cs
  30. 1 1
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializerTests.cs
  31. 1 1
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs
  32. 3 3
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfigurationTests.cs
  33. 1 1
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializerTests.cs
  34. 2 2
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorTests.cs
  35. 3 3
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfigurationTests.cs
  36. 1 1
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializerTests.cs
  37. 2 2
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorTests.cs
  38. 3 3
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfigurationTests.cs
  39. 2 2
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs
  40. 2 2
      test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs
  41. 1 1
      test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyRingBasedDataProtectorTests.cs
  42. 28 28
      test/Microsoft.AspNetCore.DataProtection.Test/RegistryPolicyResolverTests.cs

+ 22 - 27
src/Microsoft.AspNetCore.DataProtection.Extensions/DataProtectionProvider.cs

@@ -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);
-            });
+                throw new ArgumentNullException(nameof(setupAction));
+            }
 
-            // extract the provider instance from the service collection
-            _innerProvider = serviceCollection.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
-        }
+            // build the service collection
+            var serviceCollection = new ServiceCollection();
+            var builder = serviceCollection.AddDataProtection();
+            builder.PersistKeysToFileSystem(keyDirectory);
 
-        /// <summary>
-        /// Implements <see cref="IDataProtectionProvider.CreateProtector(string)"/>.
-        /// </summary>
-        public IDataProtector CreateProtector(string purpose)
-        {
-            if (purpose == null)
+            if (setupAction != null)
             {
-                throw new ArgumentNullException(nameof(purpose));
+                setupAction(builder);
             }
 
-            return _innerProvider.CreateProtector(purpose);
+            // extract the provider instance from the service collection
+            return serviceCollection.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
         }
     }
-}
+}

+ 8 - 8
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/AuthenticatedEncryptionOptions.cs → src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/AuthenticatedEncryptionSettings.cs

@@ -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);
         }

+ 4 - 4
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/CngCbcAuthenticatedEncryptionOptions.cs → src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/CngCbcAuthenticatedEncryptionSettings.cs

@@ -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);
         }

+ 4 - 4
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/CngGcmAuthenticatedEncryptionOptions.cs → src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/CngGcmAuthenticatedEncryptionSettings.cs

@@ -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);
         }

+ 8 - 8
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorConfiguration.cs

@@ -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);
         }
     }
 }

+ 12 - 12
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptor.cs

@@ -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,

+ 5 - 5
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializer.cs

@@ -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);
         }
     }
 }

+ 8 - 8
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfiguration.cs

@@ -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);
         }
     }
 }

+ 16 - 16
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptor.cs

@@ -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",

+ 7 - 7
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializer.cs

@@ -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);
         }
     }
 }

+ 8 - 8
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfiguration.cs

@@ -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);
         }
     }
 }

+ 13 - 13
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptor.cs

@@ -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",

+ 5 - 5
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializer.cs

@@ -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);
         }
     }
 }

+ 8 - 8
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfiguration.cs

@@ -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);
         }
     }
 }

+ 12 - 12
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptor.cs

@@ -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 "),

+ 5 - 5
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializer.cs

@@ -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

+ 4 - 4
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/IInternalAuthenticatedEncryptionOptions.cs → src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/IInternalAuthenticatedEncryptionSettings.cs

@@ -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();
     }

+ 4 - 4
src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ManagedAuthenticatedEncryptionOptions.cs → src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ManagedAuthenticatedEncryptionSettings.cs

@@ -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);
         }

+ 546 - 0
src/Microsoft.AspNetCore.DataProtection/DataProtectionBuilderExtensions.cs

@@ -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);
+        }
+    }
+}

+ 0 - 484
src/Microsoft.AspNetCore.DataProtection/DataProtectionConfiguration.cs

@@ -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);
-        }
-    }
-}

+ 17 - 16
src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs

@@ -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;
         }
     }
 }

+ 3 - 3
src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceDescriptors.cs

@@ -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);
         }

+ 3 - 3
src/Microsoft.AspNetCore.DataProtection/EphemeralDataProtectionProvider.cs

@@ -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;

+ 69 - 0
src/Microsoft.AspNetCore.DataProtection/IDataProtectionBuilder.cs

@@ -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; }
+    }
+}

+ 41 - 0
src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionBuilder.cs

@@ -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; }
+    }
+}

+ 16 - 0
src/Microsoft.AspNetCore.DataProtection/Properties/Resources.Designer.cs

@@ -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);

+ 5 - 5
src/Microsoft.AspNetCore.DataProtection/RegistryPolicyResolver.cs

@@ -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

+ 3 - 0
src/Microsoft.AspNetCore.DataProtection/Resources.resx

@@ -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>

+ 2 - 2
test/Microsoft.AspNetCore.DataProtection.Extensions.Test/DataProtectionProviderTests.cs

@@ -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");

+ 1 - 1
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializerTests.cs

@@ -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

+ 1 - 1
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs

@@ -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

+ 3 - 3
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfigurationTests.cs

@@ -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);
         }
     }
 }

+ 1 - 1
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializerTests.cs

@@ -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,

+ 2 - 2
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorTests.cs

@@ -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,

+ 3 - 3
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfigurationTests.cs

@@ -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);
         }
     }
 }

+ 1 - 1
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializerTests.cs

@@ -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,

+ 2 - 2
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorTests.cs

@@ -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

+ 3 - 3
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfigurationTests.cs

@@ -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);
         }
     }
 }

+ 2 - 2
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs

@@ -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,

+ 2 - 2
test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs

@@ -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,

+ 1 - 1
test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyRingBasedDataProtectorTests.cs

@@ -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);

+ 28 - 28
test/Microsoft.AspNetCore.DataProtection.Test/RegistryPolicyResolverTests.cs

@@ -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)