Flow logging through the AuthenticatedEncryption types

This commit is contained in:
Levi B 2015-03-12 15:45:41 -07:00
parent 7fe33e8159
commit bf7283697d
21 changed files with 225 additions and 73 deletions

View File

@ -6,6 +6,7 @@ using System.Security.Cryptography;
using Microsoft.AspNet.Cryptography;
using Microsoft.AspNet.Cryptography.Cng;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{
@ -54,15 +55,15 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES
*/
internal IAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret)
internal IAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, IServiceProvider services = null)
{
return CreateImplementationOptions()
.ToConfiguration()
.ToConfiguration(services)
.CreateDescriptorFromSecret(secret)
.CreateEncryptorInstance();
}
internal IInternalAuthenticatedEncryptionOptions CreateImplementationOptions()
private IInternalAuthenticatedEncryptionOptions CreateImplementationOptions()
{
if (IsGcmAlgorithm(EncryptionAlgorithm))
{
@ -192,9 +193,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return (EncryptionAlgorithm.AES_128_GCM <= algorithm && algorithm <= EncryptionAlgorithm.AES_256_GCM);
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration()
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
{
return new AuthenticatedEncryptorConfiguration(this);
return new AuthenticatedEncryptorConfiguration(this, services);
}
}
}

View File

@ -7,6 +7,7 @@ using Microsoft.AspNet.Cryptography.Cng;
using Microsoft.AspNet.Cryptography.SafeHandles;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNet.DataProtection.Cng;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{
@ -93,16 +94,16 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES
*/
internal CbcAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret)
internal CbcAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, ILogger logger = null)
{
return new CbcAuthenticatedEncryptor(
keyDerivationKey: new Secret(secret),
symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(),
symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(logger),
symmetricAlgorithmKeySizeInBytes: (uint)(EncryptionAlgorithmKeySize / 8),
hmacAlgorithmHandle: GetHmacAlgorithmHandle());
hmacAlgorithmHandle: GetHmacAlgorithmHandle(logger));
}
private BCryptAlgorithmHandle GetHmacAlgorithmHandle()
private BCryptAlgorithmHandle GetHmacAlgorithmHandle(ILogger logger)
{
// basic argument checking
if (String.IsNullOrEmpty(HashAlgorithm))
@ -110,6 +111,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(HashAlgorithm));
}
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Opening CNG algorithm '{0}' from provider '{1}' with HMAC.", HashAlgorithm, HashAlgorithmProvider);
}
BCryptAlgorithmHandle algorithmHandle = null;
// Special-case cached providers
@ -134,7 +140,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return algorithmHandle;
}
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle()
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(ILogger logger)
{
// basic argument checking
if (String.IsNullOrEmpty(EncryptionAlgorithm))
@ -146,6 +152,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyMustBeNonNegative(nameof(EncryptionAlgorithmKeySize));
}
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Opening CNG algorithm '{0}' from provider '{1}' with chaining mode CBC.", EncryptionAlgorithm, EncryptionAlgorithmProvider);
}
BCryptAlgorithmHandle algorithmHandle = null;
// Special-case cached providers
@ -172,9 +183,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return algorithmHandle;
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration()
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
{
return new CngCbcAuthenticatedEncryptorConfiguration(this);
return new CngCbcAuthenticatedEncryptorConfiguration(this, services);
}
}
}

View File

@ -7,6 +7,7 @@ using Microsoft.AspNet.Cryptography.Cng;
using Microsoft.AspNet.Cryptography.SafeHandles;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNet.DataProtection.Cng;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{
@ -69,15 +70,15 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES
*/
internal GcmAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret)
internal GcmAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, ILogger logger = null)
{
return new GcmAuthenticatedEncryptor(
keyDerivationKey: new Secret(secret),
symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(),
symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(logger),
symmetricAlgorithmKeySizeInBytes: (uint)(EncryptionAlgorithmKeySize / 8));
}
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle()
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(ILogger logger)
{
// basic argument checking
if (String.IsNullOrEmpty(EncryptionAlgorithm))
@ -91,6 +92,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
BCryptAlgorithmHandle algorithmHandle = null;
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Opening CNG algorithm '{0}' from provider '{1}' with chaining mode GCM.", EncryptionAlgorithm, EncryptionAlgorithmProvider);
}
// Special-case cached providers
if (EncryptionAlgorithmProvider == null)
{
@ -115,9 +121,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return algorithmHandle;
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration()
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
{
return new CngGcmAuthenticatedEncryptorConfiguration(this);
return new CngGcmAuthenticatedEncryptorConfiguration(this, services);
}
}
}

View File

@ -9,26 +9,31 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// <summary>
/// Represents a generalized authenticated encryption mechanism.
/// </summary>
public unsafe sealed class AuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
public sealed class AuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{
private readonly IServiceProvider _services;
public AuthenticatedEncryptorConfiguration([NotNull] AuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public AuthenticatedEncryptorConfiguration([NotNull] AuthenticatedEncryptionOptions options, IServiceProvider services)
{
Options = options;
_services = services;
}
public AuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
// generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
return this.CreateNewDescriptorCore();
}
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new AuthenticatedEncryptorDescriptor(Options, secret);
return new AuthenticatedEncryptorDescriptor(Options, secret, _services);
}
}
}

View File

@ -13,18 +13,27 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class AuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ISecret _masterKey;
private readonly AuthenticatedEncryptionOptions _options;
private readonly IServiceProvider _services;
public AuthenticatedEncryptorDescriptor([NotNull] AuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey)
: this(options, masterKey, services: null)
{
_options = options;
_masterKey = masterKey;
}
public AuthenticatedEncryptorDescriptor([NotNull] AuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey, IServiceProvider services)
{
Options = options;
MasterKey = masterKey;
_services = services;
}
internal ISecret MasterKey { get; }
internal AuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return _options.CreateAuthenticatedEncryptorInstance(_masterKey);
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _services);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -36,17 +45,17 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
// </descriptor>
var encryptionElement = new XElement("encryption",
new XAttribute("algorithm", _options.EncryptionAlgorithm));
new XAttribute("algorithm", Options.EncryptionAlgorithm));
var validationElement = (AuthenticatedEncryptionOptions.IsGcmAlgorithm(_options.EncryptionAlgorithm))
var validationElement = (AuthenticatedEncryptionOptions.IsGcmAlgorithm(Options.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", Options.ValidationAlgorithm));
var outerElement = new XElement("descriptor",
encryptionElement,
validationElement,
_masterKey.ToMasterKeyElement());
MasterKey.ToMasterKeyElement());
return new XmlSerializedDescriptorInfo(outerElement, typeof(AuthenticatedEncryptorDescriptorDeserializer));
}

View File

@ -14,6 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class AuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{
private readonly IServiceProvider _services;
public AuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public AuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary>
/// Imports the <see cref="AuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary>
@ -24,7 +36,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
// <validation algorithm="..." /> <!-- only if not GCM -->
// <masterKey requiresEncryption="true">...</masterKey>
// </descriptor>
var options = new AuthenticatedEncryptionOptions();
var encryptionElement = element.Element("encryption");
@ -38,7 +50,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
}
Secret masterKey = ((string)element.Elements("masterKey").Single()).ToSecret();
return new AuthenticatedEncryptorDescriptor(options, masterKey);
return new AuthenticatedEncryptorDescriptor(options, masterKey, _services);
}
}
}

View File

@ -10,26 +10,31 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// Represents a configured authenticated encryption mechanism which uses
/// Windows CNG algorithms in CBC encryption + HMAC authentication modes.
/// </summary>
public unsafe sealed class CngCbcAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
public sealed class CngCbcAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{
private readonly IServiceProvider _services;
public CngCbcAuthenticatedEncryptorConfiguration([NotNull] CngCbcAuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public CngCbcAuthenticatedEncryptorConfiguration([NotNull] CngCbcAuthenticatedEncryptionOptions options, IServiceProvider services)
{
Options = options;
_services = services;
}
public CngCbcAuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
// generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
return this.CreateNewDescriptorCore();
}
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new CngCbcAuthenticatedEncryptorDescriptor(Options, secret);
return new CngCbcAuthenticatedEncryptorDescriptor(Options, secret, _services);
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Xml.Linq;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{
@ -13,10 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class CngCbcAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ILogger _log;
public CngCbcAuthenticatedEncryptorDescriptor([NotNull] CngCbcAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey)
: this(options, masterKey, services: null)
{
}
public CngCbcAuthenticatedEncryptorDescriptor([NotNull] CngCbcAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey, IServiceProvider services)
{
Options = options;
MasterKey = masterKey;
_log = services.GetLogger<CngCbcAuthenticatedEncryptorDescriptor>();
}
internal ISecret MasterKey { get; }
@ -25,7 +34,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey);
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -51,7 +60,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
{
hashElement.SetAttributeValue("provider", Options.HashAlgorithmProvider);
}
var rootElement = new XElement("descriptor",
new XComment(" Algorithms provided by Windows CNG, using CBC-mode encryption with HMAC validation "),
encryptionElement,

View File

@ -13,6 +13,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class CngCbcAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{
private readonly IServiceProvider _services;
public CngCbcAuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public CngCbcAuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary>
/// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary>
@ -24,7 +36,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
// <hash algorithm="..." [provider="..."] />
// <masterKey>...</masterKey>
// </descriptor>
var options = new CngCbcAuthenticatedEncryptionOptions();
var encryptionElement = element.Element("encryption");
@ -38,7 +50,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
Secret masterKey = ((string)element.Element("masterKey")).ToSecret();
return new CngCbcAuthenticatedEncryptorDescriptor(options, masterKey);
return new CngCbcAuthenticatedEncryptorDescriptor(options, masterKey, _services);
}
}
}

View File

@ -10,26 +10,31 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// Represents a configured authenticated encryption mechanism which uses
/// Windows CNG algorithms in GCM encryption + authentication modes.
/// </summary>
public unsafe sealed class CngGcmAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
public sealed class CngGcmAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{
private readonly IServiceProvider _services;
public CngGcmAuthenticatedEncryptorConfiguration([NotNull] CngGcmAuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public CngGcmAuthenticatedEncryptorConfiguration([NotNull] CngGcmAuthenticatedEncryptionOptions options, IServiceProvider services)
{
Options = options;
_services = services;
}
public CngGcmAuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
// generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
return this.CreateNewDescriptorCore();
}
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new CngGcmAuthenticatedEncryptorDescriptor(Options, secret);
return new CngGcmAuthenticatedEncryptorDescriptor(Options, secret, _services);
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Xml.Linq;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{
@ -13,10 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class CngGcmAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ILogger _log;
public CngGcmAuthenticatedEncryptorDescriptor([NotNull] CngGcmAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey)
: this(options, masterKey, services: null)
{
}
public CngGcmAuthenticatedEncryptorDescriptor([NotNull] CngGcmAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey, IServiceProvider services)
{
Options = options;
MasterKey = masterKey;
_log = services.GetLogger<CngGcmAuthenticatedEncryptorDescriptor>();
}
internal ISecret MasterKey { get; }
@ -25,7 +34,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey);
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
}
public XmlSerializedDescriptorInfo ExportToXml()
@ -43,7 +52,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
{
encryptionElement.SetAttributeValue("provider", Options.EncryptionAlgorithmProvider);
}
var rootElement = new XElement("descriptor",
new XComment(" Algorithms provided by Windows CNG, using Galois/Counter Mode encryption and validation "),
encryptionElement,

View File

@ -13,6 +13,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class CngGcmAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{
private readonly IServiceProvider _services;
public CngGcmAuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public CngGcmAuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary>
/// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary>
@ -33,7 +45,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
Secret masterKey = ((string)element.Element("masterKey")).ToSecret();
return new CngGcmAuthenticatedEncryptorDescriptor(options, masterKey);
return new CngGcmAuthenticatedEncryptorDescriptor(options, masterKey, _services);
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{
internal static class ConfigurationCommon
{
/// <summary>
/// Creates an <see cref="IAuthenticatedEncryptorDescriptor"/> from this <see cref="IInternalAuthenticatedEncryptorConfiguration"/>
/// using a random 512-bit master key generated from a secure PRNG.
/// </summary>
public static IAuthenticatedEncryptorDescriptor CreateNewDescriptorCore(this IInternalAuthenticatedEncryptorConfiguration configuration)
{
const int KDK_SIZE_IN_BYTES = 512 / 8;
return configuration.CreateDescriptorFromSecret(Secret.Random(KDK_SIZE_IN_BYTES));
}
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{
@ -18,7 +19,6 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// Creates a new <see cref="IAuthenticatedEncryptorDescriptor"/> instance from this
/// configuration given specific secret key material.
/// </summary>
/// <returns></returns>
IAuthenticatedEncryptorDescriptor CreateDescriptorFromSecret(ISecret secret);
}
}

View File

@ -13,24 +13,29 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class ManagedAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{
private readonly IServiceProvider _services;
public ManagedAuthenticatedEncryptorConfiguration([NotNull] ManagedAuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public ManagedAuthenticatedEncryptorConfiguration([NotNull] ManagedAuthenticatedEncryptionOptions options, IServiceProvider services)
{
Options = options;
_services = services;
}
public ManagedAuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{
// generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
return this.CreateNewDescriptorCore();
}
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret)
{
return new ManagedAuthenticatedEncryptorDescriptor(Options, secret);
return new ManagedAuthenticatedEncryptorDescriptor(Options, secret, _services);
}
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Security.Cryptography;
using System.Xml.Linq;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{
@ -14,10 +15,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class ManagedAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{
private readonly ILogger _log;
public ManagedAuthenticatedEncryptorDescriptor([NotNull] ManagedAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey)
: this(options, masterKey, services: null)
{
}
public ManagedAuthenticatedEncryptorDescriptor([NotNull] ManagedAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey, IServiceProvider services)
{
Options = options;
MasterKey = masterKey;
_log = services.GetLogger<ManagedAuthenticatedEncryptorDescriptor>();
}
internal ISecret MasterKey { get; }
@ -26,7 +35,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
public IAuthenticatedEncryptor CreateEncryptorInstance()
{
return Options.CreateAuthenticatedEncryptorInstance(MasterKey);
return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
}
public XmlSerializedDescriptorInfo ExportToXml()

View File

@ -14,6 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary>
public sealed class ManagedAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{
private readonly IServiceProvider _services;
public ManagedAuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public ManagedAuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary>
/// Imports the <see cref="ManagedAuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary>
@ -37,7 +49,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
Secret masterKey = ((string)element.Element("masterKey")).ToSecret();
return new ManagedAuthenticatedEncryptorDescriptor(options, masterKey);
return new ManagedAuthenticatedEncryptorDescriptor(options, masterKey, _services);
}
// Any changes to this method should also be be reflected

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
/// Creates a <see cref="IInternalAuthenticatedEncryptorConfiguration"/> object
/// from the given options.
/// </summary>
IInternalAuthenticatedEncryptorConfiguration ToConfiguration();
IInternalAuthenticatedEncryptorConfiguration ToConfiguration(IServiceProvider services);
/// <summary>
/// Performs a self-test of the algorithm specified by the options object.

View File

@ -6,6 +6,7 @@ using System.Security.Cryptography;
using Microsoft.AspNet.Cryptography.Cng;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNet.DataProtection.Managed;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{
@ -68,16 +69,16 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES
*/
internal ManagedAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret)
internal ManagedAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, ILogger logger = null)
{
return new ManagedAuthenticatedEncryptor(
keyDerivationKey: new Secret(secret),
symmetricAlgorithmFactory: GetSymmetricBlockCipherAlgorithmFactory(),
symmetricAlgorithmFactory: GetSymmetricBlockCipherAlgorithmFactory(logger),
symmetricAlgorithmKeySizeInBytes: EncryptionAlgorithmKeySize / 8,
validationAlgorithmFactory: GetKeyedHashAlgorithmFactory());
validationAlgorithmFactory: GetKeyedHashAlgorithmFactory(logger));
}
private Func<KeyedHashAlgorithm> GetKeyedHashAlgorithmFactory()
private Func<KeyedHashAlgorithm> GetKeyedHashAlgorithmFactory(ILogger logger)
{
// basic argument checking
if (ValidationAlgorithmType == null)
@ -85,6 +86,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(ValidationAlgorithmType));
}
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Using managed keyed hash algorithm '{0}'.", ValidationAlgorithmType.FullName);
}
if (ValidationAlgorithmType == typeof(HMACSHA256))
{
return () => new HMACSHA256();
@ -99,7 +105,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
}
}
private Func<SymmetricAlgorithm> GetSymmetricBlockCipherAlgorithmFactory()
private Func<SymmetricAlgorithm> GetSymmetricBlockCipherAlgorithmFactory(ILogger logger)
{
// basic argument checking
if (EncryptionAlgorithmType == null)
@ -112,6 +118,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyMustBeNonNegative(nameof(EncryptionAlgorithmKeySize));
}
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Using managed symmetric algorithm '{0}'.", EncryptionAlgorithmType.FullName);
}
if (EncryptionAlgorithmType == typeof(Aes))
{
Func<Aes> factory = null;
@ -130,9 +141,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
}
}
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration()
IInternalAuthenticatedEncryptorConfiguration IInternalAuthenticatedEncryptionOptions.ToConfiguration(IServiceProvider services)
{
return new ManagedAuthenticatedEncryptorConfiguration(this);
return new ManagedAuthenticatedEncryptorConfiguration(this, services);
}
/// <summary>

View File

@ -66,8 +66,7 @@ namespace Microsoft.Framework.DependencyInjection
/// </summary>
public static ServiceDescriptor IAuthenticatedEncryptorConfiguration_FromOptions(IInternalAuthenticatedEncryptionOptions options)
{
// We don't flow services since there's nothing interesting to flow.
return ServiceDescriptor.Singleton<IAuthenticatedEncryptorConfiguration>(services => options.ToConfiguration());
return ServiceDescriptor.Singleton<IAuthenticatedEncryptorConfiguration>(options.ToConfiguration);
}
#if !DNXCORE50 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml

View File

@ -69,7 +69,7 @@ namespace Microsoft.AspNet.DataProtection
// Currently hardcoded to a 512-bit KDK.
private const int NUM_BYTES_IN_KDK = 512 / 8;
public IAuthenticatedEncryptor DefaultAuthenticatedEncryptor { get; } = new T().ToConfiguration().CreateNewDescriptor().CreateEncryptorInstance();
public IAuthenticatedEncryptor DefaultAuthenticatedEncryptor { get; } = new T().ToConfiguration(services: null).CreateNewDescriptor().CreateEncryptorInstance();
public Guid DefaultKeyId { get; } = default(Guid);