Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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)));
        }
Exemplo n.º 3
0
        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));
            }
Exemplo n.º 6
0
            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));
            }