public async Task EncryptionUTRewrapDekWithoutEncryptionSerializer() { string dekId = "mydek"; EncryptionTestHandler testHandler = new EncryptionTestHandler(); // Create a DEK using a properly setup client first Container container = this.GetContainerWithMockSetup(testHandler); DatabaseCore databaseWithSerializer = (DatabaseCore)((ContainerCore)(ContainerInlineCore)container).Database; DataEncryptionKeyResponse dekResponse = await databaseWithSerializer.CreateDataEncryptionKeyAsync(dekId, EncryptionUnitTests.Algo, this.metadata1); Assert.AreEqual(HttpStatusCode.Created, dekResponse.StatusCode); // Clear the handler pipeline that would have got setup testHandler.InnerHandler = null; // Ensure rewrap for this key fails on improperly configured client try { DatabaseCore database = (DatabaseCore)((ContainerCore)(ContainerInlineCore)this.GetContainer(testHandler)).Database; DataEncryptionKey dek = database.GetDataEncryptionKey(dekId); await dek.RewrapAsync(this.metadata2); Assert.Fail(); } catch (ArgumentException ex) { Assert.AreEqual(ClientResources.EncryptionKeyWrapProviderNotConfigured, ex.Message); } }
private Container GetContainer(EncryptionTestHandler encryptionTestHandler = null) { this.testHandler = encryptionTestHandler ?? new EncryptionTestHandler(); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient((builder) => builder.AddCustomHandlers(this.testHandler)); DatabaseCore database = new DatabaseCore(client.ClientContext, EncryptionUnitTests.DatabaseId); return(new ContainerInlineCore(new ContainerCore(client.ClientContext, database, EncryptionUnitTests.ContainerId))); }
private Container GetContainerWithMockSetup(EncryptionTestHandler encryptionTestHandler = null) { this.testHandler = encryptionTestHandler ?? new EncryptionTestHandler(); this.mockKeyWrapProvider = new Mock <EncryptionKeyWrapProvider>(); this.mockKeyWrapProvider.Setup(m => m.WrapKeyAsync(It.IsAny <byte[]>(), It.IsAny <EncryptionKeyWrapMetadata>(), It.IsAny <CancellationToken>())) .ReturnsAsync((byte[] key, EncryptionKeyWrapMetadata metadata, CancellationToken cancellationToken) => { EncryptionKeyWrapMetadata responseMetadata = new EncryptionKeyWrapMetadata(metadata.Value + this.metadataUpdateSuffix); int moveBy = metadata.Value == this.metadata1.Value ? 1 : 2; return(new EncryptionKeyWrapResult(key.Select(b => (byte)(b + moveBy)).ToArray(), responseMetadata)); }); this.mockKeyWrapProvider.Setup(m => m.UnwrapKeyAsync(It.IsAny <byte[]>(), It.IsAny <EncryptionKeyWrapMetadata>(), It.IsAny <CancellationToken>())) .ReturnsAsync((byte[] wrappedKey, EncryptionKeyWrapMetadata metadata, CancellationToken cancellationToken) => { int moveBy = metadata.Value == this.metadata1.Value + this.metadataUpdateSuffix ? 1 : 2; return(new EncryptionKeyUnwrapResult(wrappedKey.Select(b => (byte)(b - moveBy)).ToArray(), this.cacheTTL)); }); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient((builder) => builder .AddCustomHandlers(this.testHandler) .WithEncryptionKeyWrapProvider(this.mockKeyWrapProvider.Object)); this.mockEncryptionAlgorithm = new Mock <EncryptionAlgorithm>(); this.mockEncryptionAlgorithm.Setup(m => m.EncryptData(It.IsAny <byte[]>())) .Returns((byte[] plainText) => plainText.Reverse().ToArray()); this.mockEncryptionAlgorithm.Setup(m => m.DecryptData(It.IsAny <byte[]>())) .Returns((byte[] cipherText) => cipherText.Reverse().ToArray()); this.mockEncryptionAlgorithm.SetupGet(m => m.AlgorithmName).Returns(AeadAes256CbcHmac256Algorithm.AlgorithmNameConstant); this.mockDatabaseCore = new Mock <DatabaseCore>(client.ClientContext, EncryptionUnitTests.DatabaseId); this.mockDatabaseCore.CallBase = true; this.mockDatabaseCore.Setup(m => m.GetDataEncryptionKey(It.IsAny <string>())) .Returns((string id) => { Mock <DataEncryptionKeyCore> mockDekCore = new Mock <DataEncryptionKeyCore>(client.ClientContext, this.mockDatabaseCore.Object, id); mockDekCore.CallBase = true; mockDekCore.Setup(m => m.GenerateKey(EncryptionUnitTests.Algo)).Returns(this.dek); mockDekCore.Setup(m => m.GetEncryptionAlgorithm(It.IsAny <byte[]>(), EncryptionUnitTests.Algo)) .Returns(this.mockEncryptionAlgorithm.Object); return(new DataEncryptionKeyInlineCore(mockDekCore.Object)); }); return(new ContainerInlineCore(new ContainerCore(client.ClientContext, this.mockDatabaseCore.Object, EncryptionUnitTests.ContainerId))); }
private Container GetContainerWithMockSetup(EncryptionTestHandler encryptionTestHandler = null) { this.testHandler = encryptionTestHandler ?? new EncryptionTestHandler(); this.mockEncryptor = new Mock <Encryptor>(); this.mockEncryptor.Setup(m => m.EncryptAsync(It.IsAny <byte[]>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync((byte[] plainText, string dekId, string algo, CancellationToken t) => EncryptionUnitTests.EncryptData(plainText)); this.mockEncryptor.Setup(m => m.DecryptAsync(It.IsAny <byte[]>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync((byte[] cipherText, string dekId, string algo, CancellationToken t) => EncryptionUnitTests.DecryptData(cipherText)); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient((builder) => builder .AddCustomHandlers(this.testHandler) .WithEncryptor(this.mockEncryptor.Object)); DatabaseCore database = new DatabaseCore(client.ClientContext, EncryptionUnitTests.DatabaseId); return(new ContainerInlineCore(new ContainerCore(client.ClientContext, database, EncryptionUnitTests.ContainerId))); }
public override async Task <ResponseMessage> SendAsync( RequestMessage request, CancellationToken cancellationToken) { // We clone the request message as the Content is disposed before we can use it in the test assertions later. this.Received.Add(EncryptionTestHandler.CloneRequestMessage(request)); if (this.func != null) { return(await this.func(request)); } HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError; if (request.ResourceType == ResourceType.Document) { JObject item = null; if (request.OperationType == OperationType.Create) { item = EncryptionUnitTests.ParseStream(request.Content); string itemId = item.Property("id").Value.Value <string>(); httpStatusCode = HttpStatusCode.Created; if (!this.Items.TryAdd(itemId, item)) { httpStatusCode = HttpStatusCode.Conflict; } } else if (request.OperationType == OperationType.Read) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); httpStatusCode = HttpStatusCode.OK; if (!this.Items.TryGetValue(itemId, out item)) { httpStatusCode = HttpStatusCode.NotFound; } } else if (request.OperationType == OperationType.Replace) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); item = EncryptionUnitTests.ParseStream(request.Content); httpStatusCode = HttpStatusCode.OK; if (!this.Items.TryGetValue(itemId, out JObject existingItem)) { httpStatusCode = HttpStatusCode.NotFound; } if (!this.Items.TryUpdate(itemId, item, existingItem)) { throw new InvalidOperationException("Concurrency not handled in tests."); } } else if (request.OperationType == OperationType.Delete) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); httpStatusCode = HttpStatusCode.NoContent; if (!this.Items.TryRemove(itemId, out _)) { httpStatusCode = HttpStatusCode.NotFound; } } ResponseMessage responseMessage = new ResponseMessage(httpStatusCode, request) { Content = item != null?this.serializer.ToStream(item) : null, }; responseMessage.Headers.RequestCharge = EncryptionUnitTests.requestCharge; return(responseMessage); } return(new ResponseMessage(httpStatusCode, request)); }
public override async Task <ResponseMessage> SendAsync( RequestMessage request, CancellationToken cancellationToken) { // We clone the request message as the Content is disposed before we can use it in the test assertions later. this.Received.Add(EncryptionTestHandler.CloneRequestMessage(request)); if (this.func != null) { return(await this.func(request)); } HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError; if (request.ResourceType == ResourceType.ClientEncryptionKey) { DataEncryptionKeyProperties dekProperties = null; if (request.OperationType == OperationType.Create) { dekProperties = this.serializer.FromStream <DataEncryptionKeyProperties>(request.Content); string databaseRid = ResourceId.NewDatabaseId(1).ToString(); dekProperties.ResourceId = ResourceId.NewClientEncryptionKeyId(databaseRid, (uint)this.Received.Count).ToString(); dekProperties.CreatedTime = EncryptionTestHandler.ReducePrecisionToSeconds(DateTime.UtcNow); dekProperties.LastModified = dekProperties.CreatedTime; dekProperties.ETag = Guid.NewGuid().ToString(); dekProperties.SelfLink = string.Format( "dbs/{0}/{1}/{2}/", databaseRid, Paths.ClientEncryptionKeysPathSegment, dekProperties.ResourceId); httpStatusCode = HttpStatusCode.Created; if (!this.Deks.TryAdd(dekProperties.Id, dekProperties)) { httpStatusCode = HttpStatusCode.Conflict; } } else if (request.OperationType == OperationType.Read) { string dekId = EncryptionTestHandler.ParseDekUri(request.RequestUri); httpStatusCode = HttpStatusCode.OK; if (!this.Deks.TryGetValue(dekId, out dekProperties)) { httpStatusCode = HttpStatusCode.NotFound; } } else if (request.OperationType == OperationType.Replace) { string dekId = EncryptionTestHandler.ParseDekUri(request.RequestUri); dekProperties = this.serializer.FromStream <DataEncryptionKeyProperties>(request.Content); dekProperties.LastModified = EncryptionTestHandler.ReducePrecisionToSeconds(DateTime.UtcNow); dekProperties.ETag = Guid.NewGuid().ToString(); httpStatusCode = HttpStatusCode.OK; if (!this.Deks.TryGetValue(dekId, out DataEncryptionKeyProperties existingDekProperties)) { httpStatusCode = HttpStatusCode.NotFound; } if (!this.Deks.TryUpdate(dekId, dekProperties, existingDekProperties)) { throw new InvalidOperationException("Concurrency not handled in tests."); } } else if (request.OperationType == OperationType.Delete) { string dekId = EncryptionTestHandler.ParseDekUri(request.RequestUri); httpStatusCode = HttpStatusCode.NoContent; if (!this.Deks.TryRemove(dekId, out _)) { httpStatusCode = HttpStatusCode.NotFound; } } ResponseMessage responseMessage = new ResponseMessage(httpStatusCode, request) { Content = dekProperties != null?this.serializer.ToStream(dekProperties) : null, }; responseMessage.Headers.RequestCharge = EncryptionUnitTests.requestCharge; responseMessage.Headers.ETag = dekProperties?.ETag; return(responseMessage); } else if (request.ResourceType == ResourceType.Document) { JObject item = null; if (request.OperationType == OperationType.Create) { item = EncryptionUnitTests.ParseStream(request.Content); string itemId = item.Property("id").Value.Value <string>(); httpStatusCode = HttpStatusCode.Created; if (!this.Items.TryAdd(itemId, item)) { httpStatusCode = HttpStatusCode.Conflict; } } else if (request.OperationType == OperationType.Read) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); httpStatusCode = HttpStatusCode.OK; if (!this.Items.TryGetValue(itemId, out item)) { httpStatusCode = HttpStatusCode.NotFound; } } else if (request.OperationType == OperationType.Replace) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); item = EncryptionUnitTests.ParseStream(request.Content); httpStatusCode = HttpStatusCode.OK; if (!this.Items.TryGetValue(itemId, out JObject existingItem)) { httpStatusCode = HttpStatusCode.NotFound; } if (!this.Items.TryUpdate(itemId, item, existingItem)) { throw new InvalidOperationException("Concurrency not handled in tests."); } } else if (request.OperationType == OperationType.Delete) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); httpStatusCode = HttpStatusCode.NoContent; if (!this.Items.TryRemove(itemId, out _)) { httpStatusCode = HttpStatusCode.NotFound; } } ResponseMessage responseMessage = new ResponseMessage(httpStatusCode, request) { Content = item != null?this.serializer.ToStream(item) : null, }; responseMessage.Headers.RequestCharge = EncryptionUnitTests.requestCharge; return(responseMessage); } return(new ResponseMessage(httpStatusCode, request)); }