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

            var kmsConfig = new KmsXmlEncryptorConfig(KmsIntegrationTests.KmsTestingKey);

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddDataProtection()
            .SetApplicationName(KmsIntegrationTests.ApplicationName)
            .PersistKeysToAwsS3(s3Client, s3Config)
            .ProtectKeysWithAwsKms(kmsClient, kmsConfig);
            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);
            }
        }
Example #2
0
        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);
            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);
        }
Example #3
0
        public async Task ExpectDefaultStoreRetrieveToSucceed()
        {
            config.KeyPrefix = "DefaultTesting/";
            await s3Cleanup.ClearKeys(BucketName, config.KeyPrefix);

            var myXml      = new XElement(ElementName, ElementContent);
            var myTestName = "friendly";

            await xmlRepo.StoreElementAsync(myXml, myTestName, CancellationToken.None);

            IReadOnlyCollection <XElement> list = await xmlRepo.GetAllElementsAsync(CancellationToken.None);

            Assert.Equal(1, list.Count);
            Assert.True(XNode.DeepEquals(myXml, list.First()));
        }
Example #4
0
        private async Task <bool> RunMigrationProcess()
        {
            await s3Cleanup.ClearKeys(S3IntegrationTests.BucketName, "Migration/V1/");

            // Since we can't load multiple versions of the same assembly in the same context, we need to run migration from outside as another process
            // Fairly horrible code...

            var migrationCreationPath = Path.Combine("..", "..", "..", "..", "..", "misc", "AspNetCore.DataProtection.Aws.CreateV1Data", "bin", BuildPath, "netcoreapp1.1", "AspNetCore.DataProtection.Aws.CreateV1Data.dll");

            // dotnet.exe will complain, but this gives a more informative error message
            var absPath = Path.GetFullPath(migrationCreationPath);

            if (!File.Exists(absPath))
            {
                throw new InvalidOperationException($"Process path requested does not exist: {absPath}");
            }

            var migrationArgs = $"\"{absPath}\"";

            var startInfo = new ProcessStartInfo("dotnet", migrationArgs)
            {
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                RedirectStandardInput  = true,
                UseShellExecute        = false
            };
            string output;

            using (var process = Process.Start(startInfo))
            {
                // As per Jon Skeet's suggestion, run the STDOUT and STDERR buffering on separate threads to allow the process to read and write throughout startup and shutdown
                var outputTask = Task.Run(process.StandardOutput.ReadToEndAsync);
                var errorTask  = Task.Run(process.StandardError.ReadToEndAsync);

                try
                {
                    // Send actual configs over, migration will convert JSON to meaningful V1 config
                    foreach (var config in Configurations.Values)
                    {
                        await SendConfig(process.StandardInput, config).ConfigureAwait(false);
                    }
                    await process.StandardInput.WriteLineAsync(EndInputValue).ConfigureAwait(false);

                    if (!process.WaitForExit((int)TimeSpan.FromSeconds(30).TotalMilliseconds))
                    {
                        process.Close();
                    }

                    if (!process.WaitForExit((int)TimeSpan.FromSeconds(3).TotalMilliseconds))
                    {
                        process.Kill();
                    }
                }
                catch (Exception) when(KillProcess(process))
                {
                }

                process.WaitForExit();

                output = await outputTask.ConfigureAwait(false);

                var error = await errorTask.ConfigureAwait(false);

                if (process.ExitCode != 0)
                {
                    throw new InvalidOperationException($"Migration process hasn't terminated cleanly, code: {process.ExitCode}{Environment.NewLine}Output:{Environment.NewLine}{output}{Environment.NewLine}Error:{Environment.NewLine}{error}");
                }
            }

            using (var reader = new StringReader(output))
            {
                foreach (var config in Configurations.Values)
                {
                    config[EncryptedData] = await reader.ReadLineAsync().ConfigureAwait(false);
                }
            }

            return(true);
        }