Skip to content

Commit e0555e7

Browse files
Merge branch 'main' into rishav/slack-notification
2 parents 4cbbf36 + c751356 commit e0555e7

62 files changed

Lines changed: 698 additions & 526 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ jobs:
4545
shell: bash
4646

4747
- name: Test
48+
env:
49+
AWS_RETRY_MODE: adaptive
50+
AWS_MAX_ATTEMPTS: '5'
4851
run: |
4952
export AWS_S3EC_TEST_ALT_KMS_KEY_ARN=arn:aws:kms:${{ vars.CI_AWS_REGION }}:${{ secrets.CI_AWS_ACCOUNT_ID }}:key/${{ vars.CI_ALT_KMS_KEY_ID }}
5053
export AWS_S3EC_TEST_ALT_ROLE_ARN=arn:aws:iam::${{ secrets.CI_AWS_ACCOUNT_ID }}:role/service-role/${{ vars.CI_ALT_ROLE }}

.gitmodules

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
[submodule "specification"]
22
path = specification
3-
url = git@github.com:awslabs/private-aws-encryption-sdk-specification-staging.git
4-
branch = fire-egg-staging
3+
url = git@github.com:awslabs/aws-encryption-sdk-specification.git

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## [4.0.1](https://github.com/aws/aws-s3-encryption-client-java/compare/v4.0.0...v4.0.1) (2026-02-10)
4+
5+
### Fixes
6+
7+
* set instruction file content length ([b76c281](https://github.com/aws/aws-s3-encryption-client-java/commit/b76c2812b856eb1528eb83bbdf8d7e6ead80016e))
8+
9+
### Maintenance
10+
11+
* fix examples & spec path ([#493](https://github.com/aws/aws-s3-encryption-client-java/issues/493)) ([a95aa3f](https://github.com/aws/aws-s3-encryption-client-java/commit/a95aa3fddb5abf4e17551c0ef3c247c7a43edf40))
12+
313
## [4.0.0](https://github.com/aws/aws-s3-encryption-client-java/compare/v3.6.0...v4.0.0) (2025-12-17)
414

515
### ⚠ BREAKING CHANGES

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Example {
7979
}
8080
```
8181

82-
For detailed migration guidance and step-by-step examples, refer to the [Migration Examples](migration_examples/v3-to-v4/README.md). For more information, refer to the <a href="https://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/java-v4-migration.html">Developer Guide</a>.
82+
For detailed migration guidance and step-by-step examples, refer to the [Migration Examples](https://github.com/aws/amazon-s3-encryption-client-java/tree/main/migration_examples/v3-to-v4). For more information, refer to the <a href="https://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/java-v4-migration.html">Developer Guide</a>.
8383

8484

8585
#### V2 KMS Materials Provider to V4

migration_examples/v3-to-v4/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# S3 Encryption Client v3 to v4 Migration Examples
22

3-
> **Note:** This directory contains migration-specific examples for users upgrading from v3 to v4. If you're starting fresh with the S3 Encryption Client, see the [code examples](../../../src/examples/java/software/amazon/encryption/s3/examples).
3+
> **Note:** This directory contains migration-specific examples for users upgrading from v3 to v4. If you're starting fresh with the S3 Encryption Client, see the [code examples](https://github.com/aws/amazon-s3-encryption-client-java/tree/main/src/examples/java/software/amazon/encryption/s3/examples).
44
55
This directory contains examples demonstrating the migration path from S3 Encryption Client v3 to v4, focusing on different commitment policy configurations. For more information, refer to the <a href="https://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/java-v4-migration.html">Developer Guide</a>.
66

migration_examples/v3-to-v4/v4/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<maven.compiler.target>8</maven.compiler.target>
1818
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1919
<aws.sdk.version>2.31.14</aws.sdk.version>
20-
<s3ec.version>4.0.0</s3ec.version>
20+
<s3ec.version>4.0.1</s3ec.version>
2121
</properties>
2222

2323
<dependencies>

pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>software.amazon.encryption.s3</groupId>
88
<artifactId>amazon-s3-encryption-client-java</artifactId>
9-
<version>4.0.0</version>
9+
<version>4.0.1</version>
1010
<packaging>jar</packaging>
1111

1212
<name>Amazon S3 Encryption Client</name>
@@ -120,6 +120,12 @@
120120

121121
<!-- Test Dependencies -->
122122
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
123+
<dependency>
124+
<groupId>org.junit-pioneer</groupId>
125+
<artifactId>junit-pioneer</artifactId>
126+
<version>1.9.1</version>
127+
<scope>test</scope>
128+
</dependency>
123129
<dependency>
124130
<groupId>org.mockito</groupId>
125131
<artifactId>mockito-core</artifactId>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package software.amazon.encryption.s3.examples;
2+
3+
import java.security.NoSuchAlgorithmException;
4+
5+
import software.amazon.awssdk.core.ResponseBytes;
6+
import software.amazon.awssdk.core.sync.RequestBody;
7+
import software.amazon.awssdk.services.kms.KmsClient;
8+
import software.amazon.awssdk.services.s3.S3Client;
9+
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
10+
import software.amazon.encryption.s3.S3EncryptionClient;
11+
import software.amazon.encryption.s3.S3EncryptionClientException;
12+
import software.amazon.encryption.s3.internal.InstructionFileConfig;
13+
import software.amazon.encryption.s3.materials.KmsKeyring;
14+
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
import static org.junit.jupiter.api.Assertions.assertTrue;
17+
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.appendTestSuffix;
18+
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.deleteObject;
19+
20+
public class InstructionFileExample {
21+
22+
public static void main(final String[] args) throws NoSuchAlgorithmException {
23+
final String bucket = args[0];
24+
final String kmsKeyId = args.length > 1 ? args[1] : null;
25+
26+
if (kmsKeyId != null) {
27+
InstructionFileExample.simpleKmsKeyringUseInstructionFile(bucket, kmsKeyId);
28+
}
29+
}
30+
/**
31+
* This example demonstrates using Instruction Files.
32+
*
33+
* @param bucket The name of the Amazon S3 bucket to perform operations on.
34+
* @param kmsKeyId The KMS key ID used for encryption
35+
*/
36+
public static void simpleKmsKeyringUseInstructionFile(
37+
final String bucket,
38+
final String kmsKeyId
39+
) {
40+
// Set up the S3 object key and content to be encrypted
41+
final String objectKey = appendTestSuffix(
42+
"kms-instruction-file-test"
43+
);
44+
final String input =
45+
"Testing encryption of instruction file with KMS Keyring";
46+
47+
// Create a KMS client for key operations
48+
KmsClient kmsClient = KmsClient.create();
49+
50+
// Create the original KMS keyring with the first KMS key
51+
KmsKeyring originalKeyring = KmsKeyring
52+
.builder()
53+
.kmsClient(kmsClient)
54+
.wrappingKeyId(kmsKeyId)
55+
.build();
56+
57+
// Create a default S3 client for instruction file operations
58+
S3Client wrappedClient = S3Client.create();
59+
60+
// Create the S3 Encryption Client with instruction file support enabled
61+
// The client can perform both putObject and getObject operations using the KMS key
62+
ResponseBytes<GetObjectResponse> decryptedObject;
63+
try (S3EncryptionClient s3ec = S3EncryptionClient
64+
.builderV4()
65+
.keyring(originalKeyring)
66+
.instructionFileConfig(
67+
InstructionFileConfig
68+
.builder()
69+
.instructionFileClient(wrappedClient)
70+
.enableInstructionFilePutObject(true)
71+
.build()
72+
).build()) {
73+
74+
// Upload both the encrypted object and instruction file to the specified bucket in S3
75+
s3ec.putObject(
76+
builder -> builder.bucket(bucket).key(objectKey).build(),
77+
RequestBody.fromString(input)
78+
);
79+
80+
// Verify that the client can successfully decrypt the object
81+
decryptedObject = s3ec.getObjectAsBytes(builder ->
82+
builder.bucket(bucket).key(objectKey).build()
83+
);
84+
// Assert that the decrypted object's content matches the original input
85+
assertEquals(input, decryptedObject.asUtf8String());
86+
87+
// Call deleteObject to delete the object and instruction file
88+
// from given S3 Bucket
89+
deleteObject(bucket, objectKey, s3ec);
90+
}
91+
}
92+
}

src/test/java/software/amazon/encryption/s3/AdditionalDecryptionKeyMaterialTest.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
package software.amazon.encryption.s3;
44

55
import org.junit.jupiter.api.BeforeAll;
6-
import org.junit.jupiter.api.Test;
6+
import org.junitpioneer.jupiter.RetryingTest;
77
import software.amazon.awssdk.core.ResponseBytes;
88
import software.amazon.awssdk.core.sync.RequestBody;
99
import software.amazon.awssdk.services.s3.S3Client;
@@ -65,7 +65,7 @@ public static void setUp() throws NoSuchAlgorithmException {
6565
* Test AES keyring with null additionalDecryptionKeyMaterial map.
6666
* This tests the default behavior when no additional key material is provided.
6767
*/
68-
@Test
68+
@RetryingTest(3)
6969
public void testAesKeyringWithNullAdditionalKeyMaterial() {
7070
final String objectKey = appendTestSuffix("aes-null-additional-key-material");
7171
final String input = "AES with null additional key material";
@@ -129,7 +129,7 @@ public void testAesKeyringWithNullAdditionalKeyMaterial() {
129129
* Test AES keyring with empty additionalDecryptionKeyMaterial map.
130130
* This tests the behavior when an empty map is provided.
131131
*/
132-
@Test
132+
@RetryingTest(3)
133133
public void testAesKeyringWithEmptyAdditionalKeyMaterial() {
134134
final String objectKey = appendTestSuffix("aes-empty-additional-key-material");
135135
final String input = "AES with empty additional key material";
@@ -194,7 +194,7 @@ public void testAesKeyringWithEmptyAdditionalKeyMaterial() {
194194
* Test AES keyring with a singleton additionalDecryptionKeyMaterial map.
195195
* This tests the behavior when a single additional key material is provided.
196196
*/
197-
@Test
197+
@RetryingTest(3)
198198
public void testAesKeyringWithSingletonAdditionalKeyMaterial() {
199199
final String objectKey = appendTestSuffix("aes-singleton-additional-key-material");
200200
final String input = "AES with singleton additional key material";
@@ -265,7 +265,7 @@ public void testAesKeyringWithSingletonAdditionalKeyMaterial() {
265265
* Test AES keyring with multiple entries in the additionalDecryptionKeyMaterial map.
266266
* This tests the behavior when multiple additional key materials are provided.
267267
*/
268-
@Test
268+
@RetryingTest(3)
269269
public void testAesKeyringWithMultipleAdditionalKeyMaterials() {
270270
final String objectKey = appendTestSuffix("aes-multiple-additional-key-materials");
271271
final String input = "AES with multiple additional key materials";
@@ -348,7 +348,7 @@ public void testAesKeyringWithMultipleAdditionalKeyMaterials() {
348348
* Test AES keyring with additionalDecryptionKeyMaterial that doesn't match.
349349
* This tests the behavior when no matching key material is found and it should fall back to the default key.
350350
*/
351-
@Test
351+
@RetryingTest(3)
352352
public void testAesKeyringWithNonMatchingAdditionalKeyMaterial() {
353353
final String objectKey = appendTestSuffix("aes-non-matching-additional-key-material");
354354
final String input = "AES with non-matching additional key material";
@@ -423,7 +423,7 @@ public void testAesKeyringWithNonMatchingAdditionalKeyMaterial() {
423423
* Test AES keyring with additionalDecryptionKeyMaterial that doesn't match and a wrong default key.
424424
* This tests the behavior when no matching key material is found and the default key is also wrong.
425425
*/
426-
@Test
426+
@RetryingTest(3)
427427
public void testAesKeyringWithNonMatchingAdditionalKeyMaterialAndWrongDefaultKey() {
428428
final String objectKey = appendTestSuffix("aes-non-matching-additional-key-material-wrong-default");
429429
final String input = "AES with non-matching additional key material and wrong default key";
@@ -494,7 +494,7 @@ public void testAesKeyringWithNonMatchingAdditionalKeyMaterialAndWrongDefaultKey
494494
* Test RSA keyring with null additionalDecryptionKeyMaterial map.
495495
* This tests the default behavior when no additional key material is provided.
496496
*/
497-
@Test
497+
@RetryingTest(3)
498498
public void testRsaKeyringWithNullAdditionalKeyMaterial() {
499499
final String objectKey = appendTestSuffix("rsa-null-additional-key-material");
500500
final String input = "RSA with null additional key material";
@@ -564,7 +564,7 @@ public void testRsaKeyringWithNullAdditionalKeyMaterial() {
564564
* Test RSA keyring with empty additionalDecryptionKeyMaterial map.
565565
* This tests the behavior when an empty map is provided.
566566
*/
567-
@Test
567+
@RetryingTest(3)
568568
public void testRsaKeyringWithEmptyAdditionalKeyMaterial() {
569569
final String objectKey = appendTestSuffix("rsa-empty-additional-key-material");
570570
final String input = "RSA with empty additional key material";
@@ -635,7 +635,7 @@ public void testRsaKeyringWithEmptyAdditionalKeyMaterial() {
635635
* Test RSA keyring with a singleton additionalDecryptionKeyMaterial map.
636636
* This tests the behavior when a single additional key material is provided.
637637
*/
638-
@Test
638+
@RetryingTest(3)
639639
public void testRsaKeyringWithSingletonAdditionalKeyMaterial() {
640640
final String objectKey = appendTestSuffix("rsa-singleton-additional-key-material");
641641
final String input = "RSA with singleton additional key material";
@@ -715,7 +715,7 @@ public void testRsaKeyringWithSingletonAdditionalKeyMaterial() {
715715
* Test RSA keyring with multiple entries in the additionalDecryptionKeyMaterial map.
716716
* This tests the behavior when multiple additional key materials are provided.
717717
*/
718-
@Test
718+
@RetryingTest(3)
719719
public void testRsaKeyringWithMultipleAdditionalKeyMaterials() {
720720
final String objectKey = appendTestSuffix("rsa-multiple-additional-key-materials");
721721
final String input = "RSA with multiple additional key materials";
@@ -810,7 +810,7 @@ public void testRsaKeyringWithMultipleAdditionalKeyMaterials() {
810810
* Test RSA keyring with additionalDecryptionKeyMaterial that doesn't match.
811811
* This tests the behavior when no matching key material is found and it should fall back to the default key.
812812
*/
813-
@Test
813+
@RetryingTest(3)
814814
public void testRsaKeyringWithNonMatchingAdditionalKeyMaterial() {
815815
final String objectKey = appendTestSuffix("rsa-non-matching-additional-key-material");
816816
final String input = "RSA with non-matching additional key material";
@@ -894,7 +894,7 @@ public void testRsaKeyringWithNonMatchingAdditionalKeyMaterial() {
894894
* Test RSA keyring with additionalDecryptionKeyMaterial that doesn't match and a wrong default key.
895895
* This tests the behavior when no matching key material is found and the default key is also wrong.
896896
*/
897-
@Test
897+
@RetryingTest(3)
898898
public void testRsaKeyringWithNonMatchingAdditionalKeyMaterialAndWrongDefaultKey() {
899899
final String objectKey = appendTestSuffix("rsa-non-matching-additional-key-material-wrong-default");
900900
final String input = "RSA with non-matching additional key material and wrong default key";

0 commit comments

Comments
 (0)