public async Task ExpectFullKeyManagerExplicitAwsStoreRetrieveToSucceed()
        {
            var config = new S3XmlRepositoryConfig(S3IntegrationTests.BucketName) { KeyPrefix = "RealXmlKeyManager1/" };
            await s3Cleanup.ClearKeys(S3IntegrationTests.BucketName, config.KeyPrefix);

            var serviceCollection = new ServiceCollection();
            serviceCollection.AddDataProtection()
                             .PersistKeysToAwsS3(s3Client, config);
            using (var serviceProvider = serviceCollection.BuildServiceProvider())
            {
                var keyManager = new XmlKeyManager(serviceProvider.GetRequiredService<IOptions<KeyManagementOptions>>(),
                                                   serviceProvider.GetRequiredService<IActivator>());

                var activationDate = new DateTimeOffset(new DateTime(1980, 1, 1));
                var expirationDate = new DateTimeOffset(new DateTime(1980, 6, 1));
                keyManager.CreateNewKey(activationDate, expirationDate);

                IReadOnlyCollection<IKey> keys = keyManager.GetAllKeys();

                Assert.Equal(1, keys.Count);
                Assert.Equal(activationDate, keys.Single().ActivationDate);
                Assert.Equal(expirationDate, keys.Single().ExpirationDate);
                Assert.NotNull(keys.Single().Descriptor);
            }
        }
        public async Task ExpectFullKeyManagerStoreRetrieveWithConfigToSucceed()
        {
            var section = fixture.Configuration.GetSection("s3ImplicitAwsTestCase");

            // Just make sure config is what is actually expected - of course normally you'd not access the config like this directly
            Assert.Equal(S3IntegrationTests.BucketName, section["bucket"]);
            Assert.Equal("RealXmlKeyManager3/", section["keyPrefix"]);

            await s3Cleanup.ClearKeys(S3IntegrationTests.BucketName, section["keyPrefix"]);

            var serviceCollection = new ServiceCollection();
            serviceCollection.AddSingleton(s3Client);
            serviceCollection.AddDataProtection()
                             .PersistKeysToAwsS3(section);
            using (var serviceProvider = serviceCollection.BuildServiceProvider())
            {
                var keyManager = new XmlKeyManager(serviceProvider.GetRequiredService<IOptions<KeyManagementOptions>>(),
                                                   serviceProvider.GetRequiredService<IActivator>());

                var activationDate = new DateTimeOffset(new DateTime(1980, 1, 1));
                var expirationDate = new DateTimeOffset(new DateTime(1980, 6, 1));
                keyManager.CreateNewKey(activationDate, expirationDate);

                IReadOnlyCollection<IKey> keys = keyManager.GetAllKeys();

                Assert.Equal(1, keys.Count);
                Assert.Equal(activationDate, keys.Single().ActivationDate);
                Assert.Equal(expirationDate, keys.Single().ExpirationDate);
                Assert.NotNull(keys.Single().Descriptor);
            }
        }
Exemple #3
0
    public void CreateNewKey_CallsInternalManager()
    {
        // Arrange
        DateTimeOffset minCreationDate        = DateTimeOffset.UtcNow;
        DateTimeOffset?actualCreationDate     = null;
        DateTimeOffset activationDate         = minCreationDate + TimeSpan.FromDays(7);
        DateTimeOffset expirationDate         = activationDate.AddMonths(1);
        var            mockInternalKeyManager = new Mock <IInternalXmlKeyManager>();

        mockInternalKeyManager
        .Setup(o => o.CreateNewKey(It.IsAny <Guid>(), It.IsAny <DateTimeOffset>(), activationDate, expirationDate))
        .Callback <Guid, DateTimeOffset, DateTimeOffset, DateTimeOffset>((innerKeyId, innerCreationDate, innerActivationDate, innerExpirationDate) =>
        {
            actualCreationDate = innerCreationDate;
        });

        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = new Mock <AlgorithmConfiguration>().Object,
            XmlRepository = new Mock <IXmlRepository>().Object,
            XmlEncryptor  = null
        });
        var keyManager = new XmlKeyManager(options, SimpleActivator.DefaultWithoutServices, NullLoggerFactory.Instance, mockInternalKeyManager.Object);

        // Act
        keyManager.CreateNewKey(activationDate, expirationDate);

        // Assert
        Assert.InRange(actualCreationDate.Value, minCreationDate, DateTimeOffset.UtcNow);
    }
Exemple #4
0
    public void RevokeKey_CallsInternalManager()
    {
        // Arrange
        var            keyToRevoke            = new Guid("a11f35fc-1fed-4bd4-b727-056a63b70932");
        DateTimeOffset minRevocationDate      = DateTimeOffset.UtcNow;
        DateTimeOffset?actualRevocationDate   = null;
        var            mockInternalKeyManager = new Mock <IInternalXmlKeyManager>();

        mockInternalKeyManager
        .Setup(o => o.RevokeSingleKey(keyToRevoke, It.IsAny <DateTimeOffset>(), "Here's some reason text."))
        .Callback <Guid, DateTimeOffset, string>((innerKeyId, innerRevocationDate, innerReason) =>
        {
            actualRevocationDate = innerRevocationDate;
        });

        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = new Mock <AlgorithmConfiguration>().Object,
            XmlRepository = new Mock <IXmlRepository>().Object,
            XmlEncryptor  = null
        });
        var keyManager = new XmlKeyManager(options, SimpleActivator.DefaultWithoutServices, NullLoggerFactory.Instance, mockInternalKeyManager.Object);

        // Act
        keyManager.RevokeKey(keyToRevoke, "Here's some reason text.");

        // Assert
        Assert.InRange(actualRevocationDate.Value, minRevocationDate, DateTimeOffset.UtcNow);
    }
Exemple #5
0
        public void ExpectFullKeyManagerStoreRetrieveToSucceed()
        {
            var config = new KmsXmlEncryptorConfig(KmsIntegrationTests.KmsTestingKey);

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton(kmsClient);
            serviceCollection.AddDataProtection()
            .PersistKeysToEphemeral()
            .ProtectKeysWithAwsKms(config);
            using (var serviceProvider = serviceCollection.BuildServiceProvider())
            {
                var keyManager = new XmlKeyManager(serviceProvider.GetRequiredService <IOptions <KeyManagementOptions> >(),
                                                   serviceProvider.GetRequiredService <IActivator>());

                var activationDate = new DateTimeOffset(new DateTime(1980, 1, 1));
                var expirationDate = new DateTimeOffset(new DateTime(1980, 6, 1));
                keyManager.CreateNewKey(activationDate, expirationDate);

                IReadOnlyCollection <IKey> keys = keyManager.GetAllKeys();

                Assert.Equal(1, keys.Count);
                Assert.Equal(activationDate, keys.Single().ActivationDate);
                Assert.Equal(expirationDate, keys.Single().ExpirationDate);
                Assert.NotNull(keys.Single().Descriptor);
            }
        }
Exemple #6
0
        public void ExpectFullKeyManagerExplicitAwsStoreRetrieveWithConfigToSucceed()
        {
            var section = fixture.Configuration.GetSection("kmsTestCase");

            // Just make sure config is what is actually expected - of course normally you'd not access the config like this directly
            Assert.Equal(KmsIntegrationTests.KmsTestingKey, section["keyId"]);

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddDataProtection()
            .PersistKeysToEphemeral()
            .ProtectKeysWithAwsKms(kmsClient, section);
            using (var serviceProvider = serviceCollection.BuildServiceProvider())
            {
                var keyManager = new XmlKeyManager(serviceProvider.GetRequiredService <IOptions <KeyManagementOptions> >(),
                                                   serviceProvider.GetRequiredService <IActivator>());

                var activationDate = new DateTimeOffset(new DateTime(1980, 1, 1));
                var expirationDate = new DateTimeOffset(new DateTime(1980, 6, 1));
                keyManager.CreateNewKey(activationDate, expirationDate);

                IReadOnlyCollection <IKey> keys = keyManager.GetAllKeys();

                Assert.Equal(1, keys.Count);
                Assert.Equal(activationDate, keys.Single().ActivationDate);
                Assert.Equal(expirationDate, keys.Single().ExpirationDate);
                Assert.NotNull(keys.Single().Descriptor);
            }
        }
        public void ExpectFullKeyManagerStoreRetrieveToSucceed()
        {
            var config = new KmsXmlEncryptorConfig(KmsIntegrationTests.ApplicationName, KmsIntegrationTests.KmsTestingKey);

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton(kmsClient);
            serviceCollection.AddDataProtection()
            .ProtectKeysWithAwsKms(config);
            serviceCollection.AddSingleton <IXmlRepository, EphemeralXmlRepository>();
            var serviceProvider = serviceCollection.BuildServiceProvider();

            var keyManager = new XmlKeyManager(serviceProvider.GetRequiredService <IXmlRepository>(),
                                               serviceProvider.GetRequiredService <IAuthenticatedEncryptorConfiguration>(),
                                               serviceProvider);

            var activationDate = new DateTimeOffset(new DateTime(1980, 1, 1));
            var expirationDate = new DateTimeOffset(new DateTime(1980, 6, 1));

            keyManager.CreateNewKey(activationDate, expirationDate);

            IReadOnlyCollection <IKey> keys = keyManager.GetAllKeys();

            Assert.Equal(1, keys.Count);
            Assert.Equal(activationDate, keys.Single().ActivationDate);
            Assert.Equal(expirationDate, keys.Single().ExpirationDate);
        }
Exemple #8
0
        public async Task ExpectFullKeyManagerStoreRetrieveToSucceed()
        {
            var s3Config = new S3XmlRepositoryConfig(S3IntegrationTests.BucketName)
            {
                KeyPrefix = "CombinedXmlKeyManager2/"
            };
            await s3Cleanup.ClearKeys(S3IntegrationTests.BucketName, s3Config.KeyPrefix);

            var kmsConfig = new KmsXmlEncryptorConfig(KmsIntegrationTests.ApplicationName, KmsIntegrationTests.KmsTestingKey);

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton(s3Client);
            serviceCollection.AddSingleton(kmsClient);
            serviceCollection.AddDataProtection()
            .PersistKeysToAwsS3(s3Config)
            .ProtectKeysWithAwsKms(kmsConfig);
            var serviceProvider = serviceCollection.BuildServiceProvider();

            var keyManager = new XmlKeyManager(serviceProvider.GetRequiredService <IXmlRepository>(),
                                               serviceProvider.GetRequiredService <IAuthenticatedEncryptorConfiguration>(),
                                               serviceProvider);

            var activationDate = new DateTimeOffset(new DateTime(1980, 1, 1));
            var expirationDate = new DateTimeOffset(new DateTime(1980, 6, 1));

            keyManager.CreateNewKey(activationDate, expirationDate);

            IReadOnlyCollection <IKey> keys = keyManager.GetAllKeys();

            Assert.Equal(1, keys.Count);
            Assert.Equal(activationDate, keys.Single().ActivationDate);
            Assert.Equal(expirationDate, keys.Single().ExpirationDate);
        }
Exemple #9
0
    public void RevokeSingleKey_Internal()
    {
        // Arrange - mocks
        XElement elementStoredInRepository      = null;
        string   friendlyNameStoredInRepository = null;
        var      mockXmlRepository = new Mock <IXmlRepository>();

        mockXmlRepository
        .Setup(o => o.StoreElement(It.IsAny <XElement>(), It.IsAny <string>()))
        .Callback <XElement, string>((el, friendlyName) =>
        {
            elementStoredInRepository      = el;
            friendlyNameStoredInRepository = friendlyName;
        });

        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = new Mock <AlgorithmConfiguration>().Object,
            XmlRepository = mockXmlRepository.Object,
            XmlEncryptor  = null
        });
        var keyManager = new XmlKeyManager(options, SimpleActivator.DefaultWithoutServices, NullLoggerFactory.Instance);

        var revocationDate = new DateTimeOffset(2014, 01, 01, 0, 0, 0, TimeSpan.Zero);

        // Act & assert

        // The cancellation token should not already be fired
        var firstCancellationToken = keyManager.GetCacheExpirationToken();

        Assert.False(firstCancellationToken.IsCancellationRequested);

        // After the call to RevokeKey, the first CT should be fired,
        // and we should've gotten a new CT.
        ((IInternalXmlKeyManager)keyManager).RevokeSingleKey(
            keyId: new Guid("a11f35fc-1fed-4bd4-b727-056a63b70932"),
            revocationDate: revocationDate,
            reason: "Here's some reason text.");
        var secondCancellationToken = keyManager.GetCacheExpirationToken();

        Assert.True(firstCancellationToken.IsCancellationRequested);
        Assert.False(secondCancellationToken.IsCancellationRequested);

        // Was the correct element stored in the repository?
        var expectedRepositoryXml = string.Format(
            CultureInfo.InvariantCulture,
            @"
                <revocation version='1'>
                  {0}
                  <key id='a11f35fc-1fed-4bd4-b727-056a63b70932' />
                  <reason>Here's some reason text.</reason>
                </revocation>",
            new XElement("revocationDate", revocationDate));

        XmlAssert.Equal(expectedRepositoryXml, elementStoredInRepository);
        Assert.Equal("revocation-a11f35fc-1fed-4bd4-b727-056a63b70932", friendlyNameStoredInRepository);
    }
Exemple #10
0
    public void RevokeAllKeys()
    {
        // Arrange
        XElement elementStoredInRepository      = null;
        string   friendlyNameStoredInRepository = null;
        var      mockXmlRepository = new Mock <IXmlRepository>();

        mockXmlRepository
        .Setup(o => o.StoreElement(It.IsAny <XElement>(), It.IsAny <string>()))
        .Callback <XElement, string>((el, friendlyName) =>
        {
            elementStoredInRepository      = el;
            friendlyNameStoredInRepository = friendlyName;
        });

        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = new Mock <AlgorithmConfiguration>().Object,
            XmlRepository = mockXmlRepository.Object,
            XmlEncryptor  = null
        });
        var keyManager = new XmlKeyManager(options, SimpleActivator.DefaultWithoutServices, NullLoggerFactory.Instance);

        var revocationDate = XmlConvert.ToDateTimeOffset("2015-03-01T19:13:19.7573854-08:00");

        // Act & assert

        // The cancellation token should not already be fired
        var firstCancellationToken = keyManager.GetCacheExpirationToken();

        Assert.False(firstCancellationToken.IsCancellationRequested);

        // After the call to RevokeAllKeys, the first CT should be fired,
        // and we should've gotten a new CT.
        keyManager.RevokeAllKeys(revocationDate, "Here's some reason text.");
        var secondCancellationToken = keyManager.GetCacheExpirationToken();

        Assert.True(firstCancellationToken.IsCancellationRequested);
        Assert.False(secondCancellationToken.IsCancellationRequested);

        // Was the correct element stored in the repository?
        const string expectedRepositoryXml = @"
                <revocation version='1'>
                  <revocationDate>2015-03-01T19:13:19.7573854-08:00</revocationDate>
                  <!--All keys created before the revocation date are revoked.-->
                  <key id='*' />
                  <reason>Here's some reason text.</reason>
                </revocation>";

        XmlAssert.Equal(expectedRepositoryXml, elementStoredInRepository);
        Assert.Equal("revocation-20150302T0313197573854Z", friendlyNameStoredInRepository);
    }
Exemple #11
0
    private static IReadOnlyCollection <IKey> RunGetAllKeysCore(string xml, IActivator activator, ILoggerFactory loggerFactory = null)
    {
        // Arrange
        var mockXmlRepository = new Mock <IXmlRepository>();

        mockXmlRepository.Setup(o => o.GetAllElements()).Returns(XElement.Parse(xml).Elements().ToArray());
        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = new Mock <AlgorithmConfiguration>().Object,
            XmlRepository = mockXmlRepository.Object,
            XmlEncryptor  = null
        });
        var keyManager = new XmlKeyManager(options, activator, loggerFactory ?? NullLoggerFactory.Instance);

        // Act
        return(keyManager.GetAllKeys());
    }
Exemple #12
0
    public void Ctor_WithoutEncryptorOrRepository_UsesFallback()
    {
        // Arrange
        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = new Mock <AlgorithmConfiguration>().Object,
            XmlRepository = null,
            XmlEncryptor  = null
        });

        // Act
        var keyManager = new XmlKeyManager(options, SimpleActivator.DefaultWithoutServices, NullLoggerFactory.Instance);

        // Assert
        Assert.NotNull(keyManager.KeyRepository);

        if (OSVersionUtil.IsWindows())
        {
            Assert.NotNull(keyManager.KeyEncryptor);
        }
    }
 public KeyManager(IOptions <KeyManagementOptions> options, IActivator activator)
 {
     _wrapped = new XmlKeyManager(options, activator, NullLoggerFactory.Instance);
 }
Exemple #14
0
    public void CreateNewKey_Internal_NoEscrowOrEncryption()
    {
        // Constants
        var creationDate   = new DateTimeOffset(2014, 01, 01, 0, 0, 0, TimeSpan.Zero);
        var activationDate = new DateTimeOffset(2014, 02, 01, 0, 0, 0, TimeSpan.Zero);
        var expirationDate = new DateTimeOffset(2014, 03, 01, 0, 0, 0, TimeSpan.Zero);
        var keyId          = new Guid("3d6d01fd-c0e7-44ae-82dd-013b996b4093");

        // Arrange
        XElement elementStoredInRepository      = null;
        string   friendlyNameStoredInRepository = null;
        var      expectedAuthenticatedEncryptor = new Mock <IAuthenticatedEncryptor>().Object;
        var      mockDescriptor = new Mock <IAuthenticatedEncryptorDescriptor>();

        mockDescriptor.Setup(o => o.ExportToXml()).Returns(new XmlSerializedDescriptorInfo(serializedDescriptor, typeof(MyDeserializer)));
        var expectedDescriptor   = mockDescriptor.Object;
        var testEncryptorFactory = new TestEncryptorFactory(expectedDescriptor, expectedAuthenticatedEncryptor);
        var mockConfiguration    = new Mock <AlgorithmConfiguration>();

        mockConfiguration.Setup(o => o.CreateNewDescriptor()).Returns(expectedDescriptor);
        var mockXmlRepository = new Mock <IXmlRepository>();

        mockXmlRepository
        .Setup(o => o.StoreElement(It.IsAny <XElement>(), It.IsAny <string>()))
        .Callback <XElement, string>((el, friendlyName) =>
        {
            elementStoredInRepository      = el;
            friendlyNameStoredInRepository = friendlyName;
        });
        var options = Options.Create(new KeyManagementOptions()
        {
            AuthenticatedEncryptorConfiguration = mockConfiguration.Object,
            XmlRepository = mockXmlRepository.Object,
            XmlEncryptor  = null
        });

        options.Value.AuthenticatedEncryptorFactories.Add(testEncryptorFactory);

        var keyManager = new XmlKeyManager(options, SimpleActivator.DefaultWithoutServices, NullLoggerFactory.Instance);

        // Act & assert

        // The cancellation token should not already be fired
        var firstCancellationToken = keyManager.GetCacheExpirationToken();

        Assert.False(firstCancellationToken.IsCancellationRequested);

        // After the call to CreateNewKey, the first CT should be fired,
        // and we should've gotten a new CT.
        var newKey = ((IInternalXmlKeyManager)keyManager).CreateNewKey(
            keyId: keyId,
            creationDate: creationDate,
            activationDate: activationDate,
            expirationDate: expirationDate);
        var secondCancellationToken = keyManager.GetCacheExpirationToken();

        Assert.True(firstCancellationToken.IsCancellationRequested);
        Assert.False(secondCancellationToken.IsCancellationRequested);

        // Does the IKey have the properties we requested?
        Assert.Equal(keyId, newKey.KeyId);
        Assert.Equal(creationDate, newKey.CreationDate);
        Assert.Equal(activationDate, newKey.ActivationDate);
        Assert.Equal(expirationDate, newKey.ExpirationDate);
        Assert.Same(expectedDescriptor, newKey.Descriptor);
        Assert.False(newKey.IsRevoked);
        Assert.Same(expectedAuthenticatedEncryptor, testEncryptorFactory.CreateEncryptorInstance(newKey));

        // Finally, was the correct element stored in the repository?
        string expectedXml = string.Format(
            CultureInfo.InvariantCulture,
            @"
                <key id='3d6d01fd-c0e7-44ae-82dd-013b996b4093' version='1' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
                  {1}
                  {2}
                  {3}
                  <descriptor deserializerType='{0}'>
                    <theElement>
                      <secret enc:requiresEncryption='true'>
                        <![CDATA[This is a secret value.]]>
                      </secret>
                    </theElement>
                  </descriptor>
                </key>",
            typeof(MyDeserializer).AssemblyQualifiedName,
            new XElement("creationDate", creationDate),
            new XElement("activationDate", activationDate),
            new XElement("expirationDate", expirationDate));

        XmlAssert.Equal(expectedXml, elementStoredInRepository);
        Assert.Equal("key-3d6d01fd-c0e7-44ae-82dd-013b996b4093", friendlyNameStoredInRepository);
    }