Skip to content

Commit 30cf9b1

Browse files
fix: Guard against using another S3EC as wrappedClient (#36)
* fix: Guard against using another S3EC as wrappedClient * test: Add E2E test coverage (simple round trip call) for different S3EC construction methods
1 parent f41f8e5 commit 30cf9b1

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ private Builder() {}
131131
*/
132132
@SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Pass mutability into wrapping client")
133133
public Builder wrappedClient(S3Client wrappedClient) {
134+
if (wrappedClient instanceof S3EncryptionClient) {
135+
throw new S3EncryptionClientException("Cannot use S3EncryptionClient as wrapped client");
136+
}
137+
134138
this._wrappedClient = wrappedClient;
135139
return this;
136140
}

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import software.amazon.awssdk.services.s3.S3Client;
88
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
99
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
10+
import software.amazon.encryption.s3.materials.CryptographicMaterialsManager;
11+
import software.amazon.encryption.s3.materials.DefaultCryptoMaterialsManager;
12+
import software.amazon.encryption.s3.materials.KmsKeyring;
1013
import software.amazon.encryption.s3.utils.BoundedZerosInputStream;
1114

1215
import javax.crypto.KeyGenerator;
@@ -185,6 +188,67 @@ public void defaultModeWithLargeObjectFails() throws IOException {
185188
v3Client.close();
186189
}
187190

191+
192+
@Test
193+
public void s3EncryptionClientWithKeyringFromKmsKeyIdSucceeds() {
194+
final String objectKey = "keyring-from-kms-key-id";
195+
196+
KmsKeyring keyring = KmsKeyring.builder().wrappingKeyId(KMS_KEY_ID).build();
197+
198+
S3Client v3Client = S3EncryptionClient.builder()
199+
.keyring(keyring)
200+
.build();
201+
202+
simpleV3RoundTrip(v3Client, objectKey);
203+
}
204+
205+
@Test
206+
public void s3EncryptionClientWithCmmFromKmsKeyIdSucceeds() {
207+
final String objectKey = "cmm-from-kms-key-id";
208+
209+
KmsKeyring keyring = KmsKeyring.builder().wrappingKeyId(KMS_KEY_ID).build();
210+
211+
CryptographicMaterialsManager cmm = DefaultCryptoMaterialsManager.builder()
212+
.keyring(keyring)
213+
.build();
214+
215+
S3Client v3Client = S3EncryptionClient.builder()
216+
.cryptoMaterialsManager(cmm)
217+
.build();
218+
219+
simpleV3RoundTrip(v3Client, objectKey);
220+
}
221+
222+
@Test
223+
public void s3EncryptionClientWithWrappedS3ClientSucceeds() {
224+
final String objectKey = "wrapped-s3-client-with-kms-key-id";
225+
226+
S3Client wrappedClient = S3Client.builder().build();
227+
228+
S3Client wrappingClient = S3EncryptionClient.builder()
229+
.wrappedClient(wrappedClient)
230+
.kmsKeyId(KMS_KEY_ID)
231+
.build();
232+
233+
simpleV3RoundTrip(wrappingClient, objectKey);
234+
}
235+
236+
/**
237+
* S3EncryptionClient implements S3Client, so it can be passed into the builder as a wrappedClient.
238+
* However, is not a supported use case, and the builder should throw an exception if this happens.
239+
*/
240+
@Test
241+
public void s3EncryptionClientWithWrappedS3EncryptionClientFails() {
242+
S3Client wrappedClient = S3EncryptionClient.builder()
243+
.kmsKeyId(KMS_KEY_ID)
244+
.build();
245+
246+
assertThrows(S3EncryptionClientException.class, () -> S3EncryptionClient.builder()
247+
.wrappedClient(wrappedClient)
248+
.kmsKeyId(KMS_KEY_ID)
249+
.build());
250+
}
251+
188252
/**
189253
* A simple, reusable round-trip (encryption + decryption) using a given
190254
* S3Client. Useful for testing client configuration.

0 commit comments

Comments
 (0)