Skip to content

Commit 12355a1

Browse files
authored
fix: allow CipherSubscriber to determine if the part is last part (#453)
1 parent 647c809 commit 12355a1

File tree

10 files changed

+66
-61
lines changed

10 files changed

+66
-61
lines changed

pom.xml

+5-5
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
<dependency>
5757
<groupId>software.amazon.awssdk</groupId>
5858
<artifactId>bom</artifactId>
59-
<version>2.30.38</version>
59+
<version>2.31.14</version>
6060
<optional>true</optional>
6161
<type>pom</type>
6262
<scope>import</scope>
@@ -68,21 +68,21 @@
6868
<dependency>
6969
<groupId>software.amazon.awssdk</groupId>
7070
<artifactId>s3</artifactId>
71-
<version>2.30.38</version>
71+
<version>2.31.14</version>
7272
</dependency>
7373

7474
<dependency>
7575
<groupId>software.amazon.awssdk</groupId>
7676
<artifactId>kms</artifactId>
77-
<version>2.30.38</version>
77+
<version>2.31.14</version>
7878
</dependency>
7979

8080
<!-- Used when enableMultipartPutObject is configured -->
8181
<dependency>
8282
<groupId>software.amazon.awssdk.crt</groupId>
8383
<artifactId>aws-crt</artifactId>
8484
<optional>true</optional>
85-
<version>0.36.3</version>
85+
<version>0.37.0</version>
8686
</dependency>
8787

8888
<dependency>
@@ -163,7 +163,7 @@
163163
<dependency>
164164
<groupId>software.amazon.awssdk</groupId>
165165
<artifactId>sts</artifactId>
166-
<version>2.30.38</version>
166+
<version>2.31.14</version>
167167
<optional>true</optional>
168168
<scope>test</scope>
169169
</dependency>

src/examples/java/software/amazon/encryption/s3/examples/MultipartUploadExample.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package software.amazon.encryption.s3.examples;
22

3-
import static org.junit.jupiter.api.Assertions.assertTrue;
4-
import static software.amazon.encryption.s3.S3EncryptionClient.withAdditionalConfiguration;
5-
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.KMS_KEY_ID;
6-
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.appendTestSuffix;
7-
3+
import org.apache.commons.io.IOUtils;
84
import software.amazon.awssdk.core.ResponseInputStream;
95
import software.amazon.awssdk.core.sync.RequestBody;
106
import software.amazon.awssdk.services.s3.S3Client;
@@ -26,7 +22,10 @@
2622
import java.util.List;
2723
import java.util.Map;
2824

29-
import org.apache.commons.io.IOUtils;
25+
import static org.junit.jupiter.api.Assertions.assertTrue;
26+
import static software.amazon.encryption.s3.S3EncryptionClient.withAdditionalConfiguration;
27+
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.KMS_KEY_ID;
28+
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.appendTestSuffix;
3029

3130
public class MultipartUploadExample {
3231
public static String BUCKET;

src/main/java/software/amazon/encryption/s3/internal/CipherAsyncRequestBody.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ public class CipherAsyncRequestBody implements AsyncRequestBody {
2020
private final Long ciphertextLength;
2121
private final CryptographicMaterials materials;
2222
private final byte[] iv;
23+
private final boolean isLastPart;
2324

2425
public CipherAsyncRequestBody(final AsyncRequestBody wrappedAsyncRequestBody, final Long ciphertextLength, final CryptographicMaterials materials, final byte[] iv, final boolean isLastPart) {
2526
this.wrappedAsyncRequestBody = wrappedAsyncRequestBody;
2627
this.ciphertextLength = ciphertextLength;
2728
this.materials = materials;
2829
this.iv = iv;
30+
this.isLastPart = isLastPart;
2931
}
3032

3133
public CipherAsyncRequestBody(final AsyncRequestBody wrappedAsyncRequestBody, final Long ciphertextLength, final CryptographicMaterials materials, final byte[] iv) {
@@ -38,7 +40,7 @@ public CipherAsyncRequestBody(final AsyncRequestBody wrappedAsyncRequestBody, fi
3840
public void subscribe(Subscriber<? super ByteBuffer> subscriber) {
3941
wrappedAsyncRequestBody.subscribe(new CipherSubscriber(subscriber,
4042
contentLength().orElseThrow(() -> new S3EncryptionClientException("Unbounded streams are currently not supported.")),
41-
materials, iv));
43+
materials, iv, isLastPart));
4244
}
4345

4446
@Override

src/main/java/software/amazon/encryption/s3/internal/CipherSubscriber.java

-4
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@ public class CipherSubscriber implements Subscriber<ByteBuffer> {
1818
private final Subscriber<? super ByteBuffer> wrappedSubscriber;
1919
private Cipher cipher;
2020
private final Long contentLength;
21-
private final CryptographicMaterials materials;
22-
private byte[] iv;
2321
private boolean isLastPart;
2422

2523
private byte[] outputBuffer;
2624

2725
CipherSubscriber(Subscriber<? super ByteBuffer> wrappedSubscriber, Long contentLength, CryptographicMaterials materials, byte[] iv, boolean isLastPart) {
2826
this.wrappedSubscriber = wrappedSubscriber;
2927
this.contentLength = contentLength;
30-
this.materials = materials;
31-
this.iv = iv;
3228
cipher = materials.getCipher(iv);
3329
this.isLastPart = isLastPart;
3430
}

src/main/java/software/amazon/encryption/s3/internal/GetEncryptedObjectPipeline.java

+13-37
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,7 @@
1717
import software.amazon.encryption.s3.materials.DecryptionMaterials;
1818
import software.amazon.encryption.s3.materials.EncryptedDataKey;
1919

20-
import javax.crypto.Cipher;
21-
import javax.crypto.SecretKey;
22-
import javax.crypto.spec.GCMParameterSpec;
23-
import javax.crypto.spec.IvParameterSpec;
2420
import java.nio.ByteBuffer;
25-
import java.security.GeneralSecurityException;
2621
import java.util.Collections;
2722
import java.util.List;
2823
import java.util.concurrent.CompletableFuture;
@@ -143,42 +138,23 @@ public void onStream(SdkPublisher<ByteBuffer> ciphertextPublisher) {
143138
long[] desiredRange = RangedGetUtils.getRange(materials.getContentRange());
144139
long[] cryptoRange = RangedGetUtils.getCryptoRange(materials.getContentRange());
145140
AlgorithmSuite algorithmSuite = materials.algorithmSuite();
146-
SecretKey contentKey = materials.dataKey();
147-
final int tagLength = algorithmSuite.cipherTagLengthBits();
148141
byte[] iv = contentMetadata.contentIv();
149142
if (algorithmSuite == AlgorithmSuite.ALG_AES_256_CTR_IV16_TAG16_NO_KDF) {
150143
iv = AesCtrUtils.adjustIV(iv, cryptoRange[0]);
151144
}
152-
try {
153-
final Cipher cipher = CryptoFactory.createCipher(algorithmSuite.cipherName(), materials.cryptoProvider());
154-
switch (algorithmSuite) {
155-
case ALG_AES_256_GCM_IV12_TAG16_NO_KDF:
156-
cipher.init(Cipher.DECRYPT_MODE, contentKey, new GCMParameterSpec(tagLength, iv));
157-
break;
158-
case ALG_AES_256_CTR_IV16_TAG16_NO_KDF:
159-
case ALG_AES_256_CBC_IV16_NO_KDF:
160-
cipher.init(Cipher.DECRYPT_MODE, contentKey, new IvParameterSpec(iv));
161-
break;
162-
default:
163-
throw new S3EncryptionClientException("Unknown algorithm: " + algorithmSuite.cipherName());
164-
}
165-
166-
if (algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CBC_IV16_NO_KDF)
167-
|| algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CTR_IV16_TAG16_NO_KDF)
168-
|| _enableDelayedAuthentication) {
169-
// CBC and GCM with delayed auth enabled use a standard publisher
170-
CipherPublisher plaintextPublisher = new CipherPublisher(ciphertextPublisher,
171-
getObjectResponse.contentLength(), desiredRange, contentMetadata.contentRange(), algorithmSuite.cipherTagLengthBits(), materials, iv);
172-
wrappedAsyncResponseTransformer.onStream(plaintextPublisher);
173-
} else {
174-
// Use buffered publisher for GCM when delayed auth is not enabled
175-
BufferedCipherPublisher plaintextPublisher = new BufferedCipherPublisher(ciphertextPublisher,
176-
getObjectResponse.contentLength(), materials, iv, _bufferSize);
177-
wrappedAsyncResponseTransformer.onStream(plaintextPublisher);
178-
}
179-
180-
} catch (GeneralSecurityException e) {
181-
throw new S3EncryptionClientException("Unable to " + algorithmSuite.cipherName() + " content decrypt.", e);
145+
146+
if (algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CBC_IV16_NO_KDF)
147+
|| algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CTR_IV16_TAG16_NO_KDF)
148+
|| _enableDelayedAuthentication) {
149+
// CBC and GCM with delayed auth enabled use a standard publisher
150+
CipherPublisher plaintextPublisher = new CipherPublisher(ciphertextPublisher,
151+
getObjectResponse.contentLength(), desiredRange, contentMetadata.contentRange(), algorithmSuite.cipherTagLengthBits(), materials, iv);
152+
wrappedAsyncResponseTransformer.onStream(plaintextPublisher);
153+
} else {
154+
// Use buffered publisher for GCM when delayed auth is not enabled
155+
BufferedCipherPublisher plaintextPublisher = new BufferedCipherPublisher(ciphertextPublisher,
156+
getObjectResponse.contentLength(), materials, iv, _bufferSize);
157+
wrappedAsyncResponseTransformer.onStream(plaintextPublisher);
182158
}
183159
}
184160
}

src/test/java/software/amazon/encryption/s3/examples/AsyncClientExampleTest.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
import org.junit.jupiter.api.Test;
44
import software.amazon.encryption.s3.utils.S3EncryptionClientTestResources;
55

6+
import static org.junit.jupiter.api.Assertions.fail;
7+
68
public class AsyncClientExampleTest {
79

810
@Test
911
public void testAsyncClientExamples() {
1012
final String bucket = S3EncryptionClientTestResources.BUCKET;
11-
AsyncClientExample.main(new String[]{bucket});
13+
try {
14+
AsyncClientExample.main(new String[]{bucket});
15+
} catch (Throwable exception) {
16+
exception.printStackTrace();
17+
fail("Async Example Test Failed!!", exception);
18+
}
1219
}
1320
}

src/test/java/software/amazon/encryption/s3/examples/ClientConfigurationExampleTest.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22

33
import org.junit.jupiter.api.Test;
44

5+
import static org.junit.jupiter.api.Assertions.fail;
6+
57
public class ClientConfigurationExampleTest {
68
@Test
79
public void testClientConfigurationExamples() {
8-
ClientConfigurationExample.main(new String[0]);
10+
try {
11+
ClientConfigurationExample.main(new String[0]);
12+
} catch (Throwable exception) {
13+
exception.printStackTrace();
14+
fail("Client Configuration Example Test Failed!!", exception);
15+
}
916
}
1017
}

src/test/java/software/amazon/encryption/s3/examples/MultipartUploadExampleTest.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
import org.junit.jupiter.api.Test;
44
import software.amazon.encryption.s3.utils.S3EncryptionClientTestResources;
55

6-
import java.io.IOException;
6+
import static org.junit.jupiter.api.Assertions.fail;
77

88
public class MultipartUploadExampleTest {
99

1010
@Test
11-
public void testMultipartUploadExamples() throws IOException {
11+
public void testMultipartUploadExamples() {
1212
final String bucket = S3EncryptionClientTestResources.BUCKET;
13-
MultipartUploadExample.main(new String[]{bucket});
13+
try {
14+
MultipartUploadExample.main(new String[]{bucket});
15+
} catch (Throwable exception) {
16+
exception.printStackTrace();
17+
fail("Multipart Example Test Failed!!", exception);
18+
}
1419
}
1520
}

src/test/java/software/amazon/encryption/s3/examples/PartialKeyPairExampleTest.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55
import org.junit.jupiter.api.Test;
66
import software.amazon.encryption.s3.utils.S3EncryptionClientTestResources;
77

8+
import static org.junit.jupiter.api.Assertions.fail;
9+
810
public class PartialKeyPairExampleTest {
911

1012
@Test
1113
public void testPartialKeyPairExamples() {
1214
final String bucket = S3EncryptionClientTestResources.BUCKET;
13-
14-
PartialKeyPairExample.main(new String[]{bucket});
15+
try {
16+
PartialKeyPairExample.main(new String[]{bucket});
17+
} catch (Throwable exception) {
18+
exception.printStackTrace();
19+
fail("Partial Key Pair Example Test Failed!!", exception);
20+
}
1521
}
1622
}

src/test/java/software/amazon/encryption/s3/examples/RangedGetExampleTest.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
import org.junit.jupiter.api.Test;
44
import software.amazon.encryption.s3.utils.S3EncryptionClientTestResources;
55

6+
import static org.junit.jupiter.api.Assertions.fail;
7+
68
public class RangedGetExampleTest {
79

810
@Test
911
public void testRangedGetExamples() {
1012
final String bucket = S3EncryptionClientTestResources.BUCKET;
11-
RangedGetExample.main(new String[]{bucket});
13+
try {
14+
RangedGetExample.main(new String[]{bucket});
15+
} catch (Throwable exception) {
16+
exception.printStackTrace();
17+
fail("Ranged Get Test Failed!!", exception);
18+
}
1219
}
1320
}

0 commit comments

Comments
 (0)