/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #define AWS_DISABLE_DEPRECATION #ifndef NO_SYMMETRIC_ENCRYPTION #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { static const char* const ALLOCATION_TAG = "CryptoModuleTests"; static const char* const BUCKET_TEST_NAME = "testbucket"; static const char* const KEY_TEST_NAME = "testKey"; static const char* const BODY_STREAM_TEST = "This is a test message for encryption and decryption."; static const char* const TEST_CMK_ID = "ARN:SOME_COMBINATION_OF_LETTERS_AND_NUMBERS"; static size_t const CBC_IV_SIZE_BYTES = 16u; static const char* const BYTES_SPECIFIER = "bytes=0-10"; static const char* const GET_RANGE_SPECIFIER = "bytes=20-40"; static const char* const GET_RANGE_OUTPUT = "ge for encryption and"; static size_t const GCM_TAG_LENGTH = 128u; static size_t const GCM_IV_SIZE_BYTES = 12u; using namespace Aws::Auth; using namespace Aws::Client; using namespace Aws::S3Encryption; using namespace Aws::Utils::Crypto; using namespace Aws::Utils::Crypto::ContentCryptoSchemeMapper; using namespace Aws::Utils::Crypto::KeyWrapAlgorithmMapper; using namespace Aws::S3Encryption::Modules; using namespace Aws::S3Encryption::Materials; using namespace Aws::S3::Model; using namespace Aws::S3; using namespace Aws::KMS; using namespace Aws::KMS::Model; /* * This is a class that represents a mock KMS Client which is used to encrypt/decrypt the content encryption key * in the S3 Encryption Client module. When encrypt is called, it will take the plain text key and store it and * return the user a different generated key to take place as the encrypted key. Then when decrypt is called, the * plaintext key will be returned to the user. This does not actually decrypt or encrypt anything, but acts in * the same fashion as an actual KMS Client. */ class MockKMSClient : public KMSClient { public: MockKMSClient(ClientConfiguration clientConfiguration = ClientConfiguration()) : KMSClient(Aws::Auth::AWSCredentials("", ""), clientConfiguration), m_encryptCalledCount(0), m_genDataKeyCalledCount(0), m_decryptCalledCount(0), m_encryptedKey(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()), m_decryptedKey(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()), m_triggerDecryptFailure(false), m_triggerCorruptedDecryption(false) { } EncryptOutcome Encrypt(const EncryptRequest& request) const override { Aws::Utils::CryptoBuffer buffer(request.GetPlaintext().GetUnderlyingData(), request.GetPlaintext().GetLength()); m_decryptedKey = buffer; m_encryptCalledCount++; return PopulateSuccessfulEncryptOutcome(); } GenerateDataKeyOutcome GenerateDataKey(const GenerateDataKeyRequest&) const override { m_genDataKeyCalledCount++; return PopulateSuccessfulGenDataKeyOutcome(); } DecryptOutcome Decrypt(const DecryptRequest&) const override { m_decryptCalledCount++; if (m_triggerDecryptFailure) { return PopulateFailedDecryptOutcome(); } if (m_triggerCorruptedDecryption) { return PopulateCorruptedDecryptOutcome(); } return PopulateSuccessfulDecryptOutcome(); } mutable size_t m_encryptCalledCount; mutable size_t m_genDataKeyCalledCount; mutable size_t m_decryptCalledCount; Aws::Utils::CryptoBuffer m_encryptedKey; mutable Aws::Utils::CryptoBuffer m_decryptedKey; mutable bool m_triggerDecryptFailure; mutable bool m_triggerCorruptedDecryption; private: EncryptOutcome PopulateSuccessfulEncryptOutcome() const { EncryptOutcome outcome; EncryptResult result(outcome.GetResult()); result.SetCiphertextBlob(m_encryptedKey); return result; } GenerateDataKeyOutcome PopulateSuccessfulGenDataKeyOutcome() const { GenerateDataKeyOutcome outcome; GenerateDataKeyResult result(outcome.GetResult()); result.SetPlaintext(m_decryptedKey); result.SetCiphertextBlob(m_encryptedKey); return result; } DecryptOutcome PopulateSuccessfulDecryptOutcome() const { DecryptOutcome outcome; DecryptResult result(outcome.GetResult()); result.SetPlaintext(m_decryptedKey); return result; } DecryptOutcome PopulateFailedDecryptOutcome() const { return KMSError(); } DecryptOutcome PopulateCorruptedDecryptOutcome() const { DecryptOutcome outcome; DecryptResult result(outcome.GetResult()); result.SetPlaintext(Aws::Utils::CryptoBuffer(m_decryptedKey.GetUnderlyingData(), m_decryptedKey.GetLength() / 2)); return result; } }; /* * This is a class that represents a S3 Client which is used to mimic the put/get operations of a actual s3 client. * During a put object, the body of the request is stored as well as the metadata of the request. This data is then * populated into a get object result when a get operation is called. If a get request has a range specifying the * last 16 bytes of data, we know this is the crypto tag stored at the end of the body for GCM encryption, and we * return this. If the range is everything but the last 16 bytes then we only return that part of the body to the * result. */ class MockS3Client : public Aws::S3::S3Client { public: MockS3Client(Aws::Client::ClientConfiguration clientConfiguration = Aws::Client::ClientConfiguration()) : S3Client(Aws::Auth::AWSCredentials("", ""), Aws::MakeShared(ALLOCATION_TAG), clientConfiguration), m_putObjectCalled(0), m_getObjectCalled(0), m_body(nullptr) { } Aws::S3::Model::PutObjectOutcome PutObject(const Aws::S3::Model::PutObjectRequest& request) const override { m_putObjectCalled++; if (request.GetKey().find(Aws::S3Encryption::Handlers::DEFAULT_INSTRUCTION_FILE_SUFFIX) != Aws::String::npos) { Aws::S3::Model::PutObjectOutcome outcome; Aws::S3::Model::PutObjectResult result(outcome.GetResultWithOwnership()); return result; } m_metadata = request.GetMetadata(); m_requestContentLength = static_cast< size_t >(request.GetContentLength()); std::shared_ptr body = request.GetBody(); Aws::String tempBodyString((Aws::IStreamBufIterator(*body)), Aws::IStreamBufIterator()); bodyString = tempBodyString; Aws::S3::Model::PutObjectOutcome outcome; Aws::S3::Model::PutObjectResult result(outcome.GetResultWithOwnership()); return result; } Aws::S3::Model::GetObjectOutcome GetObject(const Aws::S3::Model::GetObjectRequest& request) const override { m_getObjectCalled++; auto factory = request.GetResponseStreamFactory(); Aws::Utils::Stream::ResponseStream responseStream(factory); Aws::String range = request.GetRange(); size_t written = 0; if (!range.empty()) { auto bytes = m_requestContentLength; auto rangeBytes = CryptoModule::ParseGetObjectRequestRange(range, bytes); responseStream.GetUnderlyingStream().write((const char*)bodyString.c_str() + rangeBytes.first, rangeBytes.second - rangeBytes.first + 1); written = static_cast< size_t >(rangeBytes.second - rangeBytes.first); } else { responseStream.GetUnderlyingStream().write((const char*)bodyString.c_str(), m_requestContentLength); written = m_requestContentLength; } responseStream.GetUnderlyingStream().flush(); Aws::AmazonWebServiceResult awsStream(std::move(responseStream), Aws::Http::HeaderValueCollection()); Aws::S3::Model::GetObjectResult getObjectResult(std::move(awsStream)); getObjectResult.SetContentLength(written); getObjectResult.SetMetadata(m_metadata); return Aws::S3::Model::GetObjectOutcome(std::move(getObjectResult)); } Aws::S3::Model::HeadObjectOutcome HeadObject(const Aws::S3::Model::HeadObjectRequest&) const override { Aws::S3::Model::HeadObjectOutcome outcome; Aws::S3::Model::HeadObjectResult result(outcome.GetResultWithOwnership()); result.SetMetadata(m_metadata); result.SetContentLength(m_requestContentLength); return result; } const Aws::Map& GetMetadata() const { return m_metadata; } size_t GetRequestContentLength() const { return m_requestContentLength; } mutable size_t m_putObjectCalled; mutable size_t m_getObjectCalled; mutable Aws::String bodyString; mutable Aws::Map m_metadata; mutable std::shared_ptr m_body; mutable std::shared_ptr m_instructionBody; mutable size_t m_requestContentLength; }; class CryptoModulesTest : public ::testing::Test { protected: /* * Function to check if metadata map contains content crypto material. * Use this function to make sure a put object request contains all the material after * a PutObjectSecurely call. */ static void MetadataFilled(Aws::Map metadataMap) { auto metadataEnd = metadataMap.end(); ASSERT_TRUE(metadataMap.find(CONTENT_KEY_HEADER) != metadataEnd && metadataMap.find(IV_HEADER) != metadataEnd && metadataMap.find(CRYPTO_TAG_LENGTH_HEADER) != metadataEnd && metadataMap.find(CONTENT_CRYPTO_SCHEME_HEADER) != metadataEnd && metadataMap.find(KEY_WRAP_ALGORITHM) != metadataEnd && metadataMap.find(MATERIALS_DESCRIPTION_HEADER) != metadataEnd); ASSERT_TRUE(metadataMap[CONTENT_KEY_HEADER].size() > 0u); ASSERT_TRUE(metadataMap[IV_HEADER].size() > 0u); ASSERT_TRUE(metadataMap[CRYPTO_TAG_LENGTH_HEADER].size() > 0u); ASSERT_TRUE(metadataMap[CONTENT_CRYPTO_SCHEME_HEADER].size() > 0u); ASSERT_TRUE(metadataMap[KEY_WRAP_ALGORITHM].size() > 0u); ASSERT_TRUE(metadataMap[MATERIALS_DESCRIPTION_HEADER].size() > 0u); } }; TEST_F(CryptoModulesTest, EncryptionOnlyOperationsTestWithSimpleEncryptionMaterials) { Aws::Utils::CryptoBuffer masterKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey(); SimpleEncryptionMaterials materials(masterKey); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, 0u); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), CBC_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::CBC); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_KEY_WRAP); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(BODY_STREAM_TEST, ss.str().c_str()); ASSERT_EQ(s3Client.GetMetadata(), getOutcome.GetResult().GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 1u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, AuthenticatedEncryptionOperationsTestWithSimpleEncryptionMaterials) { Aws::Utils::CryptoBuffer masterKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey(); SimpleEncryptionMaterials materials(masterKey); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_KEY_WRAP); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(BODY_STREAM_TEST, ss.str().c_str()); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, StrictAuthenticatedEncryptionOperationsTestWithSimpleEncryptionMaterials) { Aws::Utils::CryptoBuffer masterKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey(); SimpleEncryptionMaterials materials(masterKey); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_KEY_WRAP); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, EncryptionOnlyOperationsTestWithSimpleEncryptionMaterialsWithGCMAAD) { Aws::Utils::CryptoBuffer masterKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey(); SimpleEncryptionMaterialsWithGCMAAD materials(masterKey); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, 0u); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), CBC_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::CBC); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_GCM); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(BODY_STREAM_TEST, ss.str().c_str()); ASSERT_EQ(s3Client.GetMetadata(), getOutcome.GetResult().GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 1u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, AuthenticatedEncryptionOperationsTestWithSimpleEncryptionMaterialsWithGCMAAD) { Aws::Utils::CryptoBuffer masterKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey(); SimpleEncryptionMaterialsWithGCMAAD materials(masterKey); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_GCM); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(BODY_STREAM_TEST, ss.str().c_str()); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, StrictAuthenticatedEncryptionOperationsTestWithSimpleEncryptionMaterialsWithGCMAAD) { Aws::Utils::CryptoBuffer masterKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey(); SimpleEncryptionMaterialsWithGCMAAD materials(masterKey); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_GCM); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, EncryptionOnlyOperationsTestWithKMSWithContextEncryptionMaterials) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); KMSWithContextEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, 0u); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), CBC_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::CBC); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS_CONTEXT); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); ASSERT_EQ(contentCryptoMaterial.GetEncryptedContentEncryptionKey(), kmsClient->m_encryptedKey); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 1u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 1u); ASSERT_EQ(kmsClient->m_encryptCalledCount, 0u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, EncryptionOnlyOperationsTestWithKMSEncryptionMaterials) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); KMSEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, 0u); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), CBC_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::CBC); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); ASSERT_EQ(contentCryptoMaterial.GetEncryptedContentEncryptionKey(), kmsClient->m_encryptedKey); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 1u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 0u); ASSERT_EQ(kmsClient->m_encryptCalledCount, 1u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, AuthenticatedEncryptionOperationsTestWithKMSEncryptionMaterials) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); KMSEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 0u); ASSERT_EQ(kmsClient->m_encryptCalledCount, 1u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, AuthenticatedEncryptionOperationsTestWithKMSWithContextEncryptionMaterials) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); KMSWithContextEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS_CONTEXT); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 1u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, AuthenticatedEncryptionOperationsTestWithKMSWithContextEncryptionMaterialsWithFailedKMSDecryption) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); kmsClient->m_triggerDecryptFailure = true; KMSWithContextEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS_CONTEXT); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); ASSERT_FALSE(getOutcome.IsSuccess()); ASSERT_EQ(s3Client.m_getObjectCalled, 0u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 1u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, AuthenticatedEncryptionOperationsTestWithKMSWithContextEncryptionMaterialsWithCorruptedKMSDecryption) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); kmsClient->m_triggerCorruptedDecryption = true; KMSWithContextEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS_CONTEXT); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); ASSERT_FALSE(getOutcome.IsSuccess()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 1u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, AERangeGet) { SimpleEncryptionMaterials materials(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(GCM_TAG_LENGTH, cryptoTagLength); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(GCM_IV_SIZE_BYTES, ivBuffer.GetLength()); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(ContentCryptoScheme::GCM, scheme); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(KeyWrapAlgorithm::AES_KEY_WRAP, keyWrapAlgorithm); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); getRequest.SetRange(GET_RANGE_SPECIFIER); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(GET_RANGE_OUTPUT, ss.str().c_str()); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); //we should not have pulled a tag here. ASSERT_EQ(s3Client.m_getObjectCalled, 1u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); } TEST_F(CryptoModulesTest, StrictAuthenticatedEncryptionOperationsTestWithKMSWithContextEncryptionMaterials) { auto kmsClient = Aws::MakeShared(ALLOCATION_TAG, ClientConfiguration()); KMSWithContextEncryptionMaterials materials(TEST_CMK_ID, kmsClient); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::KMS_CONTEXT); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto getOutcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); AWS_ASSERT_SUCCESS(getOutcome); Aws::OStream& ostream = getOutcome.GetResult().GetBody(); Aws::OStringStream ss; ss << ostream.rdbuf(); ASSERT_STREQ(ss.str().c_str(), BODY_STREAM_TEST); ASSERT_EQ(getOutcome.GetResult().GetMetadata(), s3Client.GetMetadata()); ASSERT_EQ(s3Client.m_getObjectCalled, 2u); ASSERT_EQ(s3Client.m_putObjectCalled, 1u); ASSERT_EQ(kmsClient->m_genDataKeyCalledCount, 1u); ASSERT_EQ(kmsClient->m_decryptCalledCount, 1u); } TEST_F(CryptoModulesTest, StrictAERangeGet) { SimpleEncryptionMaterials materials(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()); CryptoConfiguration cryptoConfig(StorageMethod::METADATA, CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, GCM_TAG_LENGTH); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), GCM_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::GCM); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_KEY_WRAP); ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), cryptoConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); getRequest.SetRange(BYTES_SPECIFIER); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto outcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); ASSERT_FALSE(outcome.IsSuccess()); } TEST_F(CryptoModulesTest, StrictAEDecryptionFailure) { SimpleEncryptionMaterials materials(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()); CryptoConfiguration eoConfig(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); CryptoConfiguration strictAEConfig(StorageMethod::METADATA, CryptoMode::STRICT_AUTHENTICATED_ENCRYPTION); MockS3Client s3Client; CryptoModuleFactory factory; auto module = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), eoConfig); PutObjectRequest putRequest; putRequest.SetBucket(BUCKET_TEST_NAME); std::shared_ptr objectStream = Aws::MakeShared(ALLOCATION_TAG); *objectStream << BODY_STREAM_TEST; objectStream->flush(); putRequest.SetBody(objectStream); putRequest.SetKey(KEY_TEST_NAME); auto putObjectFunction = [&s3Client](Aws::S3::Model::PutObjectRequest iPutRequest) -> Aws::S3::Model::PutObjectOutcome { return s3Client.PutObject(iPutRequest); }; auto putOutcome = module->PutObjectSecurely(putRequest, putObjectFunction); AWS_ASSERT_SUCCESS(putOutcome); auto metadata = s3Client.GetMetadata(); MetadataFilled(metadata); size_t cryptoTagLength = static_cast(Aws::Utils::StringUtils::ConvertToInt64(metadata[CRYPTO_TAG_LENGTH_HEADER].c_str())); ASSERT_EQ(cryptoTagLength, 0u); Aws::Utils::CryptoBuffer ivBuffer = Aws::Utils::HashingUtils::Base64Decode(metadata[IV_HEADER]); ASSERT_EQ(ivBuffer.GetLength(), CBC_IV_SIZE_BYTES); ContentCryptoScheme scheme = ContentCryptoSchemeMapper::GetContentCryptoSchemeForName(metadata[CONTENT_CRYPTO_SCHEME_HEADER]); ASSERT_EQ(scheme, ContentCryptoScheme::CBC); KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithmMapper::GetKeyWrapAlgorithmForName(metadata[KEY_WRAP_ALGORITHM]); ASSERT_EQ(keyWrapAlgorithm, KeyWrapAlgorithm::AES_KEY_WRAP); //check to make sure content length is now padded since StrictAE appends the tag to the end of the body ASSERT_TRUE(s3Client.GetRequestContentLength() > strlen(BODY_STREAM_TEST)); auto decryptionModule = factory.FetchCryptoModule(Aws::MakeShared(ALLOCATION_TAG, materials), strictAEConfig); GetObjectRequest getRequest; getRequest.SetBucket(BUCKET_TEST_NAME); getRequest.SetKey(KEY_TEST_NAME); HeadObjectRequest headObject; headObject.WithBucket(BUCKET_TEST_NAME); headObject.WithKey(KEY_TEST_NAME); HeadObjectOutcome headOutcome = s3Client.HeadObject(headObject); Aws::S3Encryption::Handlers::MetadataHandler handler; ContentCryptoMaterial contentCryptoMaterial = handler.ReadContentCryptoMaterial(headOutcome.GetResult()); auto getObjectFunction = [&s3Client](Aws::S3::Model::GetObjectRequest iGetRequest) -> Aws::S3::Model::GetObjectOutcome { return s3Client.GetObject(iGetRequest); }; auto outcome = decryptionModule->GetObjectSecurely(getRequest, headOutcome.GetResult(), contentCryptoMaterial, getObjectFunction); ASSERT_FALSE(outcome.IsSuccess()); } TEST_F(CryptoModulesTest, RangeParserSuccess) { SimpleEncryptionMaterials materials(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()); CryptoConfiguration config(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); CryptoModuleFactory factory; int64_t contentLength = 90; Aws::Vector rangeOptions = { "bytes=10-20", "bytes=-20", "bytes=20-", "bytes=1-9" }; Aws::Vector> resultPairs = { std::make_pair(10LL, 20LL), std::make_pair(70LL, contentLength - 1), std::make_pair(20LL, contentLength - 1), std::make_pair(1LL, 9LL) }; for (size_t i = 0; i < rangeOptions.size(); ++i) { auto pair = CryptoModule::ParseGetObjectRequestRange(rangeOptions[i], contentLength); ASSERT_EQ(pair, resultPairs[i]); } } TEST_F(CryptoModulesTest, RangeParserFailure) { SimpleEncryptionMaterials materials(Aws::Utils::Crypto::SymmetricCipher::GenerateKey()); CryptoConfiguration config(StorageMethod::METADATA, CryptoMode::ENCRYPTION_ONLY); CryptoModuleFactory factory; int64_t contentLength = 90; Aws::Vector rangeOptions = { "bytes10-20", "bytes=20", "20=-", "bytes19" }; for (size_t i = 0; i < rangeOptions.size(); ++i) { auto pair = CryptoModule::ParseGetObjectRequestRange(rangeOptions[i], contentLength); ASSERT_EQ(pair, std::make_pair(static_cast(0), static_cast(0))); } } } #endif