private async Task <Stream> DecryptResponseAsync( Stream input, Action <DecryptionResult> DecryptionResultHandler, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { if (input == null) { return(input); } try { return(await EncryptionProcessor.DecryptAsync( input, this.encryptor, diagnosticsContext, cancellationToken)); } catch (Exception exception) { input.Position = 0; if (DecryptionResultHandler == null) { throw; } using (MemoryStream memoryStream = new MemoryStream((int)input.Length)) { input.CopyTo(memoryStream); ArraySegment <byte> encryptedStream; bool wasBufferReturned = memoryStream.TryGetBuffer(out encryptedStream); Debug.Assert(wasBufferReturned); DecryptionResultHandler( DecryptionResult.CreateFailure( encryptedStream, exception)); } input.Position = 0; return(input); } }
private async Task <Stream> DeserializeAndDecryptResponseAsync( Stream content, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { JObject contentJObj = EncryptionProcessor.BaseSerializer.FromStream <JObject>(content); JArray result = new JArray(); if (!(contentJObj.SelectToken(Constants.DocumentsResourcePropertyName) is JArray documents)) { throw new InvalidOperationException("Feed response Body Contract was violated. Feed response did not have an array of Documents"); } foreach (JToken value in documents) { if (!(value is JObject document)) { result.Add(value); continue; } try { JObject decryptedDocument = await EncryptionProcessor.DecryptAsync( document, this.encryptor, diagnosticsContext, cancellationToken); result.Add(decryptedDocument); } catch (Exception exception) { if (this.decryptionResultHandler == null) { throw; } result.Add(document); MemoryStream memoryStream = EncryptionProcessor.BaseSerializer.ToStream(document); Debug.Assert(memoryStream != null); bool wasBufferReturned = memoryStream.TryGetBuffer(out ArraySegment <byte> encryptedStream); Debug.Assert(wasBufferReturned); this.decryptionResultHandler( DecryptionResult.CreateFailure( encryptedStream, exception)); } } JObject decryptedResponse = new JObject(); foreach (JProperty property in contentJObj.Properties()) { if (property.Name.Equals(Constants.DocumentsResourcePropertyName)) { decryptedResponse.Add(property.Name, (JToken)result); } else { decryptedResponse.Add(property.Name, property.Value); } } return(EncryptionProcessor.BaseSerializer.ToStream(decryptedResponse)); }