@@ -180,6 +180,12 @@ protected async System.Threading.Tasks.Task PostInvokeAsync(IExecutionContext ex
180180 /// <exception cref="AmazonServiceException">Exception thrown if GetObjectResponse decryption fails</exception>
181181 protected async System . Threading . Tasks . Task DecryptObjectAsync ( byte [ ] decryptedEnvelopeKeyKMS , GetObjectResponse getObjectResponse )
182182 {
183+ /*
184+ * Per inputs from Crypto Tools team, the behavior to return plaintext violates the security guarantees of the library.
185+ * A threat actor with write access to S3 can replace an encrypted object with a plaintext object, and the GetObject operation succeeds.
186+ * This violates the integrity guarantee, i.e. that the original plaintext has not replaced with a different plaintext.
187+ * Therefore, plaintext objects must be handled outside of the security boundary of the S3EC.
188+ */
183189 if ( EncryptionUtils . IsEncryptionInfoInMetadata ( getObjectResponse ) )
184190 {
185191 DecryptObjectUsingMetadata ( getObjectResponse , decryptedEnvelopeKeyKMS ) ;
@@ -201,6 +207,11 @@ protected async System.Threading.Tasks.Task DecryptObjectAsync(byte[] decryptedE
201207 var instructionFileRequest = EncryptionUtils . GetInstructionFileRequest ( getObjectResponse , EncryptionUtils . EncryptionInstructionFileSuffix ) ;
202208 instructionFileResponse = await GetInstructionFileAsync ( instructionFileRequest ) . ConfigureAwait ( false ) ;
203209 }
210+ catch ( AmazonS3Exception amazonS3ExceptionInner ) when ( amazonS3ExceptionInner . ErrorCode == EncryptionUtils . NoSuchKey )
211+ {
212+ throw new AmazonServiceException ( $ "Exception encountered while fetching Instruction File. Ensure the object you are" +
213+ $ " attempting to decrypt has been encrypted using the S3 Encryption Client.", amazonS3ExceptionInner ) ;
214+ }
204215 catch ( AmazonServiceException ace )
205216 {
206217 throw new AmazonServiceException ( $ "Unable to decrypt data for object { getObjectResponse . Key } in bucket { getObjectResponse . BucketName } ", ace ) ;
@@ -352,6 +363,12 @@ protected void PostInvokeSynchronous(IExecutionContext executionContext, byte[]
352363 /// <exception cref="AmazonServiceException">Exception thrown if GetObjectResponse decryption fails</exception>
353364 protected void DecryptObject ( byte [ ] decryptedEnvelopeKeyKMS , GetObjectResponse getObjectResponse )
354365 {
366+ /*
367+ * Per inputs from Crypto Tools team, the behavior to return plaintext violates the security guarantees of the library.
368+ * A threat actor with write access to S3 can replace an encrypted object with a plaintext object, and the GetObject operation succeeds.
369+ * This violates the integrity guarantee, i.e. that the original plaintext has not replaced with a different plaintext.
370+ * Therefore, plaintext objects must be handled outside of the security boundary of the S3EC.
371+ */
355372 if ( EncryptionUtils . IsEncryptionInfoInMetadata ( getObjectResponse ) )
356373 {
357374 DecryptObjectUsingMetadata ( getObjectResponse , decryptedEnvelopeKeyKMS ) ;
@@ -373,6 +390,11 @@ protected void DecryptObject(byte[] decryptedEnvelopeKeyKMS, GetObjectResponse g
373390 var instructionFileRequest = EncryptionUtils . GetInstructionFileRequest ( getObjectResponse , EncryptionUtils . EncryptionInstructionFileSuffix ) ;
374391 instructionFileResponse = GetInstructionFile ( instructionFileRequest ) ;
375392 }
393+ catch ( AmazonS3Exception amazonS3ExceptionInner ) when ( amazonS3ExceptionInner . ErrorCode == EncryptionUtils . NoSuchKey )
394+ {
395+ throw new AmazonServiceException ( $ "Exception encountered while fetching Instruction File. Ensure the object you are" +
396+ $ " attempting to decrypt has been encrypted using the S3 Encryption Client.", amazonS3ExceptionInner ) ;
397+ }
376398 catch ( AmazonServiceException ace )
377399 {
378400 throw new AmazonServiceException ( $ "Unable to decrypt data for object { getObjectResponse . Key } in bucket { getObjectResponse . BucketName } ", ace ) ;
0 commit comments