@@ -176,6 +176,12 @@ protected async System.Threading.Tasks.Task PostInvokeAsync(IExecutionContext ex
176176 /// <exception cref="AmazonServiceException">Exception thrown if GetObjectResponse decryption fails</exception>
177177 protected async System . Threading . Tasks . Task DecryptObjectAsync ( byte [ ] decryptedEnvelopeKeyKMS , GetObjectResponse getObjectResponse )
178178 {
179+ /*
180+ * Per inputs from Crypto Tools team, the behavior to return plaintext violates the security guarantees of the library.
181+ * A threat actor with write access to S3 can replace an encrypted object with a plaintext object, and the GetObject operation succeeds.
182+ * This violates the integrity guarantee, i.e. that the original plaintext has not replaced with a different plaintext.
183+ * Therefore, plaintext objects must be handled outside of the security boundary of the S3EC.
184+ */
179185 if ( EncryptionUtils . IsEncryptionInfoInMetadata ( getObjectResponse ) )
180186 {
181187 DecryptObjectUsingMetadata ( getObjectResponse , decryptedEnvelopeKeyKMS ) ;
@@ -197,6 +203,11 @@ protected async System.Threading.Tasks.Task DecryptObjectAsync(byte[] decryptedE
197203 var instructionFileRequest = EncryptionUtils . GetInstructionFileRequest ( getObjectResponse , EncryptionUtils . EncryptionInstructionFileSuffix ) ;
198204 instructionFileResponse = await GetInstructionFileAsync ( instructionFileRequest ) . ConfigureAwait ( false ) ;
199205 }
206+ catch ( AmazonS3Exception amazonS3ExceptionInner ) when ( amazonS3ExceptionInner . ErrorCode == EncryptionUtils . NoSuchKey )
207+ {
208+ throw new AmazonServiceException ( $ "Exception encountered while fetching Instruction File. Ensure the object you are" +
209+ $ " attempting to decrypt has been encrypted using the S3 Encryption Client.", amazonS3ExceptionInner ) ;
210+ }
200211 catch ( AmazonServiceException ace )
201212 {
202213 throw new AmazonServiceException ( $ "Unable to decrypt data for object { getObjectResponse . Key } in bucket { getObjectResponse . BucketName } ", ace ) ;
@@ -307,6 +318,12 @@ protected void PostInvokeSynchronous(IExecutionContext executionContext, byte[]
307318 /// <exception cref="AmazonServiceException">Exception thrown if GetObjectResponse decryption fails</exception>
308319 protected void DecryptObject ( byte [ ] decryptedEnvelopeKeyKMS , GetObjectResponse getObjectResponse )
309320 {
321+ /*
322+ * Per inputs from Crypto Tools team, the behavior to return plaintext violates the security guarantees of the library.
323+ * A threat actor with write access to S3 can replace an encrypted object with a plaintext object, and the GetObject operation succeeds.
324+ * This violates the integrity guarantee, i.e. that the original plaintext has not replaced with a different plaintext.
325+ * Therefore, plaintext objects must be handled outside of the security boundary of the S3EC.
326+ */
310327 if ( EncryptionUtils . IsEncryptionInfoInMetadata ( getObjectResponse ) )
311328 {
312329 DecryptObjectUsingMetadata ( getObjectResponse , decryptedEnvelopeKeyKMS ) ;
@@ -328,6 +345,11 @@ protected void DecryptObject(byte[] decryptedEnvelopeKeyKMS, GetObjectResponse g
328345 var instructionFileRequest = EncryptionUtils . GetInstructionFileRequest ( getObjectResponse , EncryptionUtils . EncryptionInstructionFileSuffix ) ;
329346 instructionFileResponse = GetInstructionFile ( instructionFileRequest ) ;
330347 }
348+ catch ( AmazonS3Exception amazonS3ExceptionInner ) when ( amazonS3ExceptionInner . ErrorCode == EncryptionUtils . NoSuchKey )
349+ {
350+ throw new AmazonServiceException ( $ "Exception encountered while fetching Instruction File. Ensure the object you are" +
351+ $ " attempting to decrypt has been encrypted using the S3 Encryption Client.", amazonS3ExceptionInner ) ;
352+ }
331353 catch ( AmazonServiceException ace )
332354 {
333355 throw new AmazonServiceException ( $ "Unable to decrypt data for object { getObjectResponse . Key } in bucket { getObjectResponse . BucketName } ", ace ) ;
0 commit comments