From 06ff2644ed7106eed56f5a130e652b66f891b8cf Mon Sep 17 00:00:00 2001 From: okruitho Date: Thu, 10 Sep 2026 18:02:43 +0200 Subject: [PATCH 1/2] Added test where no expiration on credentials fails to report the correct value for isExpired --- .../aws/auth/CrtCredentialsProviderTest.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp b/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp index 265a9f16c5cf..81d43aee5e68 100644 --- a/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp +++ b/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -104,6 +105,21 @@ class AsyncMockedCredsProvider : public Aws::Auth::CrtCredentialsProvider { class CrtCredentialsProviderTest : public Aws::Testing::AwsCppSdkGTestSuite {}; +TEST_F(CrtCredentialsProviderTest, NonExpiringCredentialsMustNotBeExpired) { + auto underlying_mock = Aws::MakeShared(CRT_CREDS_TEST_LOG); + + underlying_mock->AddCredentialForReturn(Aws::MakeShared( + CRT_CREDS_TEST_LOG, Aws::Crt::ByteCursorFromCString("access"), Aws::Crt::ByteCursorFromCString("secret"), + Aws::Crt::ByteCursorFromCString(""), std::numeric_limits::max())); + + MockedCredsProvider provider(underlying_mock); + const auto credentials = provider.GetAWSCredentials(); + + EXPECT_FALSE(credentials.IsEmpty()); + EXPECT_FALSE(credentials.IsExpired()); + EXPECT_FALSE(credentials.IsExpiredOrEmpty()); +} + TEST_F(CrtCredentialsProviderTest, ShouldNotUseFreedStateWhenRefreshOutlivesTimeout) { auto crtCreds = Aws::MakeShared( CRT_CREDS_TEST_LOG, Aws::Crt::ByteCursorFromCString("access"), Aws::Crt::ByteCursorFromCString("secret"), From f88d70efa5a0bc1d09b149fb3195f672840e3521 Mon Sep 17 00:00:00 2001 From: okruitho Date: Thu, 10 Sep 2026 18:09:41 +0200 Subject: [PATCH 2/2] Fixed bug where non-expiry would fail to return true on IsExpired --- .../source/auth/CrtCredentialsProvider.cpp | 8 ++++++-- .../aws/auth/CrtCredentialsProviderTest.cpp | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/aws-cpp-sdk-core/source/auth/CrtCredentialsProvider.cpp b/src/aws-cpp-sdk-core/source/auth/CrtCredentialsProvider.cpp index f58deb94c41a..3a7eb8fabb3b 100644 --- a/src/aws-cpp-sdk-core/source/auth/CrtCredentialsProvider.cpp +++ b/src/aws-cpp-sdk-core/source/auth/CrtCredentialsProvider.cpp @@ -9,6 +9,7 @@ #include #include +#include #include using namespace Aws::Auth; @@ -99,8 +100,11 @@ AWSCredentials CrtCredentialsProvider::ExtractCredentialsFromCrt(const Aws::Crt: credentials.SetAWSAccessKeyId({reinterpret_cast(accountIdCursor.ptr), accountIdCursor.len}); const auto secretKeyCursor = crtCredentials.GetSecretAccessKey(); credentials.SetAWSSecretKey({reinterpret_cast(secretKeyCursor.ptr), secretKeyCursor.len}); - const auto expiration = crtCredentials.GetExpirationTimepointInSeconds(); - credentials.SetExpiration(DateTime{static_cast(expiration)}); + const uint64_t expiration = crtCredentials.GetExpirationTimepointInSeconds(); + // CRT uses UINT64_MAX for no expiration; preserve AWSCredentials' non-expiring default. + if (expiration != (std::numeric_limits::max)()) { + credentials.SetExpiration(DateTime{expiration}); + } const auto sessionTokenCursor = crtCredentials.GetSessionToken(); credentials.SetSessionToken({reinterpret_cast(sessionTokenCursor.ptr), sessionTokenCursor.len}); return credentials; diff --git a/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp b/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp index 81d43aee5e68..05c082a7a448 100644 --- a/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp +++ b/tests/aws-cpp-sdk-core-tests/aws/auth/CrtCredentialsProviderTest.cpp @@ -118,6 +118,24 @@ TEST_F(CrtCredentialsProviderTest, NonExpiringCredentialsMustNotBeExpired) { EXPECT_FALSE(credentials.IsEmpty()); EXPECT_FALSE(credentials.IsExpired()); EXPECT_FALSE(credentials.IsExpiredOrEmpty()); + EXPECT_EQ(credentials.GetExpiration(), Aws::Auth::AWSCredentials{}.GetExpiration()); + EXPECT_FALSE(provider.GetAWSCredentials().IsExpiredOrEmpty()); + EXPECT_EQ(underlying_mock->GetNumCalls(), 1); +} + +TEST_F(CrtCredentialsProviderTest, ShouldPreserveFiniteExpiration) { + auto underlying_mock = Aws::MakeShared(CRT_CREDS_TEST_LOG); + const auto expiration = (Aws::Utils::DateTime::Now() + std::chrono::minutes(100)).Seconds(); + + underlying_mock->AddCredentialForReturn(Aws::MakeShared( + CRT_CREDS_TEST_LOG, Aws::Crt::ByteCursorFromCString("access"), Aws::Crt::ByteCursorFromCString("secret"), + Aws::Crt::ByteCursorFromCString("token"), static_cast(expiration))); + + MockedCredsProvider provider(underlying_mock); + const auto credentials = provider.GetAWSCredentials(); + + EXPECT_EQ(credentials.GetExpiration().Seconds(), expiration); + EXPECT_FALSE(credentials.IsExpiredOrEmpty()); } TEST_F(CrtCredentialsProviderTest, ShouldNotUseFreedStateWhenRefreshOutlivesTimeout) {