public override async Task <ItemResponse <T> > CreateItemAsync <T>( T item, PartitionKey?partitionKey = null, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (partitionKey == null) { throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}."); } CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("CreateItem")) { ResponseMessage responseMessage; using (Stream itemStream = this.CosmosSerializer.ToStream <T>(item)) { responseMessage = await this.CreateItemHelperAsync( itemStream, partitionKey.Value, requestOptions, diagnosticsContext, cancellationToken); } return(this.ResponseFactory.CreateItemResponse <T>(responseMessage)); } }
public override async Task <ResponseMessage> ReplaceItemStreamAsync( Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { if (id == null) { throw new ArgumentNullException(nameof(id)); } if (streamPayload == null) { throw new ArgumentNullException(nameof(streamPayload)); } CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("ReplaceItemStream")) { return(await this.ReplaceItemHelperAsync( streamPayload, id, partitionKey, requestOptions, diagnosticsContext, cancellationToken)); } }
public override async Task <TransactionalBatchResponse> ExecuteAsync( CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(options: null); using (diagnosticsContext.CreateScope("TransactionalBatch.ExecuteAsync")) { TransactionalBatchResponse response = await this.transactionalBatch.ExecuteAsync(cancellationToken); if (response.IsSuccessStatusCode) { for (int index = 0; index < response.Count; index++) { TransactionalBatchOperationResult result = response[index]; if (result.ResourceStream != null) { result.ResourceStream = await EncryptionProcessor.DecryptAsync( result.ResourceStream, this.encryptor, diagnosticsContext, cancellationToken); } } } return(response); } }
public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default) { if (this.feedIterator == null) { if (this.queryDefinition != null) { this.feedIterator = await this.InitializeInternalFeedIteratorAsync(this.queryDefinition); } } CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(options: null); using (diagnosticsContext.CreateScope("FeedIterator.ReadNext")) { ResponseMessage responseMessage = await this.feedIterator.ReadNextAsync(cancellationToken); if (responseMessage.IsSuccessStatusCode && responseMessage.Content != null) { Stream decryptedContent = await this.DeserializeAndDecryptResponseAsync( responseMessage.Content, diagnosticsContext, cancellationToken); return(new DecryptedResponseMessage(responseMessage, decryptedContent)); } return(responseMessage); } }
public override TransactionalBatch CreateItemStream( Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { if (requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions && encryptionItemRequestOptions.EncryptionOptions != null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { streamPayload = EncryptionProcessor.EncryptAsync( streamPayload, this.encryptor, encryptionItemRequestOptions.EncryptionOptions, diagnosticsContext, cancellationToken: default).Result; } } this.transactionalBatch = this.transactionalBatch.CreateItemStream( streamPayload, requestOptions); return(this); }
internal async Task <(byte[], EncryptionKeyWrapMetadata, InMemoryRawDek)> WrapAsync( string id, byte[] key, string encryptionAlgorithm, EncryptionKeyWrapMetadata metadata, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { EncryptionKeyWrapResult keyWrapResponse; using (diagnosticsContext.CreateScope("WrapDataEncryptionKey")) { keyWrapResponse = await this.DekProvider.EncryptionKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken); } // Verify DataEncryptionKeyProperties tempDekProperties = new DataEncryptionKeyProperties(id, encryptionAlgorithm, keyWrapResponse.WrappedDataEncryptionKey, keyWrapResponse.EncryptionKeyWrapMetadata, DateTime.UtcNow); InMemoryRawDek roundTripResponse = await this.UnwrapAsync(tempDekProperties, diagnosticsContext, cancellationToken); if (!roundTripResponse.DataEncryptionKey.RawKey.SequenceEqual(key)) { throw new InvalidOperationException("The key wrapping provider configured was unable to unwrap the wrapped key correctly."); } return(keyWrapResponse.WrappedDataEncryptionKey, keyWrapResponse.EncryptionKeyWrapMetadata, roundTripResponse); }
public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder <T>( string processorName, ChangesHandler <T> onChangesDelegate) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(null); using (diagnosticsContext.CreateScope("GetChangeFeedProcessorBuilder")) { return(this.Container.GetChangeFeedProcessorBuilder( processorName, async(IReadOnlyCollection <JObject> documents, CancellationToken cancellationToken) => { List <T> decryptedItems = new List <T>(documents.Count); foreach (JObject document in documents) { JObject decryptedDocument = await this.EncryptionProcessor.DecryptAsync( document, diagnosticsContext, cancellationToken); decryptedItems.Add(decryptedDocument.ToObject <T>()); } // Call the original passed in delegate await onChangesDelegate(decryptedItems, cancellationToken); })); } }
public async override Task <ResponseMessage> ReadItemStreamAsync( string id, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("ReadItemStream")) { ResponseMessage responseMessage = await this.container.ReadItemStreamAsync( id, partitionKey, requestOptions, cancellationToken); Action <DecryptionResult> decryptionErroHandler = null; if (requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) { decryptionErroHandler = encryptionItemRequestOptions.DecryptionResultHandler; } responseMessage.Content = await this.DecryptResponseAsync( responseMessage.Content, decryptionErroHandler, diagnosticsContext, cancellationToken); return(responseMessage); } }
public async override Task <ResponseMessage> ReplaceItemStreamAsync( Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { if (id == null) { throw new ArgumentNullException(nameof(id)); } if (streamPayload == null) { throw new ArgumentNullException(nameof(streamPayload)); } CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("ReplaceItemStream")) { if (requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) { if (partitionKey == null) { throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}."); } streamPayload = await EncryptionProcessor.EncryptAsync( streamPayload, this.encryptor, encryptionItemRequestOptions.EncryptionOptions, diagnosticsContext, cancellationToken); ResponseMessage responseMessage = await this.container.ReplaceItemStreamAsync(streamPayload, id, partitionKey, requestOptions, cancellationToken); responseMessage.Content = await this.DecryptResponseAsync( responseMessage.Content, encryptionItemRequestOptions.DecryptionResultHandler, diagnosticsContext, cancellationToken); return(responseMessage); } else { return(await this.container.ReplaceItemStreamAsync(streamPayload, id, partitionKey, requestOptions, cancellationToken)); } } }
public override TransactionalBatch CreateItemStream( Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { EncryptionSettings encryptionSettings = this.encryptionContainer.GetOrUpdateEncryptionSettingsFromCacheAsync(obsoleteEncryptionSettings: null, cancellationToken: default)
public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder <T>( string processorName, ChangesHandler <T> onChangesDelegate) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(null); using (diagnosticsContext.CreateScope("GetChangeFeedProcessorBuilder")) { return(this.container.GetChangeFeedProcessorBuilder( processorName, async(IReadOnlyCollection <JObject> documents, CancellationToken cancellationToken) => { List <T> decryptedItems = new List <T>(documents.Count); foreach (JObject document in documents) { EncryptionSettings encryptionSettings = await this.GetOrUpdateEncryptionSettingsFromCacheAsync(obsoleteEncryptionSettings: null, cancellationToken: cancellationToken); try { JObject decryptedDocument = await EncryptionProcessor.DecryptAsync( document, encryptionSettings, diagnosticsContext, cancellationToken); decryptedItems.Add(decryptedDocument.ToObject <T>()); } // we cannot rely currently on a specific exception, this is due to the fact that the run time issue can be variable, // we can hit issue with either Json serialization say an item was not encrypted but the policy shows it as encrypted, // or we could hit a MicrosoftDataEncryptionException from MDE lib etc. catch (Exception) { // most likely the encryption policy has changed. encryptionSettings = await this.GetOrUpdateEncryptionSettingsFromCacheAsync( obsoleteEncryptionSettings: encryptionSettings, cancellationToken: cancellationToken); JObject decryptedDocument = await EncryptionProcessor.DecryptAsync( document, encryptionSettings, diagnosticsContext, cancellationToken); decryptedItems.Add(decryptedDocument.ToObject <T>()); } } // Call the original passed in delegate await onChangesDelegate(decryptedItems, cancellationToken); })); } }
private async Task <DataEncryptionKeyProperties> ReadResourceAsync( string id, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { using (diagnosticsContext.CreateScope("ReadDataEncryptionKey")) { return(await this.ReadInternalAsync( id : id, requestOptions : null, diagnosticsContext : diagnosticsContext, cancellationToken : cancellationToken)); } }
public override async Task <TransactionalBatchResponse> ExecuteAsync( CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(options: null); using (diagnosticsContext.CreateScope("TransactionalBatch.ExecuteAsync")) { TransactionalBatchResponse response = await this.transactionalBatch.ExecuteAsync(cancellationToken); return(await this.DecryptTransactionalBatchResponseAsync( response, diagnosticsContext, cancellationToken)); } }
public override async Task <ResponseMessage> CreateItemStreamAsync( Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { if (streamPayload == null) { throw new ArgumentNullException(nameof(streamPayload)); } CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("CreateItemStream")) { if (requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) { streamPayload = await EncryptionProcessor.EncryptAsync( streamPayload, this.encryptor, encryptionItemRequestOptions.EncryptionOptions, diagnosticsContext, cancellationToken); ResponseMessage responseMessage = await this.container.CreateItemStreamAsync( streamPayload, partitionKey, requestOptions, cancellationToken); responseMessage.Content = await this.DecryptResponseAsync( responseMessage.Content, encryptionItemRequestOptions.DecryptionResultHandler, diagnosticsContext, cancellationToken); return(responseMessage); } else { return(await this.container.CreateItemStreamAsync( streamPayload, partitionKey, requestOptions, cancellationToken)); } } }
public override async Task <ResponseMessage> ReadItemStreamAsync( string id, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("ReadItemStream")) { return(await this.ReadItemHelperAsync( id, partitionKey, requestOptions, diagnosticsContext, cancellationToken)); } }
internal async Task <InMemoryRawDek> UnwrapAsync( DataEncryptionKeyProperties dekProperties, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { EncryptionKeyUnwrapResult unwrapResult; using (diagnosticsContext.CreateScope("UnwrapDataEncryptionKey")) { unwrapResult = await this.DekProvider.EncryptionKeyWrapProvider.UnwrapKeyAsync( dekProperties.WrappedDataEncryptionKey, dekProperties.EncryptionKeyWrapMetadata, cancellationToken); } DataEncryptionKey dek = DataEncryptionKey.Create(unwrapResult.DataEncryptionKey, dekProperties.EncryptionAlgorithm); return(new InMemoryRawDek(dek, unwrapResult.ClientCacheTimeToLive)); }
public override async Task <ItemResponse <T> > ReadItemAsync <T>( string id, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("ReadItem")) { ResponseMessage responseMessage; if (typeof(T) == typeof(DecryptableItem)) { responseMessage = await this.ReadItemHelperAsync( id, partitionKey, requestOptions, decryptResponse : false, diagnosticsContext, cancellationToken); DecryptableItemCore decryptableItem = new DecryptableItemCore( EncryptionProcessor.BaseSerializer.FromStream <JObject>(responseMessage.Content), this.Encryptor, this.CosmosSerializer); return(new EncryptionItemResponse <T>( responseMessage, (T)(object)decryptableItem)); } responseMessage = await this.ReadItemHelperAsync( id, partitionKey, requestOptions, decryptResponse : true, diagnosticsContext, cancellationToken); return(this.ResponseFactory.CreateItemResponse <T>(responseMessage)); } }
public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(options: null); using (diagnosticsContext.CreateScope("FeedIterator.ReadNext")) { EncryptionSettings encryptionSettings = await this.encryptionContainer.GetOrUpdateEncryptionSettingsFromCacheAsync(obsoleteEncryptionSettings : null, cancellationToken : cancellationToken); encryptionSettings.SetRequestHeaders(this.requestOptions); ResponseMessage responseMessage = await this.feedIterator.ReadNextAsync(cancellationToken); // check for Bad Request and Wrong RID intended and update the cached RID and Client Encryption Policy. if (responseMessage.StatusCode == HttpStatusCode.BadRequest && string.Equals(responseMessage.Headers.Get(Constants.SubStatusHeader), Constants.IncorrectContainerRidSubStatus)) { await this.encryptionContainer.GetOrUpdateEncryptionSettingsFromCacheAsync( obsoleteEncryptionSettings : encryptionSettings, cancellationToken : cancellationToken); throw new CosmosException( "Operation has failed due to a possible mismatch in Client Encryption Policy configured on the container. Please refer to https://aka.ms/CosmosClientEncryption for more details. " + responseMessage.ErrorMessage, responseMessage.StatusCode, int.Parse(Constants.IncorrectContainerRidSubStatus), responseMessage.Headers.ActivityId, responseMessage.Headers.RequestCharge); } if (responseMessage.IsSuccessStatusCode && responseMessage.Content != null) { Stream decryptedContent = await this.DeserializeAndDecryptResponseAsync( responseMessage.Content, encryptionSettings, diagnosticsContext, cancellationToken); return(new DecryptedResponseMessage(responseMessage, decryptedContent)); } return(responseMessage); } }
public override async Task <ItemResponse <T> > ReadItemAsync <T>( string id, PartitionKey partitionKey, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("ReadItem")) { ResponseMessage responseMessage; responseMessage = await this.ReadItemHelperAsync( id, partitionKey, requestOptions, diagnosticsContext, cancellationToken); return(this.ResponseFactory.CreateItemResponse <T>(responseMessage)); } }
public override TransactionalBatch ReplaceItemStream( string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { streamPayload = this.encryptionProcessor.EncryptAsync( streamPayload, diagnosticsContext, default).Result; } this.transactionalBatch = this.transactionalBatch.ReplaceItemStream( id, streamPayload, requestOptions); return(this); }
public override async Task <ItemResponse <T> > CreateItemAsync <T>( T item, PartitionKey?partitionKey = null, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (!(requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) || encryptionItemRequestOptions.EncryptionOptions == null) { return(await this.container.CreateItemAsync <T>( item, partitionKey, requestOptions, cancellationToken)); } if (partitionKey == null) { throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}."); } CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("CreateItem")) { ResponseMessage responseMessage; if (item is EncryptableItem encryptableItem) { using (Stream streamPayload = encryptableItem.ToStream(this.CosmosSerializer)) { responseMessage = await this.CreateItemHelperAsync( streamPayload, partitionKey.Value, requestOptions, decryptResponse : false, diagnosticsContext, cancellationToken); } encryptableItem.SetDecryptableItem( EncryptionProcessor.BaseSerializer.FromStream <JObject>(responseMessage.Content), this.Encryptor, this.CosmosSerializer); return(new EncryptionItemResponse <T>( responseMessage, item)); } else { using (Stream itemStream = this.CosmosSerializer.ToStream <T>(item)) { responseMessage = await this.CreateItemHelperAsync( itemStream, partitionKey.Value, requestOptions, decryptResponse : true, diagnosticsContext, cancellationToken); } return(this.ResponseFactory.CreateItemResponse <T>(responseMessage)); } } }