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);
}
}