in src/aws-cpp-sdk-s3-encryption/source/s3-encryption/S3EncryptionClient.cpp [66:148]
S3EncryptionGetObjectOutcome S3EncryptionClientBase::GetObject(const Aws::S3::Model::GetObjectRequest & request) const
{
Aws::S3::Model::HeadObjectRequest headRequest;
headRequest.WithBucket(request.GetBucket());
headRequest.WithKey(request.GetKey());
Aws::S3::Model::HeadObjectOutcome headOutcome = m_s3Client->HeadObject(headRequest);
if (!headOutcome.IsSuccess())
{
AWS_LOGSTREAM_ERROR(ALLOCATION_TAG, "Head Request not successful: "
<< headOutcome.GetError().GetExceptionName() << " : "
<< headOutcome.GetError().GetMessage());
return S3EncryptionGetObjectOutcome(BuildS3EncryptionError(headOutcome.GetError()));
}
auto headMetadata = headOutcome.GetResult().GetMetadata();
auto metadataEnd = headMetadata.end();
CryptoConfiguration decryptionCryptoConfig;
headMetadata.find(CONTENT_KEY_HEADER) != metadataEnd && headMetadata.find(IV_HEADER) != metadataEnd
? decryptionCryptoConfig.SetStorageMethod(StorageMethod::METADATA)
: decryptionCryptoConfig.SetStorageMethod(StorageMethod::INSTRUCTION_FILE);
ContentCryptoMaterial contentCryptoMaterial;
if (decryptionCryptoConfig.GetStorageMethod() == StorageMethod::INSTRUCTION_FILE)
{
GetObjectOutcome instructionOutcome = GetInstructionFileObject(request);
if (!instructionOutcome.IsSuccess())
{
return S3EncryptionGetObjectOutcome(BuildS3EncryptionError(instructionOutcome.GetError()));
}
Handlers::InstructionFileHandler handler;
contentCryptoMaterial = handler.ReadContentCryptoMaterial(instructionOutcome.GetResult());
}
else
{
Handlers::MetadataHandler handler;
contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult());
}
// security check
if (request.RangeHasBeenSet() && m_cryptoConfig.GetUnAuthenticatedRangeGet() == RangeGetMode::DISABLED)
{
AWS_LOGSTREAM_ERROR(ALLOCATION_TAG, "Unable to perform range get request: Range get support has been disabled. See https://docs.aws.amazon.com/general/latest/gr/aws_sdk_cryptography.html");
return S3EncryptionGetObjectOutcome(BuildS3EncryptionError(AWSError<S3Errors>(S3Errors::INVALID_ACTION, "RangeGetFailed",
"Unable to perform range get request: Range get support has been disabled. See https://docs.aws.amazon.com/general/latest/gr/aws_sdk_cryptography.html", false/*not retryable*/)));
}
if (m_cryptoConfig.GetSecurityProfile() == SecurityProfile::V2)
{
if (contentCryptoMaterial.GetKeyWrapAlgorithm() != KeyWrapAlgorithm::AES_GCM &&
contentCryptoMaterial.GetKeyWrapAlgorithm() != KeyWrapAlgorithm::KMS_CONTEXT)
{
AWS_LOGSTREAM_ERROR(ALLOCATION_TAG, "The requested object is encrypted with V1 encryption schemas that have been disabled by client configuration securityProfile=V2. Retry with V2_AND_LEGACY enabled or re-encrypt the object");
return S3EncryptionGetObjectOutcome(BuildS3EncryptionError(AWSError<S3Errors>(S3Errors::INVALID_ACTION, "DecryptV1EncryptSchemaFailed",
"The requested object is encrypted with V1 encryption schemas that have been disabled by client configuration securityProfile=V2. Retry with V2_AND_LEGACY enabled or re-encrypt the object.", false/*not retryable*/)));
}
if (contentCryptoMaterial.GetContentCryptoScheme() != ContentCryptoScheme::GCM)
{
AWS_LOGSTREAM_ERROR(ALLOCATION_TAG, "The requested object is encrypted with V1 encryption schemas that have been disabled by client configuration securityProfile=V2. Retry with V2_AND_LEGACY enabled or re-encrypt the object");
return S3EncryptionGetObjectOutcome(BuildS3EncryptionError(AWSError<S3Errors>(S3Errors::INVALID_ACTION, "DecryptV1EncryptSchemaFailed",
"The requested object is encrypted with V1 encryption schemas that have been disabled by client configuration securityProfile=V2. Retry with V2_AND_LEGACY enabled or re-encrypt the object.", false/*not retryable*/)));
}
}
if (contentCryptoMaterial.GetContentCryptoScheme() == ContentCryptoScheme::CBC)
{
decryptionCryptoConfig.SetCryptoMode(CryptoMode::ENCRYPTION_ONLY);
}
else if (m_cryptoConfig.GetCryptoMode() != CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION &&
contentCryptoMaterial.GetContentCryptoScheme() == ContentCryptoScheme::GCM)
{
decryptionCryptoConfig.SetCryptoMode(CryptoMode::AUTHENTICATED_ENCRYPTION);
}
else
{
assert(request.GetRange().empty());
decryptionCryptoConfig.SetCryptoMode(CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION);
}
auto module = m_cryptoModuleFactory.FetchCryptoModule(m_encryptionMaterials, decryptionCryptoConfig);
auto getObjectFunction = [this](const Aws::S3::Model::GetObjectRequest& getRequest) { return m_s3Client->GetObject(getRequest); };
return module->GetObjectSecurely(request, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction);
}