コード例 #1
0
        internal async Task <(byte[], EncryptionKeyWrapMetadata, InMemoryRawDek)> WrapAsync(
            byte[] key,
            CosmosEncryptionAlgorithm encryptionAlgorithmId,
            EncryptionKeyWrapMetadata metadata,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            EncryptionKeyWrapProvider encryptionKeyWrapProvider = this.ClientContext.ClientOptions.EncryptionKeyWrapProvider;

            if (encryptionKeyWrapProvider == null)
            {
                throw new ArgumentException(ClientResources.EncryptionKeyWrapProviderNotConfigured);
            }

            EncryptionKeyWrapResult keyWrapResponse;

            using (diagnosticsContext.CreateScope("WrapDataEncryptionKey"))
            {
                keyWrapResponse = await encryptionKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken);
            }

            // Verify
            DataEncryptionKeyProperties tempDekProperties = new DataEncryptionKeyProperties(this.Id, encryptionAlgorithmId, keyWrapResponse.WrappedDataEncryptionKey, keyWrapResponse.EncryptionKeyWrapMetadata);
            InMemoryRawDek roundTripResponse = await this.UnwrapAsync(tempDekProperties, diagnosticsContext, cancellationToken);

            if (!roundTripResponse.RawDek.SequenceEqual(key))
            {
                throw CosmosExceptionFactory.CreateBadRequestException(ClientResources.KeyWrappingDidNotRoundtrip,
                                                                       diagnosticsContext: diagnosticsContext);
            }

            return(keyWrapResponse.WrappedDataEncryptionKey, keyWrapResponse.EncryptionKeyWrapMetadata, roundTripResponse);
        }
コード例 #2
0
        internal async Task <InMemoryRawDek> UnwrapAsync(
            DataEncryptionKeyProperties dekProperties,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            EncryptionKeyWrapProvider encryptionKeyWrapProvider = this.ClientContext.ClientOptions.EncryptionKeyWrapProvider;

            if (encryptionKeyWrapProvider == null)
            {
                throw new ArgumentException(ClientResources.EncryptionKeyWrapProviderNotConfigured);
            }

            EncryptionKeyUnwrapResult unwrapResult = null;

            using (diagnosticsContext.CreateScope("UnwrapDataEncryptionKey"))
            {
                unwrapResult = await encryptionKeyWrapProvider.UnwrapKeyAsync(
                    dekProperties.WrappedDataEncryptionKey,
                    dekProperties.EncryptionKeyWrapMetadata,
                    cancellationToken);
            }

            EncryptionAlgorithm encryptionAlgorithm = this.GetEncryptionAlgorithm(unwrapResult.DataEncryptionKey, dekProperties.EncryptionAlgorithmId);

            return(new InMemoryRawDek(unwrapResult.DataEncryptionKey, encryptionAlgorithm, unwrapResult.ClientCacheTimeToLive));
        }
コード例 #3
0
        internal async Task <(DataEncryptionKeyProperties, InMemoryRawDek)> FetchUnwrappedAsync(
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            DataEncryptionKeyProperties dekProperties = null;

            try
            {
                dekProperties = await this.ClientContext.DekCache.GetOrAddByNameLinkUriAsync(
                    this.LinkUri,
                    this.Database.Id,
                    this.ReadResourceAsync,
                    diagnosticsContext,
                    cancellationToken);
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          ClientResources.DataEncryptionKeyNotFound,
                          diagnosticsContext: diagnosticsContext,
                          innerException: ex);
            }

            InMemoryRawDek inMemoryRawDek = await this.ClientContext.DekCache.GetOrAddRawDekAsync(
                dekProperties,
                this.UnwrapAsync,
                diagnosticsContext,
                cancellationToken);

            return(dekProperties, inMemoryRawDek);
        }
コード例 #4
0
        public void Set(string databaseId, Uri dekNameLinkUri, DataEncryptionKeyProperties dekProperties)
        {
            CachedDekProperties cachedDekProperties = new CachedDekProperties(databaseId, dekProperties, DateTime.UtcNow + this.dekPropertiesTimeToLive);

            this.DekPropertiesByNameLinkUriCache.Set(dekNameLinkUri, cachedDekProperties);
            this.DekPropertiesByRidSelfLinkCache.Set(dekProperties.SelfLink, cachedDekProperties);
        }
コード例 #5
0
        private async Task <CachedDekProperties> FetchAsync(
            Func <CosmosDiagnosticsContext, CancellationToken, Task <DataEncryptionKeyProperties> > fetcher,
            string databaseId,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            DataEncryptionKeyProperties serverProperties = await fetcher(diagnosticsContext, cancellationToken);

            return(new CachedDekProperties(databaseId, serverProperties, DateTime.UtcNow + this.dekPropertiesTimeToLive));
        }
コード例 #6
0
        public CachedDekProperties(
            string databaseId,
            DataEncryptionKeyProperties serverProperties,
            DateTime serverPropertiesExpiryUtc)
        {
            Debug.Assert(databaseId != null);
            Debug.Assert(serverProperties != null);

            this.DatabaseId                = databaseId;
            this.ServerProperties          = serverProperties;
            this.ServerPropertiesExpiryUtc = serverPropertiesExpiryUtc;
        }
コード例 #7
0
        async Task <DataEncryptionKeyResponse> CreateDataEncryptionKeyAsync(
            string id,
            CosmosEncryptionAlgorithm encryptionAlgorithmId,
            EncryptionKeyWrapMetadata encryptionKeyWrapMetadata,
            RequestOptions requestOptions       = null,
            CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (encryptionAlgorithmId != CosmosEncryptionAlgorithm.AE_AES_256_CBC_HMAC_SHA_256_RANDOMIZED)
            {
                throw new ArgumentException(string.Format("Unsupported Encryption Algorithm {0}", encryptionAlgorithmId), nameof(encryptionAlgorithmId));
            }

            if (encryptionKeyWrapMetadata == null)
            {
                throw new ArgumentNullException(nameof(encryptionKeyWrapMetadata));
            }

            this.ClientContext.ValidateResource(id);

            DataEncryptionKeyCore newDek = (DataEncryptionKeyInlineCore)this.GetDataEncryptionKey(id);

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            byte[] rawDek = newDek.GenerateKey(encryptionAlgorithmId);

            (byte[] wrappedDek, EncryptionKeyWrapMetadata updatedMetadata, InMemoryRawDek inMemoryRawDek) = await newDek.WrapAsync(
                rawDek,
                encryptionAlgorithmId,
                encryptionKeyWrapMetadata,
                diagnosticsContext,
                cancellationToken);

            DataEncryptionKeyProperties dekProperties = new DataEncryptionKeyProperties(id, encryptionAlgorithmId, wrappedDek, updatedMetadata);
            Stream streamPayload = this.ClientContext.SerializerCore.ToStream(dekProperties);
            Task <ResponseMessage> responseMessage = this.CreateDataEncryptionKeyStreamAsync(
                streamPayload,
                requestOptions,
                cancellationToken);

            DataEncryptionKeyResponse dekResponse = await this.ClientContext.ResponseFactory.CreateDataEncryptionKeyResponseAsync(newDek, responseMessage);

            Debug.Assert(dekResponse.Resource != null);

            this.ClientContext.DekCache.Set(this.Id, newDek.LinkUri, dekResponse.Resource);
            this.ClientContext.DekCache.SetRawDek(dekResponse.Resource.SelfLink, inMemoryRawDek);
            return(dekResponse);
        }
コード例 #8
0
        /// <inheritdoc/>
        public override async Task <DataEncryptionKeyResponse> RewrapAsync(
            EncryptionKeyWrapMetadata newWrapMetadata,
            RequestOptions requestOptions       = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (newWrapMetadata == null)
            {
                throw new ArgumentNullException(nameof(newWrapMetadata));
            }

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            (DataEncryptionKeyProperties dekProperties, InMemoryRawDek inMemoryRawDek) = await this.FetchUnwrappedAsync(
                diagnosticsContext,
                cancellationToken);

            (byte[] wrappedDek, EncryptionKeyWrapMetadata updatedMetadata, InMemoryRawDek updatedRawDek) = await this.WrapAsync(
                inMemoryRawDek.RawDek,
                dekProperties.EncryptionAlgorithmId,
                newWrapMetadata,
                diagnosticsContext,
                cancellationToken);

            if (requestOptions == null)
            {
                requestOptions = new RequestOptions();
            }

            requestOptions.IfMatchEtag = dekProperties.ETag;

            DataEncryptionKeyProperties newDekProperties = new DataEncryptionKeyProperties(dekProperties);

            newDekProperties.WrappedDataEncryptionKey  = wrappedDek;
            newDekProperties.EncryptionKeyWrapMetadata = updatedMetadata;

            Task <ResponseMessage> responseMessage = this.ProcessStreamAsync(
                this.ClientContext.SerializerCore.ToStream(newDekProperties),
                OperationType.Replace,
                requestOptions,
                diagnosticsContext,
                cancellationToken);

            DataEncryptionKeyResponse response = await this.ClientContext.ResponseFactory.CreateDataEncryptionKeyResponseAsync(this, responseMessage);

            Debug.Assert(response.Resource != null);

            this.ClientContext.DekCache.Set(this.Database.Id, this.LinkUri, response.Resource);
            this.ClientContext.DekCache.SetRawDek(response.Resource.ResourceId, updatedRawDek);
            return(response);
        }
コード例 #9
0
 internal Task <DataEncryptionKeyResponse> CreateDataEncryptionKeyResponseAsync(
     DataEncryptionKey dataEncryptionKey,
     Task <ResponseMessage> cosmosResponseMessageTask)
 {
     return(this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) =>
     {
         DataEncryptionKeyProperties dekProperties = this.ToObjectInternal <DataEncryptionKeyProperties>(cosmosResponseMessage);
         return new DataEncryptionKeyResponse(
             cosmosResponseMessage.StatusCode,
             cosmosResponseMessage.Headers,
             dekProperties,
             dataEncryptionKey,
             cosmosResponseMessage.Diagnostics);
     }));
 }
コード例 #10
0
        public async Task EncryptionUTRewrapDek()
        {
            Container    container = this.GetContainerWithMockSetup();
            DatabaseCore database  = (DatabaseCore)((ContainerCore)(ContainerInlineCore)container).Database;

            string dekId = "mydek";
            DataEncryptionKeyResponse createResponse = await database.CreateDataEncryptionKeyAsync(dekId, EncryptionUnitTests.Algo, this.metadata1);

            DataEncryptionKeyProperties createdProperties = createResponse.Resource;

            Assert.AreEqual(HttpStatusCode.Created, createResponse.StatusCode);
            this.VerifyWrap(this.dek, this.metadata1);

            DataEncryptionKey         dek            = database.GetDataEncryptionKey(dekId);
            DataEncryptionKeyResponse rewrapResponse = await dek.RewrapAsync(this.metadata2);

            DataEncryptionKeyProperties rewrappedProperties = rewrapResponse.Resource;

            Assert.IsNotNull(rewrappedProperties);

            Assert.AreEqual(dekId, rewrappedProperties.Id);
            Assert.AreEqual(createdProperties.CreatedTime, rewrappedProperties.CreatedTime);
            Assert.IsNotNull(rewrappedProperties.LastModified);
            Assert.AreEqual(createdProperties.ResourceId, rewrappedProperties.ResourceId);
            Assert.AreEqual(createdProperties.SelfLink, rewrappedProperties.SelfLink);

            IEnumerable <byte> expectedRewrappedKey = this.dek.Select(b => (byte)(b + 2));

            Assert.IsTrue(expectedRewrappedKey.SequenceEqual(rewrappedProperties.WrappedDataEncryptionKey));

            Assert.AreEqual(new EncryptionKeyWrapMetadata(this.metadata2.Value + this.metadataUpdateSuffix), rewrappedProperties.EncryptionKeyWrapMetadata);

            Assert.AreEqual(2, this.testHandler.Received.Count);
            RequestMessage rewrapRequestMessage = this.testHandler.Received[1];

            Assert.AreEqual(ResourceType.ClientEncryptionKey, rewrapRequestMessage.ResourceType);
            Assert.AreEqual(OperationType.Replace, rewrapRequestMessage.OperationType);
            Assert.AreEqual(createResponse.ETag, rewrapRequestMessage.Headers[HttpConstants.HttpHeaders.IfMatch]);

            Assert.IsTrue(this.testHandler.Deks.ContainsKey(dekId));
            DataEncryptionKeyProperties serverDekProperties = this.testHandler.Deks[dekId];

            Assert.IsTrue(serverDekProperties.Equals(rewrappedProperties));

            this.VerifyWrap(this.dek, this.metadata2);
            this.mockKeyWrapProvider.VerifyNoOtherCalls();
        }
コード例 #11
0
        internal async Task <(DataEncryptionKeyProperties, InMemoryRawDek)> FetchUnwrappedByRidAsync(
            string rid,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            string dekRidSelfLink = PathsHelper.GeneratePath(ResourceType.ClientEncryptionKey, rid, isFeed: false);

            // Server self links end with / but client generate links don't - match them.
            if (!dekRidSelfLink.EndsWith("/"))
            {
                dekRidSelfLink += "/";
            }

            DataEncryptionKeyProperties dekProperties = null;

            try
            {
                dekProperties = await this.ClientContext.DekCache.GetOrAddByRidSelfLinkAsync(
                    dekRidSelfLink,
                    this.Database.Id,
                    this.ReadResourceByRidSelfLinkAsync,
                    this.LinkUri,
                    diagnosticsContext,
                    cancellationToken);
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          ClientResources.DataEncryptionKeyNotFound,
                          diagnosticsContext: diagnosticsContext,
                          innerException: ex);
            }

            InMemoryRawDek inMemoryRawDek = await this.ClientContext.DekCache.GetOrAddRawDekAsync(
                dekProperties,
                this.UnwrapAsync,
                diagnosticsContext,
                cancellationToken);

            return(dekProperties, inMemoryRawDek);
        }
コード例 #12
0
        public async Task <InMemoryRawDek> GetOrAddRawDekAsync(
            DataEncryptionKeyProperties dekProperties,
            Func <DataEncryptionKeyProperties, CosmosDiagnosticsContext, CancellationToken, Task <InMemoryRawDek> > unwrapper,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            InMemoryRawDek inMemoryRawDek = await this.RawDekByRidSelfLinkCache.GetAsync(
                dekProperties.SelfLink,
                null,
                () => unwrapper(dekProperties, diagnosticsContext, cancellationToken),
                cancellationToken);

            if (inMemoryRawDek.RawDekExpiry <= DateTime.UtcNow)
            {
                inMemoryRawDek = await this.RawDekByRidSelfLinkCache.GetAsync(
                    dekProperties.SelfLink,
                    null,
                    () => unwrapper(dekProperties, diagnosticsContext, cancellationToken),
                    cancellationToken,
                    forceRefresh : true);
            }

            return(inMemoryRawDek);
        }
コード例 #13
0
        public async Task EncryptionUTCreateDek()
        {
            Container    container = this.GetContainerWithMockSetup();
            DatabaseCore database  = (DatabaseCore)((ContainerCore)(ContainerInlineCore)container).Database;

            string dekId = "mydek";
            DataEncryptionKeyResponse dekResponse = await database.CreateDataEncryptionKeyAsync(dekId, EncryptionUnitTests.Algo, this.metadata1);

            Assert.AreEqual(HttpStatusCode.Created, dekResponse.StatusCode);
            Assert.AreEqual(requestCharge, dekResponse.RequestCharge);
            Assert.IsNotNull(dekResponse.ETag);

            DataEncryptionKeyProperties dekProperties = dekResponse.Resource;

            Assert.IsNotNull(dekProperties);
            Assert.AreEqual(dekResponse.ETag, dekProperties.ETag);
            Assert.AreEqual(dekId, dekProperties.Id);

            Assert.AreEqual(1, this.testHandler.Received.Count);
            RequestMessage createDekRequestMessage = this.testHandler.Received[0];

            Assert.AreEqual(ResourceType.ClientEncryptionKey, createDekRequestMessage.ResourceType);
            Assert.AreEqual(OperationType.Create, createDekRequestMessage.OperationType);

            Assert.IsTrue(this.testHandler.Deks.ContainsKey(dekId));
            DataEncryptionKeyProperties serverDekProperties = this.testHandler.Deks[dekId];

            Assert.IsTrue(serverDekProperties.Equals(dekProperties));

            // Make sure we didn't push anything else in the JSON (such as raw DEK) by comparing JSON properties
            // to properties exposed in DataEncryptionKeyProperties.
            createDekRequestMessage.Content.Position = 0; // it is a test assumption that the client uses MemoryStream
            JObject jObj = JObject.Parse(await new StreamReader(createDekRequestMessage.Content).ReadToEndAsync());
            IEnumerable <string> dekPropertiesPropertyNames = GetJsonPropertyNamesForType(typeof(DataEncryptionKeyProperties));

            foreach (JProperty property in jObj.Properties())
            {
                Assert.IsTrue(dekPropertiesPropertyNames.Contains(property.Name));
            }

            // Key wrap metadata should be the only "object" child in the JSON (given current properties in DataEncryptionKeyProperties)
            IEnumerable <JToken> objectChildren = jObj.PropertyValues().Where(v => v.Type == JTokenType.Object);

            Assert.AreEqual(1, objectChildren.Count());
            JObject keyWrapMetadataJObj = (JObject)objectChildren.First();

            Assert.AreEqual(Constants.Properties.KeyWrapMetadata, ((JProperty)keyWrapMetadataJObj.Parent).Name);

            IEnumerable <string> keyWrapMetadataPropertyNames = GetJsonPropertyNamesForType(typeof(EncryptionKeyWrapMetadata));

            foreach (JProperty property in keyWrapMetadataJObj.Properties())
            {
                Assert.IsTrue(keyWrapMetadataPropertyNames.Contains(property.Name));
            }

            IEnumerable <byte> expectedWrappedKey = this.VerifyWrap(this.dek, this.metadata1);

            this.mockKeyWrapProvider.VerifyNoOtherCalls();

            Assert.IsTrue(expectedWrappedKey.SequenceEqual(dekProperties.WrappedDataEncryptionKey));
        }
コード例 #14
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));
            }