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;
using Microsoft.AspNet.Cryptography.Cng; using Microsoft.AspNet.Cryptography.Cng;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{ {
@ -54,15 +55,15 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES * HELPER ROUTINES
*/ */
internal IAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret) internal IAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, IServiceProvider services = null)
{ {
return CreateImplementationOptions() return CreateImplementationOptions()
.ToConfiguration() .ToConfiguration(services)
.CreateDescriptorFromSecret(secret) .CreateDescriptorFromSecret(secret)
.CreateEncryptorInstance(); .CreateEncryptorInstance();
} }
internal IInternalAuthenticatedEncryptionOptions CreateImplementationOptions() private IInternalAuthenticatedEncryptionOptions CreateImplementationOptions()
{ {
if (IsGcmAlgorithm(EncryptionAlgorithm)) if (IsGcmAlgorithm(EncryptionAlgorithm))
{ {
@ -192,9 +193,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return (EncryptionAlgorithm.AES_128_GCM <= algorithm && algorithm <= EncryptionAlgorithm.AES_256_GCM); 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.Cryptography.SafeHandles;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNet.DataProtection.Cng; using Microsoft.AspNet.DataProtection.Cng;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{ {
@ -93,16 +94,16 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES * HELPER ROUTINES
*/ */
internal CbcAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret) internal CbcAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, ILogger logger = null)
{ {
return new CbcAuthenticatedEncryptor( return new CbcAuthenticatedEncryptor(
keyDerivationKey: new Secret(secret), keyDerivationKey: new Secret(secret),
symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(), symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(logger),
symmetricAlgorithmKeySizeInBytes: (uint)(EncryptionAlgorithmKeySize / 8), symmetricAlgorithmKeySizeInBytes: (uint)(EncryptionAlgorithmKeySize / 8),
hmacAlgorithmHandle: GetHmacAlgorithmHandle()); hmacAlgorithmHandle: GetHmacAlgorithmHandle(logger));
} }
private BCryptAlgorithmHandle GetHmacAlgorithmHandle() private BCryptAlgorithmHandle GetHmacAlgorithmHandle(ILogger logger)
{ {
// basic argument checking // basic argument checking
if (String.IsNullOrEmpty(HashAlgorithm)) if (String.IsNullOrEmpty(HashAlgorithm))
@ -110,6 +111,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(HashAlgorithm)); 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; BCryptAlgorithmHandle algorithmHandle = null;
// Special-case cached providers // Special-case cached providers
@ -134,7 +140,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return algorithmHandle; return algorithmHandle;
} }
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle() private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(ILogger logger)
{ {
// basic argument checking // basic argument checking
if (String.IsNullOrEmpty(EncryptionAlgorithm)) if (String.IsNullOrEmpty(EncryptionAlgorithm))
@ -146,6 +152,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyMustBeNonNegative(nameof(EncryptionAlgorithmKeySize)); 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; BCryptAlgorithmHandle algorithmHandle = null;
// Special-case cached providers // Special-case cached providers
@ -172,9 +183,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return algorithmHandle; 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.Cryptography.SafeHandles;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNet.DataProtection.Cng; using Microsoft.AspNet.DataProtection.Cng;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{ {
@ -69,15 +70,15 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES * HELPER ROUTINES
*/ */
internal GcmAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret) internal GcmAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, ILogger logger = null)
{ {
return new GcmAuthenticatedEncryptor( return new GcmAuthenticatedEncryptor(
keyDerivationKey: new Secret(secret), keyDerivationKey: new Secret(secret),
symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(), symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(logger),
symmetricAlgorithmKeySizeInBytes: (uint)(EncryptionAlgorithmKeySize / 8)); symmetricAlgorithmKeySizeInBytes: (uint)(EncryptionAlgorithmKeySize / 8));
} }
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle() private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(ILogger logger)
{ {
// basic argument checking // basic argument checking
if (String.IsNullOrEmpty(EncryptionAlgorithm)) if (String.IsNullOrEmpty(EncryptionAlgorithm))
@ -91,6 +92,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
BCryptAlgorithmHandle algorithmHandle = null; 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 // Special-case cached providers
if (EncryptionAlgorithmProvider == null) if (EncryptionAlgorithmProvider == null)
{ {
@ -115,9 +121,9 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
return algorithmHandle; 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> /// <summary>
/// Represents a generalized authenticated encryption mechanism. /// Represents a generalized authenticated encryption mechanism.
/// </summary> /// </summary>
public unsafe sealed class AuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration public sealed class AuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{ {
private readonly IServiceProvider _services;
public AuthenticatedEncryptorConfiguration([NotNull] AuthenticatedEncryptionOptions options) public AuthenticatedEncryptorConfiguration([NotNull] AuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public AuthenticatedEncryptorConfiguration([NotNull] AuthenticatedEncryptionOptions options, IServiceProvider services)
{ {
Options = options; Options = options;
_services = services;
} }
public AuthenticatedEncryptionOptions Options { get; } public AuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor() public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{ {
// generate a 512-bit secret randomly return this.CreateNewDescriptorCore();
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
} }
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret) 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> /// </summary>
public sealed class AuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor public sealed class AuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{ {
private readonly ISecret _masterKey; private readonly IServiceProvider _services;
private readonly AuthenticatedEncryptionOptions _options;
public AuthenticatedEncryptorDescriptor([NotNull] AuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey) 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() public IAuthenticatedEncryptor CreateEncryptorInstance()
{ {
return _options.CreateAuthenticatedEncryptorInstance(_masterKey); return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _services);
} }
public XmlSerializedDescriptorInfo ExportToXml() public XmlSerializedDescriptorInfo ExportToXml()
@ -36,17 +45,17 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
// </descriptor> // </descriptor>
var encryptionElement = new XElement("encryption", 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 XComment(" AES-GCM includes a 128-bit authentication tag, no extra validation algorithm required. ")
: (object)new XElement("validation", : (object)new XElement("validation",
new XAttribute("algorithm", _options.ValidationAlgorithm)); new XAttribute("algorithm", Options.ValidationAlgorithm));
var outerElement = new XElement("descriptor", var outerElement = new XElement("descriptor",
encryptionElement, encryptionElement,
validationElement, validationElement,
_masterKey.ToMasterKeyElement()); MasterKey.ToMasterKeyElement());
return new XmlSerializedDescriptorInfo(outerElement, typeof(AuthenticatedEncryptorDescriptorDeserializer)); return new XmlSerializedDescriptorInfo(outerElement, typeof(AuthenticatedEncryptorDescriptorDeserializer));
} }

View File

@ -14,6 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class AuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer public sealed class AuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{ {
private readonly IServiceProvider _services;
public AuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public AuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary> /// <summary>
/// Imports the <see cref="AuthenticatedEncryptorDescriptor"/> from serialized XML. /// Imports the <see cref="AuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary> /// </summary>
@ -24,7 +36,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
// <validation algorithm="..." /> <!-- only if not GCM --> // <validation algorithm="..." /> <!-- only if not GCM -->
// <masterKey requiresEncryption="true">...</masterKey> // <masterKey requiresEncryption="true">...</masterKey>
// </descriptor> // </descriptor>
var options = new AuthenticatedEncryptionOptions(); var options = new AuthenticatedEncryptionOptions();
var encryptionElement = element.Element("encryption"); var encryptionElement = element.Element("encryption");
@ -38,7 +50,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
} }
Secret masterKey = ((string)element.Elements("masterKey").Single()).ToSecret(); 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 /// Represents a configured authenticated encryption mechanism which uses
/// Windows CNG algorithms in CBC encryption + HMAC authentication modes. /// Windows CNG algorithms in CBC encryption + HMAC authentication modes.
/// </summary> /// </summary>
public unsafe sealed class CngCbcAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration public sealed class CngCbcAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{ {
private readonly IServiceProvider _services;
public CngCbcAuthenticatedEncryptorConfiguration([NotNull] CngCbcAuthenticatedEncryptionOptions options) public CngCbcAuthenticatedEncryptorConfiguration([NotNull] CngCbcAuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public CngCbcAuthenticatedEncryptorConfiguration([NotNull] CngCbcAuthenticatedEncryptionOptions options, IServiceProvider services)
{ {
Options = options; Options = options;
_services = services;
} }
public CngCbcAuthenticatedEncryptionOptions Options { get; } public CngCbcAuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor() public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{ {
// generate a 512-bit secret randomly return this.CreateNewDescriptorCore();
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
} }
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret) 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;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{ {
@ -13,10 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class CngCbcAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor public sealed class CngCbcAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{ {
private readonly ILogger _log;
public CngCbcAuthenticatedEncryptorDescriptor([NotNull] CngCbcAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey) 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; Options = options;
MasterKey = masterKey; MasterKey = masterKey;
_log = services.GetLogger<CngCbcAuthenticatedEncryptorDescriptor>();
} }
internal ISecret MasterKey { get; } internal ISecret MasterKey { get; }
@ -25,7 +34,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
public IAuthenticatedEncryptor CreateEncryptorInstance() public IAuthenticatedEncryptor CreateEncryptorInstance()
{ {
return Options.CreateAuthenticatedEncryptorInstance(MasterKey); return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
} }
public XmlSerializedDescriptorInfo ExportToXml() public XmlSerializedDescriptorInfo ExportToXml()
@ -51,7 +60,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
{ {
hashElement.SetAttributeValue("provider", Options.HashAlgorithmProvider); hashElement.SetAttributeValue("provider", Options.HashAlgorithmProvider);
} }
var rootElement = new XElement("descriptor", var rootElement = new XElement("descriptor",
new XComment(" Algorithms provided by Windows CNG, using CBC-mode encryption with HMAC validation "), new XComment(" Algorithms provided by Windows CNG, using CBC-mode encryption with HMAC validation "),
encryptionElement, encryptionElement,

View File

@ -13,6 +13,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class CngCbcAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer public sealed class CngCbcAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{ {
private readonly IServiceProvider _services;
public CngCbcAuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public CngCbcAuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary> /// <summary>
/// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML. /// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary> /// </summary>
@ -24,7 +36,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
// <hash algorithm="..." [provider="..."] /> // <hash algorithm="..." [provider="..."] />
// <masterKey>...</masterKey> // <masterKey>...</masterKey>
// </descriptor> // </descriptor>
var options = new CngCbcAuthenticatedEncryptionOptions(); var options = new CngCbcAuthenticatedEncryptionOptions();
var encryptionElement = element.Element("encryption"); var encryptionElement = element.Element("encryption");
@ -38,7 +50,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
Secret masterKey = ((string)element.Element("masterKey")).ToSecret(); 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 /// Represents a configured authenticated encryption mechanism which uses
/// Windows CNG algorithms in GCM encryption + authentication modes. /// Windows CNG algorithms in GCM encryption + authentication modes.
/// </summary> /// </summary>
public unsafe sealed class CngGcmAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration public sealed class CngGcmAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{ {
private readonly IServiceProvider _services;
public CngGcmAuthenticatedEncryptorConfiguration([NotNull] CngGcmAuthenticatedEncryptionOptions options) public CngGcmAuthenticatedEncryptorConfiguration([NotNull] CngGcmAuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public CngGcmAuthenticatedEncryptorConfiguration([NotNull] CngGcmAuthenticatedEncryptionOptions options, IServiceProvider services)
{ {
Options = options; Options = options;
_services = services;
} }
public CngGcmAuthenticatedEncryptionOptions Options { get; } public CngGcmAuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor() public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{ {
// generate a 512-bit secret randomly return this.CreateNewDescriptorCore();
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
} }
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret) 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;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{ {
@ -13,10 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class CngGcmAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor public sealed class CngGcmAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{ {
private readonly ILogger _log;
public CngGcmAuthenticatedEncryptorDescriptor([NotNull] CngGcmAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey) 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; Options = options;
MasterKey = masterKey; MasterKey = masterKey;
_log = services.GetLogger<CngGcmAuthenticatedEncryptorDescriptor>();
} }
internal ISecret MasterKey { get; } internal ISecret MasterKey { get; }
@ -25,7 +34,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
public IAuthenticatedEncryptor CreateEncryptorInstance() public IAuthenticatedEncryptor CreateEncryptorInstance()
{ {
return Options.CreateAuthenticatedEncryptorInstance(MasterKey); return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
} }
public XmlSerializedDescriptorInfo ExportToXml() public XmlSerializedDescriptorInfo ExportToXml()
@ -43,7 +52,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
{ {
encryptionElement.SetAttributeValue("provider", Options.EncryptionAlgorithmProvider); encryptionElement.SetAttributeValue("provider", Options.EncryptionAlgorithmProvider);
} }
var rootElement = new XElement("descriptor", var rootElement = new XElement("descriptor",
new XComment(" Algorithms provided by Windows CNG, using Galois/Counter Mode encryption and validation "), new XComment(" Algorithms provided by Windows CNG, using Galois/Counter Mode encryption and validation "),
encryptionElement, encryptionElement,

View File

@ -13,6 +13,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class CngGcmAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer public sealed class CngGcmAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{ {
private readonly IServiceProvider _services;
public CngGcmAuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public CngGcmAuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary> /// <summary>
/// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML. /// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary> /// </summary>
@ -33,7 +45,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
Secret masterKey = ((string)element.Element("masterKey")).ToSecret(); 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel 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 /// Creates a new <see cref="IAuthenticatedEncryptorDescriptor"/> instance from this
/// configuration given specific secret key material. /// configuration given specific secret key material.
/// </summary> /// </summary>
/// <returns></returns>
IAuthenticatedEncryptorDescriptor CreateDescriptorFromSecret(ISecret secret); IAuthenticatedEncryptorDescriptor CreateDescriptorFromSecret(ISecret secret);
} }
} }

View File

@ -13,24 +13,29 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class ManagedAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration public sealed class ManagedAuthenticatedEncryptorConfiguration : IAuthenticatedEncryptorConfiguration, IInternalAuthenticatedEncryptorConfiguration
{ {
private readonly IServiceProvider _services;
public ManagedAuthenticatedEncryptorConfiguration([NotNull] ManagedAuthenticatedEncryptionOptions options) public ManagedAuthenticatedEncryptorConfiguration([NotNull] ManagedAuthenticatedEncryptionOptions options)
: this(options, services: null)
{
}
public ManagedAuthenticatedEncryptorConfiguration([NotNull] ManagedAuthenticatedEncryptionOptions options, IServiceProvider services)
{ {
Options = options; Options = options;
_services = services;
} }
public ManagedAuthenticatedEncryptionOptions Options { get; } public ManagedAuthenticatedEncryptionOptions Options { get; }
public IAuthenticatedEncryptorDescriptor CreateNewDescriptor() public IAuthenticatedEncryptorDescriptor CreateNewDescriptor()
{ {
// generate a 512-bit secret randomly return this.CreateNewDescriptorCore();
const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return ((IInternalAuthenticatedEncryptorConfiguration)this).CreateDescriptorFromSecret(secret);
} }
IAuthenticatedEncryptorDescriptor IInternalAuthenticatedEncryptorConfiguration.CreateDescriptorFromSecret(ISecret secret) 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.Security.Cryptography;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel
{ {
@ -14,10 +15,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class ManagedAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor public sealed class ManagedAuthenticatedEncryptorDescriptor : IAuthenticatedEncryptorDescriptor
{ {
private readonly ILogger _log;
public ManagedAuthenticatedEncryptorDescriptor([NotNull] ManagedAuthenticatedEncryptionOptions options, [NotNull] ISecret masterKey) 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; Options = options;
MasterKey = masterKey; MasterKey = masterKey;
_log = services.GetLogger<ManagedAuthenticatedEncryptorDescriptor>();
} }
internal ISecret MasterKey { get; } internal ISecret MasterKey { get; }
@ -26,7 +35,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
public IAuthenticatedEncryptor CreateEncryptorInstance() public IAuthenticatedEncryptor CreateEncryptorInstance()
{ {
return Options.CreateAuthenticatedEncryptorInstance(MasterKey); return Options.CreateAuthenticatedEncryptorInstance(MasterKey, _log);
} }
public XmlSerializedDescriptorInfo ExportToXml() public XmlSerializedDescriptorInfo ExportToXml()

View File

@ -14,6 +14,18 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
/// </summary> /// </summary>
public sealed class ManagedAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer public sealed class ManagedAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer
{ {
private readonly IServiceProvider _services;
public ManagedAuthenticatedEncryptorDescriptorDeserializer()
: this(services: null)
{
}
public ManagedAuthenticatedEncryptorDescriptorDeserializer(IServiceProvider services)
{
_services = services;
}
/// <summary> /// <summary>
/// Imports the <see cref="ManagedAuthenticatedEncryptorDescriptor"/> from serialized XML. /// Imports the <see cref="ManagedAuthenticatedEncryptorDescriptor"/> from serialized XML.
/// </summary> /// </summary>
@ -37,7 +49,7 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationM
Secret masterKey = ((string)element.Element("masterKey")).ToSecret(); 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 // 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 /// Creates a <see cref="IInternalAuthenticatedEncryptorConfiguration"/> object
/// from the given options. /// from the given options.
/// </summary> /// </summary>
IInternalAuthenticatedEncryptorConfiguration ToConfiguration(); IInternalAuthenticatedEncryptorConfiguration ToConfiguration(IServiceProvider services);
/// <summary> /// <summary>
/// Performs a self-test of the algorithm specified by the options object. /// 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.Cryptography.Cng;
using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNet.DataProtection.Managed; using Microsoft.AspNet.DataProtection.Managed;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
{ {
@ -68,16 +69,16 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
* HELPER ROUTINES * HELPER ROUTINES
*/ */
internal ManagedAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret) internal ManagedAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(ISecret secret, ILogger logger = null)
{ {
return new ManagedAuthenticatedEncryptor( return new ManagedAuthenticatedEncryptor(
keyDerivationKey: new Secret(secret), keyDerivationKey: new Secret(secret),
symmetricAlgorithmFactory: GetSymmetricBlockCipherAlgorithmFactory(), symmetricAlgorithmFactory: GetSymmetricBlockCipherAlgorithmFactory(logger),
symmetricAlgorithmKeySizeInBytes: EncryptionAlgorithmKeySize / 8, symmetricAlgorithmKeySizeInBytes: EncryptionAlgorithmKeySize / 8,
validationAlgorithmFactory: GetKeyedHashAlgorithmFactory()); validationAlgorithmFactory: GetKeyedHashAlgorithmFactory(logger));
} }
private Func<KeyedHashAlgorithm> GetKeyedHashAlgorithmFactory() private Func<KeyedHashAlgorithm> GetKeyedHashAlgorithmFactory(ILogger logger)
{ {
// basic argument checking // basic argument checking
if (ValidationAlgorithmType == null) if (ValidationAlgorithmType == null)
@ -85,6 +86,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(ValidationAlgorithmType)); throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(ValidationAlgorithmType));
} }
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Using managed keyed hash algorithm '{0}'.", ValidationAlgorithmType.FullName);
}
if (ValidationAlgorithmType == typeof(HMACSHA256)) if (ValidationAlgorithmType == typeof(HMACSHA256))
{ {
return () => new 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 // basic argument checking
if (EncryptionAlgorithmType == null) if (EncryptionAlgorithmType == null)
@ -112,6 +118,11 @@ namespace Microsoft.AspNet.DataProtection.AuthenticatedEncryption
throw Error.Common_PropertyMustBeNonNegative(nameof(EncryptionAlgorithmKeySize)); throw Error.Common_PropertyMustBeNonNegative(nameof(EncryptionAlgorithmKeySize));
} }
if (logger.IsVerboseLevelEnabled())
{
logger.LogVerbose("Using managed symmetric algorithm '{0}'.", EncryptionAlgorithmType.FullName);
}
if (EncryptionAlgorithmType == typeof(Aes)) if (EncryptionAlgorithmType == typeof(Aes))
{ {
Func<Aes> factory = null; 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> /// <summary>

View File

@ -66,8 +66,7 @@ namespace Microsoft.Framework.DependencyInjection
/// </summary> /// </summary>
public static ServiceDescriptor IAuthenticatedEncryptorConfiguration_FromOptions(IInternalAuthenticatedEncryptionOptions options) public static ServiceDescriptor IAuthenticatedEncryptorConfiguration_FromOptions(IInternalAuthenticatedEncryptionOptions options)
{ {
// We don't flow services since there's nothing interesting to flow. return ServiceDescriptor.Singleton<IAuthenticatedEncryptorConfiguration>(options.ToConfiguration);
return ServiceDescriptor.Singleton<IAuthenticatedEncryptorConfiguration>(services => options.ToConfiguration());
} }
#if !DNXCORE50 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml #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. // Currently hardcoded to a 512-bit KDK.
private const int NUM_BYTES_IN_KDK = 512 / 8; 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); public Guid DefaultKeyId { get; } = default(Guid);