protected void DecryptObject()

in src/Internal/SetupDecryptionHandler.cs [319:365]


        protected void DecryptObject(byte[] decryptedEnvelopeKeyKMS, GetObjectResponse getObjectResponse)
        {
            /*
            * Per inputs from Crypto Tools team, the behavior to return plaintext violates the security guarantees of the library.
            * A threat actor with write access to S3 can replace an encrypted object with a plaintext object, and the GetObject operation succeeds. 
            * This violates the integrity guarantee, i.e. that the original plaintext has not replaced with a different plaintext. 
            * Therefore, plaintext objects must be handled outside of the security boundary of the S3EC.
            */
            if (EncryptionUtils.IsEncryptionInfoInMetadata(getObjectResponse))
            {
                DecryptObjectUsingMetadata(getObjectResponse, decryptedEnvelopeKeyKMS);
            }
            else
            {
                GetObjectResponse instructionFileResponse = null;
                try
                {
                    var instructionFileRequest = EncryptionUtils.GetInstructionFileRequest(getObjectResponse, EncryptionUtils.EncryptionInstructionFileV2Suffix);
                    instructionFileResponse = GetInstructionFile(instructionFileRequest);
                }
                catch (AmazonS3Exception amazonS3Exception) when (amazonS3Exception.ErrorCode == EncryptionUtils.NoSuchKey)
                {
                    Logger.InfoFormat($"New instruction file with suffix {EncryptionUtils.EncryptionInstructionFileV2Suffix} doesn't exist. " +
                                      $"Try to get old instruction file with suffix {EncryptionUtils.EncryptionInstructionFileSuffix}. {amazonS3Exception.Message}");
                    try
                    {
                        var instructionFileRequest = EncryptionUtils.GetInstructionFileRequest(getObjectResponse, EncryptionUtils.EncryptionInstructionFileSuffix);
                        instructionFileResponse = GetInstructionFile(instructionFileRequest);
                    }
                    catch (AmazonS3Exception amazonS3ExceptionInner) when (amazonS3ExceptionInner.ErrorCode == EncryptionUtils.NoSuchKey)
                    {
                        throw new AmazonServiceException($"Exception encountered while fetching Instruction File. Ensure the object you are" +
                            $" attempting to decrypt has been encrypted using the S3 Encryption Client.", amazonS3ExceptionInner);
                    }
                    catch (AmazonServiceException ace)
                    {
                        throw new AmazonServiceException($"Unable to decrypt data for object {getObjectResponse.Key} in bucket {getObjectResponse.BucketName}", ace);
                    }
                }
                catch (AmazonServiceException ace)
                {
                    throw new AmazonServiceException($"Unable to decrypt data for object {getObjectResponse.Key} in bucket {getObjectResponse.BucketName}", ace);
                }

                DecryptObjectUsingInstructionFile(getObjectResponse, instructionFileResponse);
            }
        }