Skip to content

Commit a4dc46f

Browse files
chore: enable java-v3-transition test server (#70)
* chore: s3ec v3 transtion and v4 improved tests * comment cpp checkout * bump s3ec-java commits * chore: add duvet reports for s3ec-java (transition & improved) * format * git-ignore * update java submodule * fix configuration * Revert "chore: reenable c++ (#52)" This reverts commit 8c6db9e. * remove java transiton for now * fix configuration * fix configuration * Update test configuration * Duvet * Rebase * nit - format * Change java-v4-port * duvet changes * Dotnet change * remove symlink * Fix Tests * chore: enable java-v3-transition test server * chore: enable java-v3-transition test server * update .gitmodule branch * Merge Conflicts * chore: update client configuration to allow for default. * point iv's changes commit * Apply suggestion from @rishav-karanjit Co-authored-by: Rishav karanjit <karanjitrishav4@gmail.com> * allow java * fix duvet --------- Co-authored-by: Rishav karanjit <karanjitrishav4@gmail.com>
1 parent d948160 commit a4dc46f

19 files changed

Lines changed: 507 additions & 511 deletions

File tree

.github/workflows/test.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,27 +156,27 @@ jobs:
156156
aws-region: us-west-2
157157

158158
- name: Build the servers
159-
run: cd test-server && make build-all-servers FILTER=ruby,go,cpp,php
159+
run: cd test-server && make build-all-servers FILTER=ruby,go,cpp,php,java
160160
env:
161161
MAKEFLAGS: -j${{ steps.cpu-count.outputs.count }}
162162
AWS_REGION: us-west-2
163163

164164
- name: Start the servers
165-
run: cd test-server && make start-all-servers FILTER=ruby,go,cpp,php
165+
run: cd test-server && make start-all-servers FILTER=ruby,go,cpp,php,java
166166
env:
167167
AWS_REGION: us-west-2
168168
TEST_SERVER_S3_BUCKET: ${{ vars.TEST_SERVER_S3_BUCKET }}
169169
TEST_SERVER_KMS_KEY_ARN: ${{ vars.TEST_SERVER_KMS_KEY_ARN }}
170170

171171
- name: Wait for servers to start
172-
run: cd test-server && make wait-all-servers FILTER=ruby,go,cpp,php
172+
run: cd test-server && make wait-all-servers FILTER=ruby,go,cpp,php,java
173173
env:
174174
AWS_REGION: us-west-2
175175
TEST_SERVER_S3_BUCKET: ${{ vars.TEST_SERVER_S3_BUCKET }}
176176
TEST_SERVER_KMS_KEY_ARN: ${{ vars.TEST_SERVER_KMS_KEY_ARN }}
177177

178178
- name: Run run-tests
179-
run: cd test-server && make run-tests FILTER=ruby,go,cpp,php
179+
run: cd test-server && make run-tests FILTER=ruby,go,cpp,php,java
180180
env:
181181
AWS_REGION: us-west-2
182182
TEST_SERVER_S3_BUCKET: ${{ vars.TEST_SERVER_S3_BUCKET }}
@@ -194,7 +194,7 @@ jobs:
194194
test-server/*/net-v3-server.log
195195
196196
- name: Stop the servers
197-
run: cd test-server && make stop-servers FILTER=ruby,go,cpp,php
197+
run: cd test-server && make stop-servers FILTER=ruby,go,cpp,php,java
198198

199199
- name: Upload results
200200
if: always()

.gitmodules

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818
[submodule "test-server/java-v3-transition-server/s3ec-staging"]
1919
path = test-server/java-v3-transition-server/s3ec-staging
2020
url = git@github.com:aws/private-amazon-s3-encryption-client-java-staging.git
21-
branch = imabhichow/s3ec-transition
21+
branch = imabhichow/transition-read-kc
2222
[submodule "test-server/java-v4-server/s3ec-staging"]
2323
path = test-server/java-v4-server/s3ec-staging
2424
url = git@github.com:aws/private-amazon-s3-encryption-client-java-staging.git
2525
branch = imabhichow/add-kc
26-
; branch = s3ec/improved
2726
[submodule "test-server/specification"]
2827
path = test-server/specification
2928
url = git@github.com:awslabs/private-aws-encryption-sdk-specification-staging.git

test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public class TestUtils {
134134

135135
public static final Set<String> TRANSITION_VERSIONS =
136136
Set.of(
137-
// JAVA_V3_TRANSITION,
137+
JAVA_V3_TRANSITION,
138138
GO_V3_TRANSITION,
139139
// NET_V2_TRANSITION,
140140
NET_V3_TRANSITION,
@@ -172,8 +172,7 @@ public class TestUtils {
172172
servers.put(NET_V4, new LanguageServerTarget(NET_V4, "8090"));
173173
servers.put(RUBY_V3, new LanguageServerTarget(RUBY_V3, "8092"));
174174
servers.put(PHP_V3, new LanguageServerTarget(PHP_V3, "8093"));
175-
// TODO: Create and add transition servers
176-
// servers.put(JAVA_V3_TRANSITION, new LanguageServerTarget(JAVA_V3_TRANSITION, "8094"));
175+
servers.put(JAVA_V3_TRANSITION, new LanguageServerTarget(JAVA_V3_TRANSITION, "8094"));
177176
servers.put(GO_V3_TRANSITION, new LanguageServerTarget(GO_V3_TRANSITION, "8095"));
178177
// servers.put(NET_V2_TRANSITION, new LanguageServerTarget(NET_V2_TRANSITION, "8096"));
179178
servers.put(RUBY_V2_TRANSITION, new LanguageServerTarget(RUBY_V2_TRANSITION, "8098"));

test-server/java-v3-server/.duvet/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'$schema' = "https://awslabs.github.io/duvet/config/v0.4.0.json"
22

33
[[source]]
4-
pattern = "s3ec-staging/*.java"
4+
pattern = "s3ec-staging/**/*.java"
55

66
# Include required specifications here
77
[[specification]]

test-server/java-v3-transition-server/.duvet/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'$schema' = "https://awslabs.github.io/duvet/config/v0.4.0.json"
22

33
[[source]]
4-
pattern = "s3ec-staging/*.java"
4+
pattern = "s3ec-staging/**/*.java"
55

66
# Include required specifications here
77
[[specification]]

test-server/java-v3-transition-server/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ dependencies {
1414
implementation("software.amazon.smithy.java:aws-server-restjson:$smithyJavaVersion")
1515

1616
// S3EC from local Maven repository (installed by mvn install)
17-
implementation("software.amazon.encryption.s3:amazon-s3-encryption-client-java:3.4.0-TRANSITION")
17+
implementation("software.amazon.encryption.s3:amazon-s3-encryption-client-java:3.4.0-read-kc")
1818
}
1919

2020
// Use that application plugin to start the service via the `run` task.
Lines changed: 136 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package software.amazon.encryption.s3;
22

33
import software.amazon.awssdk.services.s3.S3Client;
4-
import software.amazon.encryption.s3.algorithms.AlgorithmSuite;
54
import software.amazon.encryption.s3.internal.InstructionFileConfig;
6-
import software.amazon.encryption.s3.S3EncryptionClient;
5+
import software.amazon.encryption.s3.algorithms.AlgorithmSuite;
76
import software.amazon.encryption.s3.materials.AesKeyring;
87
import software.amazon.encryption.s3.materials.Keyring;
98
import software.amazon.encryption.s3.materials.KmsKeyring;
@@ -31,148 +30,150 @@
3130
import java.util.UUID;
3231

3332
import static software.amazon.encryption.s3.CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT;
34-
import static software.amazon.encryption.s3.model.EncryptionAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY;
33+
import static software.amazon.encryption.s3.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT;
34+
import static software.amazon.encryption.s3.CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT;
3535

3636
public class CreateClientOperationImpl implements CreateClientOperation {
37-
private Map<String, S3Client> clientCache_;
38-
39-
public CreateClientOperationImpl(Map<String, S3Client> clientCache) {
40-
clientCache_ = clientCache;
41-
}
42-
43-
// Copied from S3EC.
44-
private boolean onlyOneNonNull(Object... values) {
45-
boolean haveOneNonNull = false;
46-
for (Object o : values) {
47-
if (o != null) {
48-
if (haveOneNonNull) {
49-
return false;
37+
private final Map<String, S3Client> clientCache_;
38+
39+
public CreateClientOperationImpl(Map<String, S3Client> clientCache) {
40+
clientCache_ = clientCache;
41+
}
42+
43+
// Copied from S3EC.
44+
private boolean onlyOneNonNull(Object... values) {
45+
boolean haveOneNonNull = false;
46+
for (Object o : values) {
47+
if (o != null) {
48+
if (haveOneNonNull) {
49+
return false;
50+
}
51+
52+
haveOneNonNull = true;
53+
}
5054
}
5155

52-
haveOneNonNull = true;
53-
}
56+
return haveOneNonNull;
5457
}
5558

56-
return haveOneNonNull;
57-
}
58-
59-
@Override
60-
public CreateClientOutput createClient(CreateClientInput input, RequestContext context) {
61-
try {
62-
KeyMaterial key = input.getConfig().getKeyMaterial();
63-
if (!onlyOneNonNull(key.getAesKey(), key.getKmsKeyId(), key.getRsaKey())) {
64-
throw new RuntimeException("KeyMaterial must be only one, non-null input!");
65-
}
66-
Keyring keyring;
67-
if (key.getAesKey() != null) {
68-
byte[] keyBytes = new byte[key.getAesKey().remaining()];
69-
key.getAesKey().get(keyBytes);
70-
keyring = AesKeyring.builder()
71-
.wrappingKey(new SecretKeySpec(keyBytes, "AES"))
72-
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
73-
.build();
74-
} else if (key.getRsaKey() != null) {
59+
@Override
60+
public CreateClientOutput createClient(CreateClientInput input, RequestContext context) {
7561
try {
76-
byte[] keyBytes = new byte[key.getRsaKey().remaining()];
77-
key.getRsaKey().get(keyBytes);
78-
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
79-
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
80-
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec);
81-
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(
82-
privateKey.getModulus(),
83-
privateKey.getPublicExponent()
84-
);
85-
86-
// Generate public key
87-
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
88-
89-
keyring = RsaKeyring.builder()
90-
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
91-
.wrappingKeyPair(PartialRsaKeyPair.builder()
92-
.publicKey(publicKey)
93-
.privateKey(privateKey).build())
94-
.build();
95-
} catch (NoSuchAlgorithmException | InvalidKeySpecException nse) {
96-
throw GenericServerError.builder()
97-
.message(nse.getMessage())
98-
.build();
62+
KeyMaterial key = input.getConfig().getKeyMaterial();
63+
if (!onlyOneNonNull(key.getAesKey(), key.getKmsKeyId(), key.getRsaKey())) {
64+
throw new RuntimeException("KeyMaterial must be only one, non-null input!");
65+
}
66+
Keyring keyring;
67+
if (key.getAesKey() != null) {
68+
byte[] keyBytes = new byte[key.getAesKey().remaining()];
69+
key.getAesKey().get(keyBytes);
70+
keyring = AesKeyring.builder()
71+
.wrappingKey(new SecretKeySpec(keyBytes, "AES"))
72+
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
73+
.build();
74+
} else if (key.getRsaKey() != null) {
75+
try {
76+
byte[] keyBytes = new byte[key.getRsaKey().remaining()];
77+
key.getRsaKey().get(keyBytes);
78+
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
79+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
80+
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec);
81+
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(
82+
privateKey.getModulus(),
83+
privateKey.getPublicExponent()
84+
);
85+
86+
// Generate public key
87+
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
88+
89+
keyring = RsaKeyring.builder()
90+
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
91+
.wrappingKeyPair(PartialRsaKeyPair.builder()
92+
.publicKey(publicKey)
93+
.privateKey(privateKey).build())
94+
.build();
95+
} catch (NoSuchAlgorithmException | InvalidKeySpecException nse) {
96+
throw GenericServerError.builder()
97+
.message(nse.getMessage())
98+
.build();
99+
}
100+
} else if (key.getKmsKeyId() != null) {
101+
keyring = KmsKeyring.builder()
102+
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
103+
.wrappingKeyId(key.getKmsKeyId())
104+
.build();
105+
} else {
106+
throw new RuntimeException("No KeyMaterial found!");
107+
}
108+
109+
// V3 Transition server configuration
110+
// Existing Builder defaults to FORBID_ENCRYPT and ALG_AES_256_GCM_IV12_TAG16_NO_KDF
111+
S3EncryptionClient.Builder s3ClientBuilder = S3EncryptionClient.builder()
112+
.keyring(keyring)
113+
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
114+
.enableLegacyUnauthenticatedModes(input.getConfig().isEnableLegacyUnauthenticatedModes());
115+
116+
// Instruction File Put Configuration
117+
boolean instFilePut = false;
118+
if (input.getConfig().getInstructionFileConfig() != null) {
119+
instFilePut = input.getConfig().getInstructionFileConfig().isEnableInstructionFilePutObject();
120+
s3ClientBuilder.instructionFileConfig(InstructionFileConfig.builder()
121+
.instructionFileClient(S3Client.create())
122+
.enableInstructionFilePutObject(instFilePut)
123+
.build());
124+
}
125+
126+
// Configure commitment policy if provided
127+
if (input.getConfig().getCommitmentPolicy() != null) {
128+
CommitmentPolicy policy = getCommitmentPolicy(input.getConfig().getCommitmentPolicy());
129+
s3ClientBuilder.commitmentPolicy(policy);
130+
}
131+
132+
// Configure encryption algorithm if provided
133+
if (input.getConfig().getEncryptionAlgorithm() != null) {
134+
AlgorithmSuite algorithm = getAlgorithmSuite(input.getConfig().getEncryptionAlgorithm());
135+
s3ClientBuilder.encryptionAlgorithm(algorithm);
136+
}
137+
138+
S3Client s3Client = s3ClientBuilder.build();
139+
140+
UUID uuid = UUID.randomUUID();
141+
String uuidString = uuid.toString();
142+
clientCache_.put(uuidString, s3Client);
143+
return CreateClientOutput.builder()
144+
.clientId(uuidString)
145+
.build();
146+
} catch (Exception e) {
147+
StringWriter sw = new StringWriter();
148+
e.printStackTrace(new PrintWriter(sw));
149+
String stackTrace = sw.toString();
150+
throw GenericServerError.builder()
151+
.message(stackTrace)
152+
.build();
99153
}
100-
} else if (key.getKmsKeyId() != null) {
101-
keyring = KmsKeyring.builder()
102-
.enableLegacyWrappingAlgorithms(input.getConfig().isEnableLegacyWrappingAlgorithms())
103-
.wrappingKeyId(key.getKmsKeyId())
104-
.build();
105-
} else {
106-
throw new RuntimeException("No KeyMaterial found!");
107-
}
108-
109-
boolean instFilePut = false;
110-
if (input.getConfig().getInstructionFileConfig() != null) {
111-
instFilePut = input.getConfig().getInstructionFileConfig().isEnableInstructionFilePutObject();
112-
}
113-
114-
// V3-Transitional server configuration
115-
S3EncryptionClient.Builder clientBuilder = S3EncryptionClient.builder()
116-
.instructionFileConfig(InstructionFileConfig.builder()
117-
.instructionFileClient(S3Client.create())
118-
.enableInstructionFilePutObject(instFilePut)
119-
.build())
120-
.keyring(keyring);
121-
122-
// Configure commitment policy if provided ( feature)
123-
if (input.getConfig().getCommitmentPolicy() != null) {
124-
CommitmentPolicy policy = getCommitmentPolicy(input);
125-
clientBuilder.commitmentPolicy(policy);
126-
}
127-
// V3-Transitional default: No commitment policy (null) for backward compatibility
128-
129-
// Configure encryption algorithm if provided ( feature)
130-
if (input.getConfig().getEncryptionAlgorithm() != null) {
131-
AlgorithmSuite algorithm = getAlgorithmSuite(input);
132-
clientBuilder.encryptionAlgorithm(algorithm);
133-
} else {
134-
// V3-Transitional default: Legacy algorithm for backward compatibility
135-
clientBuilder.encryptionAlgorithm(AlgorithmSuite.ALG_AES_256_GCM_IV12_TAG16_NO_KDF);
136-
}
137-
138-
S3Client s3Client = clientBuilder.build();
139-
UUID uuid = UUID.randomUUID();
140-
String uuidString = uuid.toString();
141-
clientCache_.put(uuidString, s3Client);
142-
return CreateClientOutput.builder()
143-
.clientId(uuidString)
144-
.build();
145-
} catch (Exception e) {
146-
StringWriter sw = new StringWriter();
147-
e.printStackTrace(new PrintWriter(sw));
148-
String stackTrace = sw.toString();
149-
throw GenericServerError.builder()
150-
.message(stackTrace)
151-
.build();
152154
}
153-
}
154-
155-
private static AlgorithmSuite getAlgorithmSuite(CreateClientInput input) {
156-
if (input.getConfig().getEncryptionAlgorithm().equals(EncryptionAlgorithm.ALG_AES_256_CBC_IV16_NO_KDF)) {
157-
return AlgorithmSuite.ALG_AES_256_CBC_IV16_NO_KDF;
158-
} else if (input.getConfig().getEncryptionAlgorithm().equals(EncryptionAlgorithm.ALG_AES_256_GCM_IV12_TAG16_NO_KDF)) {
159-
return AlgorithmSuite.ALG_AES_256_GCM_IV12_TAG16_NO_KDF;
160-
} else if (input.getConfig().getEncryptionAlgorithm().equals(EncryptionAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY)) {
161-
return AlgorithmSuite.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY;
162-
} else {
163-
throw new RuntimeException("Unknown encryption algorithm: " + input.getConfig().getEncryptionAlgorithm());
155+
156+
private static AlgorithmSuite getAlgorithmSuite(EncryptionAlgorithm input) {
157+
if (input.equals(EncryptionAlgorithm.ALG_AES_256_CBC_IV16_NO_KDF)) {
158+
return AlgorithmSuite.ALG_AES_256_CBC_IV16_NO_KDF;
159+
} else if (input.equals(EncryptionAlgorithm.ALG_AES_256_GCM_IV12_TAG16_NO_KDF)) {
160+
return AlgorithmSuite.ALG_AES_256_GCM_IV12_TAG16_NO_KDF;
161+
} else if (input.equals(EncryptionAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY)) {
162+
return AlgorithmSuite.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY;
163+
} else {
164+
throw new RuntimeException("Unknown encryption algorithm: " + input);
165+
}
164166
}
165-
}
166-
167-
private static software.amazon.encryption.s3.CommitmentPolicy getCommitmentPolicy(CreateClientInput input) {
168-
if (input.getConfig().getCommitmentPolicy().equals(software.amazon.encryption.s3.model.CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)) {
169-
return FORBID_ENCRYPT_ALLOW_DECRYPT;
170-
} else if (input.getConfig().getCommitmentPolicy().equals(software.amazon.encryption.s3.model.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT)) {
171-
return null;
172-
} else if (input.getConfig().getCommitmentPolicy().equals(software.amazon.encryption.s3.model.CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)) {
173-
return null;
174-
} else {
175-
throw new RuntimeException("Unknown commitment policy: " + input.getConfig().getCommitmentPolicy());
167+
168+
private static software.amazon.encryption.s3.CommitmentPolicy getCommitmentPolicy(software.amazon.encryption.s3.model.CommitmentPolicy input) {
169+
if (input.equals(software.amazon.encryption.s3.model.CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)) {
170+
return FORBID_ENCRYPT_ALLOW_DECRYPT;
171+
} else if (input.equals(software.amazon.encryption.s3.model.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT)) {
172+
return REQUIRE_ENCRYPT_ALLOW_DECRYPT;
173+
} else if (input.equals(software.amazon.encryption.s3.model.CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)) {
174+
return REQUIRE_ENCRYPT_REQUIRE_DECRYPT;
175+
} else {
176+
throw new RuntimeException("Unknown commitment policy: " + input);
177+
}
176178
}
177-
}
178179
}

0 commit comments

Comments
 (0)