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); } }
/// <inheritdoc/> public override async Task <DataEncryptionKeyResponse> ReadAsync( RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { DataEncryptionKeyResponse response = await this.ReadInternalAsync(requestOptions, diagnosticsContext : null, cancellationToken : cancellationToken); this.ClientContext.DekCache.Set(this.Database.Id, this.LinkUri, response.Resource); return(response); }
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); }
/// <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); }
public async Task EncryptionUTReadItem() { 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); MyItem item = await EncryptionUnitTests.CreateItemAsync(container, dekId, MyItem.PathsToEncrypt); ItemResponse <MyItem> readResponse = await container.ReadItemAsync <MyItem>(item.Id, new PartitionKey(item.PK)); Assert.AreEqual(item, readResponse.Resource); }
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(); }
private async Task <DataEncryptionKeyResponse> ReadInternalAsync( RequestOptions requestOptions, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { Task <ResponseMessage> responseMessage = this.ProcessStreamAsync( streamPayload: null, operationType: OperationType.Read, requestOptions: requestOptions, diagnosticsContext: diagnosticsContext, cancellationToken: cancellationToken); DataEncryptionKeyResponse response = await this.ClientContext.ResponseFactory.CreateDataEncryptionKeyResponseAsync(this, responseMessage); Debug.Assert(response.Resource != null); return(response); }
private async Task <DataEncryptionKeyProperties> ReadResourceByRidSelfLinkAsync( string ridSelfLink, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken = default(CancellationToken)) { Task <ResponseMessage> responseMessage = this.ClientContext.ProcessResourceOperationStreamAsync( resourceUri: new Uri(ridSelfLink, UriKind.Relative), resourceType: ResourceType.ClientEncryptionKey, operationType: OperationType.Read, cosmosContainerCore: null, partitionKey: null, streamPayload: null, requestOptions: null, requestEnricher: null, diagnosticsScope: diagnosticsContext, cancellationToken: cancellationToken); DataEncryptionKeyResponse response = await this.ClientContext.ResponseFactory.CreateDataEncryptionKeyResponseAsync(this, responseMessage); Debug.Assert(response.Resource != null); return(response); }
public async Task EncryptionUTCreateItem() { 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); MyItem item = await EncryptionUnitTests.CreateItemAsync(container, dekId, MyItem.PathsToEncrypt); // Validate server state Assert.IsTrue(this.testHandler.Items.TryGetValue(item.Id, out JObject serverItem)); Assert.IsNotNull(serverItem); Assert.AreEqual(item.Id, serverItem.Property(Constants.Properties.Id).Value.Value <string>()); Assert.AreEqual(item.PK, serverItem.Property(nameof(MyItem.PK)).Value.Value <string>()); Assert.IsNull(serverItem.Property(nameof(MyItem.EncStr1))); Assert.IsNull(serverItem.Property(nameof(MyItem.EncInt))); JProperty eiJProp = serverItem.Property(Constants.Properties.EncryptedInfo); Assert.IsNotNull(eiJProp); Assert.IsNotNull(eiJProp.Value); Assert.AreEqual(JTokenType.Object, eiJProp.Value.Type); EncryptionProperties encryptionPropertiesAtServer = ((JObject)eiJProp.Value).ToObject <EncryptionProperties>(); Assert.IsNotNull(encryptionPropertiesAtServer); Assert.AreEqual(dekResponse.Resource.ResourceId, encryptionPropertiesAtServer.DataEncryptionKeyRid); Assert.AreEqual(1, encryptionPropertiesAtServer.EncryptionFormatVersion); Assert.IsNotNull(encryptionPropertiesAtServer.EncryptedData); JObject decryptedJObj = EncryptionUnitTests.ParseStream(new MemoryStream(encryptionPropertiesAtServer.EncryptedData.Reverse().ToArray())); Assert.AreEqual(2, decryptedJObj.Properties().Count()); Assert.AreEqual(item.EncStr1, decryptedJObj.Property(nameof(MyItem.EncStr1)).Value.Value <string>()); Assert.AreEqual(item.EncInt, decryptedJObj.Property(nameof(MyItem.EncInt)).Value.Value <int>()); }
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)); }