protected void DecryptObjectUsingMetadata()

in src/Internal/SetupDecryptionHandler.cs [402:458]


        protected void DecryptObjectUsingMetadata(GetObjectResponse getObjectResponse, byte[] decryptedEnvelopeKeyKMS)
        {
            // Create an instruction object from the object metadata
            EncryptionInstructions instructions = EncryptionUtils.BuildInstructionsFromObjectMetadata(getObjectResponse, EncryptionClient.EncryptionMaterials, decryptedEnvelopeKeyKMS);

            if (decryptedEnvelopeKeyKMS != null)
            {
                // Check if encryption context is present for KMS+context (v2) objects
                if (getObjectResponse.Metadata[EncryptionUtils.XAmzCekAlg] != null
                    && instructions.MaterialsDescription.ContainsKey(EncryptionUtils.XAmzEncryptionContextCekAlg))
                {
                    // If encryption context is present, ensure that the GCM algorithm name is in the EC as expected in v2
                    if (EncryptionUtils.XAmzAesGcmCekAlgValue.Equals(getObjectResponse.Metadata[EncryptionUtils.XAmzCekAlg])
                        && EncryptionUtils.XAmzAesGcmCekAlgValue.Equals(instructions.MaterialsDescription[EncryptionUtils.XAmzEncryptionContextCekAlg]))
                    {
                        // Decrypt the object with V2 instruction
                        EncryptionUtils.DecryptObjectUsingInstructionsGcm(getObjectResponse, instructions);
                    }
                    else
                    {
                        throw new AmazonCryptoException($"The content encryption algorithm used at encryption time does not match the algorithm stored for decryption time." +
                                                        " The object may be altered or corrupted.");
                    }
                }
                // Handle legacy KMS (v1) mode with GCM content encryption 
                // See https://github.com/aws/amazon-s3-encryption-client-dotnet/issues/26 for context. It fixes AWS SES encryption/decryption bug
                else if (EncryptionUtils.XAmzAesGcmCekAlgValue.Equals(instructions.CekAlgorithm)) 
                {
                    // KMS (v1) without Encryption Context requires legacy mode to be enabled even when GCM is used for content encryption
                    ThrowIfLegacyReadIsDisabled();
                    EncryptionUtils.DecryptObjectUsingInstructionsGcm(getObjectResponse, instructions);
                }
                else if (EncryptionUtils.XAmzAesCbcPaddingCekAlgValue.Equals(instructions.CekAlgorithm))
                {
                    ThrowIfLegacyReadIsDisabled();
                    // Decrypt the object with V1 instruction
                    EncryptionUtils.DecryptObjectUsingInstructions(getObjectResponse, instructions);
                }
                else
                {
                    throw new AmazonCryptoException($"The content encryption algorithm used at encryption time does not match the algorithm stored for decryption time." +
                                                    " The object may be altered or corrupted.");
                }
            }
            else if (EncryptionUtils.XAmzAesGcmCekAlgValue.Equals(getObjectResponse.Metadata[EncryptionUtils.XAmzCekAlg]))
            {
                // Decrypt the object with V2 instruction
                EncryptionUtils.DecryptObjectUsingInstructionsGcm(getObjectResponse, instructions);
            }
            // It is safe to assume, this is either non KMS encryption with V1 client or AES CBC
            // We don't need to check cek algorithm to be AES CBC, because non KMS encryption with V1 client doesn't set it
            else
            {
                ThrowIfLegacyReadIsDisabled();
                EncryptionUtils.DecryptObjectUsingInstructions(getObjectResponse, instructions);
            }
        }