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 ExpectProtectRoundTripToSucceed() { var s3Config = new S3XmlRepositoryConfig(S3IntegrationTests.BucketName) { KeyPrefix = "CombinedXmlKeyManager3/" }; await s3Cleanup.ClearKeys(S3IntegrationTests.BucketName, s3Config.KeyPrefix); var kmsConfig = new KmsXmlEncryptorConfig(KmsIntegrationTests.KmsTestingKey); var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(s3Client); serviceCollection.AddSingleton(kmsClient); serviceCollection.AddDataProtection() .SetApplicationName(KmsIntegrationTests.ApplicationName) .PersistKeysToAwsS3(s3Config) .ProtectKeysWithAwsKms(kmsConfig); using (var serviceProvider = serviceCollection.BuildServiceProvider()) { var prov = serviceProvider.GetRequiredService <IDataProtectionProvider>().CreateProtector("bob"); var plaintext = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var encrypted = prov.Protect(plaintext); var decrypted = prov.Unprotect(encrypted); Assert.Equal(plaintext, decrypted); } }
public void ExpectSuccessfulCopy() { config.Bucket = "somebucket"; config.KeyPrefix = "keypref"; config.MaxS3QueryConcurrency = 4; config.StorageClass = S3StorageClass.Glacier; config.ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS; config.ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256; config.ServerSideEncryptionCustomerProvidedKey = "key"; config.ServerSideEncryptionCustomerProvidedKeyMd5 = "md5"; config.ServerSideEncryptionKeyManagementServiceKeyId = "keyid"; config.ClientSideCompression = !config.ClientSideCompression; config.ValidateETag = !config.ValidateETag; config.ValidateMd5Metadata = !config.ValidateMd5Metadata; var copy = new S3XmlRepositoryConfig(); copy.CopyFrom(config); Assert.Equal(config.Bucket, copy.Bucket); Assert.Equal(config.KeyPrefix, copy.KeyPrefix); Assert.Equal(config.MaxS3QueryConcurrency, copy.MaxS3QueryConcurrency); Assert.Equal(config.StorageClass, copy.StorageClass); Assert.Equal(config.ServerSideEncryptionMethod, copy.ServerSideEncryptionMethod); Assert.Equal(config.ServerSideEncryptionCustomerMethod, copy.ServerSideEncryptionCustomerMethod); Assert.Equal(config.ServerSideEncryptionCustomerProvidedKey, copy.ServerSideEncryptionCustomerProvidedKey); Assert.Equal(config.ServerSideEncryptionCustomerProvidedKeyMd5, copy.ServerSideEncryptionCustomerProvidedKeyMd5); Assert.Equal(config.ServerSideEncryptionKeyManagementServiceKeyId, copy.ServerSideEncryptionKeyManagementServiceKeyId); Assert.Equal(config.ClientSideCompression, copy.ClientSideCompression); Assert.Equal(config.ValidateETag, copy.ValidateETag); Assert.Equal(config.ValidateMd5Metadata, copy.ValidateMd5Metadata); }
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); }
public void ExpectBuilderAdditionsConfig(bool withClient) { var services = new List <ServiceDescriptor>(); builder.Setup(x => x.Services).Returns(svcCollection.Object); svcCollection.Setup(x => x.GetEnumerator()).Returns(() => services.GetEnumerator()); svcCollection.Setup(x => x.Add(It.IsAny <ServiceDescriptor>())) .Callback <ServiceDescriptor>(sd => { services.Add(sd); }); // An empty collection seems to be enough to run what is eventually ConfigurationBinder.Bind, since there is no way to mock the options configure call // ReSharper disable once CollectionNeverUpdated.Local var configChildren = new List <IConfigurationSection>(); Mock <IConfiguration> configMock = repository.Create <IConfiguration>(); configMock.Setup(x => x.GetChildren()).Returns(configChildren); // Repeat call to ensure cumulative calls work if (withClient) { builder.Object.PersistKeysToAwsS3(client.Object, configMock.Object); builder.Object.PersistKeysToAwsS3(client.Object, configMock.Object); } else { builder.Object.PersistKeysToAwsS3(configMock.Object); builder.Object.PersistKeysToAwsS3(configMock.Object); provider.Setup(x => x.GetService(typeof(IAmazonS3))).Returns(client.Object); } Assert.Equal(1, services.Count(x => x.ServiceType == typeof(IMockingWrapper))); // IConfigureOptions is designed & expected to be present multiple times, so expect two after two calls Assert.Equal(2, services.Count(x => x.ServiceType == typeof(IConfigureOptions <KeyManagementOptions>))); Assert.Equal(2, services.Count(x => x.ServiceType == typeof(IConfigureOptions <S3XmlRepositoryConfig>))); Assert.Equal(ServiceLifetime.Singleton, services.Single(x => x.ServiceType == typeof(IMockingWrapper)).Lifetime); Assert.Equal(ServiceLifetime.Singleton, services.First(x => x.ServiceType == typeof(IConfigureOptions <KeyManagementOptions>)).Lifetime); Assert.Equal(ServiceLifetime.Singleton, services.First(x => x.ServiceType == typeof(IConfigureOptions <S3XmlRepositoryConfig>)).Lifetime); // Ensure we run equivalent config for the actual configuration object var configureObject = services.First(x => x.ServiceType == typeof(IConfigureOptions <S3XmlRepositoryConfig>)).ImplementationInstance; var optionsObject = new S3XmlRepositoryConfig(); ((IConfigureOptions <S3XmlRepositoryConfig>)configureObject).Configure(optionsObject); provider.Setup(x => x.GetService(typeof(ILoggerFactory))).Returns(loggerFactory.Object); provider.Setup(x => x.GetService(typeof(IOptions <S3XmlRepositoryConfig>))).Returns(snapshot.Object); loggerFactory.Setup(x => x.CreateLogger(typeof(S3XmlRepository).FullName)).Returns(repository.Create <ILogger <S3XmlRepository> >().Object); snapshot.Setup(x => x.Value).Returns(optionsObject); var configure = services.First(x => x.ServiceType == typeof(IConfigureOptions <KeyManagementOptions>)).ImplementationFactory(provider.Object); var options = new KeyManagementOptions(); ((IConfigureOptions <KeyManagementOptions>)configure).Configure(options); Assert.IsType <S3XmlRepository>(options.XmlRepository); }
public S3IntegrationTests() { // Expectation that local SDK has been configured correctly, whether via VS Tools or user config files s3Client = new AmazonS3Client(RegionEndpoint.EUWest1); // Override the default for ease of debugging. Explicitly turn on for compression tests. config = new S3XmlRepositoryConfig(BucketName) { ClientSideCompression = false }; xmlRepo = new S3XmlRepository(s3Client, new DirectOptions <S3XmlRepositoryConfig>(config)); s3Cleanup = new CleanupS3(s3Client); }
public async Task ExpectApplicationIsolationToThrow(string app1, string app2, bool throws) { var s3Config = new S3XmlRepositoryConfig(S3IntegrationTests.BucketName) { KeyPrefix = "CombinedXmlKeyManager4/" }; await s3Cleanup.ClearKeys(S3IntegrationTests.BucketName, s3Config.KeyPrefix); var kmsConfig = new KmsXmlEncryptorConfig(KmsIntegrationTests.KmsTestingKey); var plaintext = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] encrypted; { var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(s3Client); serviceCollection.AddSingleton(kmsClient); serviceCollection.AddDataProtection() .SetApplicationName(app1) .PersistKeysToAwsS3(s3Config) .ProtectKeysWithAwsKms(kmsConfig); using (var serviceProvider = serviceCollection.BuildServiceProvider()) { var prov = serviceProvider.GetRequiredService <IDataProtectionProvider>().CreateProtector("bob"); encrypted = prov.Protect(plaintext); } } { var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(s3Client); serviceCollection.AddSingleton(kmsClient); serviceCollection.AddDataProtection() .SetApplicationName(app2) .PersistKeysToAwsS3(s3Config) .ProtectKeysWithAwsKms(kmsConfig); using (var serviceProvider = serviceCollection.BuildServiceProvider()) { var prov = serviceProvider.GetRequiredService <IDataProtectionProvider>().CreateProtector("bob"); if (throws) { Assert.Throws <CryptographicException>(() => prov.Unprotect(encrypted)); } else { Assert.NotNull(prov.Unprotect(encrypted)); } } } }
private static S3XmlRepositoryConfig ToNewS3Config(JObject config) { var newConfig = new S3XmlRepositoryConfig(config[nameof(S3XmlRepositoryConfig.Bucket)].Value <string>()); if (config.TryGetValue(nameof(S3XmlRepositoryConfig.KeyPrefix), out JToken keyprefix)) { newConfig.KeyPrefix = keyprefix.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.MaxS3QueryConcurrency), out JToken concurrency)) { newConfig.MaxS3QueryConcurrency = concurrency.Value <int>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.StorageClass), out JToken storageClass)) { newConfig.StorageClass = S3StorageClass.FindValue(storageClass.Value <string>()); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionMethod), out JToken serverSideEncryptionMethod)) { newConfig.ServerSideEncryptionMethod = ServerSideEncryptionMethod.FindValue(serverSideEncryptionMethod.Value <string>()); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionCustomerMethod), out JToken serverSideEncryptionCustomerMethod)) { newConfig.ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.FindValue(serverSideEncryptionCustomerMethod.Value <string>()); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionCustomerProvidedKey), out JToken serverSideEncryptionCustomerProvidedKey)) { newConfig.ServerSideEncryptionCustomerProvidedKey = serverSideEncryptionCustomerProvidedKey.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionCustomerProvidedKeyMd5), out JToken serverSideEncryptionCustomerProvidedKeyMd5)) { newConfig.ServerSideEncryptionCustomerProvidedKeyMd5 = serverSideEncryptionCustomerProvidedKeyMd5.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionKeyManagementServiceKeyId), out JToken serverSideEncryptionKeyManagementServiceKeyId)) { newConfig.ServerSideEncryptionKeyManagementServiceKeyId = serverSideEncryptionKeyManagementServiceKeyId.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ClientSideCompression), out JToken clientSideCompression)) { newConfig.ClientSideCompression = clientSideCompression.Value <bool>(); } return(newConfig); }
public byte[] CreateS3(byte[] toEncrypt, string protector, S3XmlRepositoryConfig config) { var serviceCollection = new ServiceCollection(); serviceCollection.AddDataProtection() .PersistKeysToAwsS3(s3Client, config); var serviceProvider = serviceCollection.BuildServiceProvider(); using (serviceProvider as IDisposable) { var prov = serviceProvider.GetRequiredService <IDataProtectionProvider>().CreateProtector(protector); return(prov.Protect(toEncrypt)); } }
public void ExpectBuilderAdditions(bool withClient) { var services = new List <ServiceDescriptor>(); builder.Setup(x => x.Services).Returns(svcCollection.Object); svcCollection.Setup(x => x.Count).Returns(() => services.Count); svcCollection.Setup(x => x.Add(It.IsAny <ServiceDescriptor>())).Callback <ServiceDescriptor>(sd => services.Add(sd)); svcCollection.Setup(x => x[It.IsAny <int>()]).Returns <int>(index => services[index]); svcCollection.Setup(x => x.RemoveAt(It.IsAny <int>())).Callback <int>(index => services.RemoveAt(index)); var config = new S3XmlRepositoryConfig("bucket"); // Repeat call to ensure cumulative calls work if (withClient) { builder.Object.PersistKeysToAwsS3(client.Object, config); builder.Object.PersistKeysToAwsS3(client.Object, config); } else { builder.Object.PersistKeysToAwsS3(config); builder.Object.PersistKeysToAwsS3(config); provider.Setup(x => x.GetService(typeof(IAmazonS3))).Returns(client.Object); } Assert.Equal(1, services.Count(x => x.ServiceType == typeof(IMockingWrapper))); Assert.Equal(1, services.Count(x => x.ServiceType == typeof(IXmlRepository))); Assert.Equal(ServiceLifetime.Singleton, services.Single(x => x.ServiceType == typeof(IMockingWrapper)).Lifetime); Assert.Equal(ServiceLifetime.Singleton, services.Single(x => x.ServiceType == typeof(IXmlRepository)).Lifetime); provider.Setup(x => x.GetService(typeof(ILoggerFactory))).Returns(loggerFactory.Object); loggerFactory.Setup(x => x.CreateLogger(typeof(S3XmlRepository).FullName)).Returns(repository.Create <ILogger <S3XmlRepository> >().Object); Assert.IsType <S3XmlRepository>(services.Single(x => x.ServiceType == typeof(IXmlRepository)).ImplementationFactory(provider.Object)); }
#pragma warning disable S3242 // JObject is more descriptive than 'more general' IDictionary private static (string ControlValue, byte[] ToEncrypt, string Protector, string ApplicationName, S3XmlRepositoryConfig S3Config, KmsXmlEncryptorConfig KmsConfig) ToOldConfig(JObject config) #pragma warning restore S3242 { var controlValue = config[ConfigType].Value <string>(); var protectData = Convert.FromBase64String(config[DataToProtect].Value <string>()); var protectorValue = config[ProtectorKey].Value <string>(); var old = new S3XmlRepositoryConfig(config[nameof(S3XmlRepositoryConfig.Bucket)].Value <string>()); if (config.TryGetValue(nameof(S3XmlRepositoryConfig.KeyPrefix), out JToken keyprefix)) { old.KeyPrefix = keyprefix.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.MaxS3QueryConcurrency), out JToken concurrency)) { old.MaxS3QueryConcurrency = concurrency.Value <int>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.StorageClass), out JToken storageClass)) { old.StorageClass = S3StorageClass.FindValue(storageClass.Value <string>()); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionMethod), out JToken serverSideEncryptionMethod)) { old.ServerSideEncryptionMethod = ServerSideEncryptionMethod.FindValue(serverSideEncryptionMethod.Value <string>()); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionCustomerMethod), out JToken serverSideEncryptionCustomerMethod)) { old.ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.FindValue(serverSideEncryptionCustomerMethod.Value <string>()); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionCustomerProvidedKey), out JToken serverSideEncryptionCustomerProvidedKey)) { old.ServerSideEncryptionCustomerProvidedKey = serverSideEncryptionCustomerProvidedKey.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionCustomerProvidedKeyMd5), out JToken serverSideEncryptionCustomerProvidedKeyMd5)) { old.ServerSideEncryptionCustomerProvidedKeyMd5 = serverSideEncryptionCustomerProvidedKeyMd5.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ServerSideEncryptionKeyManagementServiceKeyId), out JToken serverSideEncryptionKeyManagementServiceKeyId)) { old.ServerSideEncryptionKeyManagementServiceKeyId = serverSideEncryptionKeyManagementServiceKeyId.Value <string>(); } if (config.TryGetValue(nameof(S3XmlRepositoryConfig.ClientSideCompression), out JToken clientSideCompression)) { old.ClientSideCompression = clientSideCompression.Value <bool>(); } string applicationName = null; if (config.TryGetValue(ApplicationNameKey, out JToken appName)) { applicationName = appName.Value <string>(); } string kmsApplicationName = null; if (config.TryGetValue(KmsApplicationNameKey, out JToken kmsAppName)) { kmsApplicationName = kmsAppName.Value <string>(); } string keyIdentifier = null; if (config.TryGetValue(nameof(KmsXmlEncryptorConfig.KeyId), out JToken keyId)) { keyIdentifier = keyId.Value <string>(); } KmsXmlEncryptorConfig kmsConfig = null; if (!string.IsNullOrEmpty(kmsApplicationName) && !string.IsNullOrEmpty(keyIdentifier)) { kmsConfig = new KmsXmlEncryptorConfig(kmsApplicationName, keyIdentifier); } return(controlValue, protectData, protectorValue, applicationName, old, kmsConfig); }
public byte[] CreateS3AndKms(byte[] toEncrypt, string protector, string applicationName, S3XmlRepositoryConfig s3Config, KmsXmlEncryptorConfig kmsConfig) { var serviceCollection = new ServiceCollection(); serviceCollection.AddDataProtection() .SetApplicationName(applicationName) .ProtectKeysWithAwsKms(kmsClient, kmsConfig) .PersistKeysToAwsS3(s3Client, s3Config); var serviceProvider = serviceCollection.BuildServiceProvider(); using (serviceProvider as IDisposable) { var prov = serviceProvider.GetRequiredService <IDataProtectionProvider>().CreateProtector(protector); return(prov.Protect(toEncrypt)); } }
public S3XmlRepositoryConfigTests() { config = new S3XmlRepositoryConfig("somebucket"); }