From e71d2fde08f33b57b54638ca550ef8bc8522af90 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 19 May 2026 12:41:50 -0700 Subject: [PATCH 01/11] m --- .../encryption/s3/S3EncryptionClientTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index ea46b7e1d..ac5e6e0d9 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -42,6 +42,7 @@ import software.amazon.encryption.s3.algorithms.AlgorithmSuite; import software.amazon.encryption.s3.internal.InstructionFileConfig; import software.amazon.encryption.s3.internal.MetadataKeyConstants; +import software.amazon.encryption.s3.materials.AesKeyring; import software.amazon.encryption.s3.materials.CryptographicMaterialsManager; import software.amazon.encryption.s3.materials.DefaultCryptoMaterialsManager; import software.amazon.encryption.s3.materials.KmsKeyring; @@ -52,6 +53,7 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; @@ -964,6 +966,32 @@ public void s3EncryptionClientTopLevelCredentialsWrongRegion() { } } + @RetryingTest(3) + public void crossRegionRoundTrip() { + final String objectKey = appendTestSuffix("cross-region-test"); + SecretKeySpec aesKey = new SecretKeySpec(new byte[32], "AES"); + AesKeyring keyRing = AesKeyring.builder().wrappingKey(aesKey).build(); + + S3Client s3 = S3EncryptionClient.builderV4() + .region(Region.EU_CENTRAL_1) + .crossRegionAccessEnabled(true) + .keyring(keyRing) + .build(); + + try { + PutObjectRequest request = PutObjectRequest.builder().bucket(BUCKET).key(objectKey).build(); + s3.putObject(request, RequestBody.fromBytes("test".getBytes())); + ResponseBytes response = s3.getObjectAsBytes(builder -> builder + .bucket(BUCKET) + .key(objectKey) + .build()); + assertEquals("test", response.asUtf8String()); + } finally { + deleteObject(BUCKET, objectKey, s3); + s3.close(); + } + } + @RetryingTest(3) public void s3EncryptionClientTopLevelCredentialsNullCreds() { final String objectKey = appendTestSuffix("wrapped-s3-client-with-null-credentials"); From 5a81feb7906e40800d8211d3c696b053cb2c94f1 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 19 May 2026 12:42:04 -0700 Subject: [PATCH 02/11] empty commit From 12a2e1362e57ee2a8454a3205190563bb32a5138 Mon Sep 17 00:00:00 2001 From: Rishav karanjit Date: Tue, 19 May 2026 14:48:22 -0700 Subject: [PATCH 03/11] Update pom.xml to have AWS SDK v2.43.0 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index de793bbb9..bb2451d6c 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ software.amazon.awssdk bom - 2.31.14 + 2.43.0 true pom import @@ -68,13 +68,13 @@ software.amazon.awssdk s3 - 2.31.14 + 2.43.0 software.amazon.awssdk kms - 2.31.14 + 2.43.0 @@ -169,7 +169,7 @@ software.amazon.awssdk sts - 2.31.14 + 2.43.0 true test From c078643f60681b252fda4671aba9aeb2db91f423 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 19 May 2026 15:45:50 -0700 Subject: [PATCH 04/11] m --- .../s3/internal/PutEncryptedObjectPipeline.java | 2 +- .../encryption/s3/S3EncryptionClientTest.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/software/amazon/encryption/s3/internal/PutEncryptedObjectPipeline.java b/src/main/java/software/amazon/encryption/s3/internal/PutEncryptedObjectPipeline.java index fb2ddbae3..96be243d3 100644 --- a/src/main/java/software/amazon/encryption/s3/internal/PutEncryptedObjectPipeline.java +++ b/src/main/java/software/amazon/encryption/s3/internal/PutEncryptedObjectPipeline.java @@ -84,7 +84,7 @@ public CompletableFuture putObject(PutObjectRequest request, .overrideConfiguration(API_NAME_INTERCEPTOR) .contentLength(encryptedContent.getCiphertextLength()) .build(); - return _s3AsyncClient.putObject(encryptedPutRequest, encryptedContent.getAsyncCiphertext()); + return _s3AsyncClient.putObject(encryptedPutRequest, new NoRetriesAsyncRequestBody(encryptedContent.getAsyncCiphertext())); } public static class Builder { diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index ac5e6e0d9..f614b8dfb 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -17,6 +17,7 @@ import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junitpioneer.jupiter.RetryingTest; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; @@ -966,7 +967,7 @@ public void s3EncryptionClientTopLevelCredentialsWrongRegion() { } } - @RetryingTest(3) + @Test public void crossRegionRoundTrip() { final String objectKey = appendTestSuffix("cross-region-test"); SecretKeySpec aesKey = new SecretKeySpec(new byte[32], "AES"); @@ -980,14 +981,12 @@ public void crossRegionRoundTrip() { try { PutObjectRequest request = PutObjectRequest.builder().bucket(BUCKET).key(objectKey).build(); - s3.putObject(request, RequestBody.fromBytes("test".getBytes())); - ResponseBytes response = s3.getObjectAsBytes(builder -> builder - .bucket(BUCKET) - .key(objectKey) - .build()); - assertEquals("test", response.asUtf8String()); + S3EncryptionClientException ex = assertThrows(S3EncryptionClientException.class, () -> + s3.putObject(request, RequestBody.fromBytes("test".getBytes()))); + // Cross-region redirect causes the SDK to re-subscribe to the request body. + // NoRetriesAsyncRequestBody blocks this to prevent GCM cipher key/IV reuse. + assertTrue(ex.getMessage().contains("Re-subscription is not supported")); } finally { - deleteObject(BUCKET, objectKey, s3); s3.close(); } } From 0bd24f45e20d41a50359dc90d9041ea026062345 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 19 May 2026 15:55:05 -0700 Subject: [PATCH 05/11] m --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb2451d6c..c1e07da23 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ software.amazon.awssdk.crt aws-crt true - 0.37.0 + 0.41.0 From c4c362aa6b18cadb7ac639041d6d936a385098a0 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 19 May 2026 16:01:53 -0700 Subject: [PATCH 06/11] m --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c1e07da23..98159fd1d 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ software.amazon.awssdk.crt aws-crt true - 0.41.0 + 0.45.1 From 9522261101b09d00c7d6c9d016f5ab5ef6edc216 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 19 May 2026 16:09:04 -0700 Subject: [PATCH 07/11] m --- .../software/amazon/encryption/s3/S3EncryptionClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index f614b8dfb..c60c21fe9 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -984,7 +984,7 @@ public void crossRegionRoundTrip() { S3EncryptionClientException ex = assertThrows(S3EncryptionClientException.class, () -> s3.putObject(request, RequestBody.fromBytes("test".getBytes()))); // Cross-region redirect causes the SDK to re-subscribe to the request body. - // NoRetriesAsyncRequestBody blocks this to prevent GCM cipher key/IV reuse. + // S3EC blocks this to prevent GCM cipher key/IV reuse. assertTrue(ex.getMessage().contains("Re-subscription is not supported")); } finally { s3.close(); From 0a5be43d1e760090af504ded1843d0f593a9d26f Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 20 May 2026 10:03:16 -0700 Subject: [PATCH 08/11] m --- .../s3/S3AsyncEncryptionClientTest.java | 26 +++++++++++++++++++ .../encryption/s3/S3EncryptionClientTest.java | 6 ++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java index 4a9aa9483..1adbfe6af 100644 --- a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java @@ -46,6 +46,7 @@ import software.amazon.awssdk.services.s3.multipart.MultipartConfiguration; import software.amazon.encryption.s3.algorithms.AlgorithmSuite; import software.amazon.encryption.s3.internal.InstructionFileConfig; +import software.amazon.encryption.s3.materials.AesKeyring; import software.amazon.encryption.s3.materials.KmsKeyring; import software.amazon.encryption.s3.utils.BoundedInputStream; import software.amazon.encryption.s3.utils.S3EncryptionClientTestResources; @@ -53,6 +54,7 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchAlgorithmException; @@ -349,6 +351,30 @@ public void asyncTopLevelConfigurationWrongRegion() { } } + @RetryingTest(3) + public void roundTripWithCrossRegionAccessEnabled() { + final String objectKey = appendTestSuffix("roundTripWithCrossRegionAccessEnabled-async-s3ec"); + SecretKeySpec aesKey = new SecretKeySpec(new byte[32], "AES"); + AesKeyring keyRing = AesKeyring.builder().wrappingKey(aesKey).build(); + + S3AsyncClient s3Client = S3AsyncEncryptionClient.builderV4() + .region(Region.EU_CENTRAL_1) + .crossRegionAccessEnabled(true) + .keyring(keyRing) + .build(); + + try { + PutObjectRequest request = PutObjectRequest.builder().bucket(BUCKET).key(objectKey).build(); + S3EncryptionClientException ex = assertThrows(S3EncryptionClientException.class, () -> + s3Client.putObject(request, AsyncRequestBody.fromBytes("test".getBytes())).join()); + // Cross-region redirect causes the SDK to re-subscribe to the request body. + // NoRetriesAsyncRequestBody blocks this to prevent GCM cipher key/IV reuse. + assertTrue(ex.getMessage().contains("Re-subscription is not supported")); + } finally { + s3Client.close(); + } + } + @RetryingTest(3) public void asyncTopLevelConfigurationNullCreds() { final String objectKey = appendTestSuffix("wrapped-s3-client-with-null-credentials-async"); diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index c60c21fe9..526b2e6eb 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -967,9 +967,9 @@ public void s3EncryptionClientTopLevelCredentialsWrongRegion() { } } - @Test - public void crossRegionRoundTrip() { - final String objectKey = appendTestSuffix("cross-region-test"); + @RetryingTest(3) + public void roundTripWithCrossRegionAccessEnabled() { + final String objectKey = appendTestSuffix("roundTripWithCrossRegionAccessEnabled-sync-s3ec"); SecretKeySpec aesKey = new SecretKeySpec(new byte[32], "AES"); AesKeyring keyRing = AesKeyring.builder().wrappingKey(aesKey).build(); From 961b26090906344c8513e1735d8bc9786a6261c4 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 20 May 2026 12:30:29 -0700 Subject: [PATCH 09/11] m --- .../software/amazon/encryption/s3/S3EncryptionClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index 526b2e6eb..94948eb53 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -985,7 +985,7 @@ public void roundTripWithCrossRegionAccessEnabled() { s3.putObject(request, RequestBody.fromBytes("test".getBytes()))); // Cross-region redirect causes the SDK to re-subscribe to the request body. // S3EC blocks this to prevent GCM cipher key/IV reuse. - assertTrue(ex.getMessage().contains("Re-subscription is not supported")); + assertTrue(ex.getCause().getMessage().contains("Re-subscription is not supported")); } finally { s3.close(); } From da9b68486839ecddcc44736bb152bc49f7b87e2e Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 20 May 2026 12:50:29 -0700 Subject: [PATCH 10/11] m --- .../amazon/encryption/s3/S3AsyncEncryptionClientTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java index 1adbfe6af..141e3f5ca 100644 --- a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java @@ -365,11 +365,12 @@ public void roundTripWithCrossRegionAccessEnabled() { try { PutObjectRequest request = PutObjectRequest.builder().bucket(BUCKET).key(objectKey).build(); - S3EncryptionClientException ex = assertThrows(S3EncryptionClientException.class, () -> + CompletionException ex = assertThrows(CompletionException.class, () -> s3Client.putObject(request, AsyncRequestBody.fromBytes("test".getBytes())).join()); // Cross-region redirect causes the SDK to re-subscribe to the request body. // NoRetriesAsyncRequestBody blocks this to prevent GCM cipher key/IV reuse. - assertTrue(ex.getMessage().contains("Re-subscription is not supported")); + assertTrue(ex.getCause() instanceof S3EncryptionClientException); + assertTrue(ex.getCause().getMessage().contains("Re-subscription is not supported")); } finally { s3Client.close(); } From 9c5321807886cefaea32731ed155a3bd1dbef83f Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 20 May 2026 14:43:25 -0700 Subject: [PATCH 11/11] m --- .../software/amazon/encryption/s3/S3EncryptionClientTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java index 94948eb53..356ddbdff 100644 --- a/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3EncryptionClientTest.java @@ -17,7 +17,6 @@ import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junitpioneer.jupiter.RetryingTest; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;