Skip to content

Commit ebcddbf

Browse files
authored
fix: regression in ranged gets when using buffered subscriber (#107)
* fix: regression in ranged gets when using buffered subscriber
1 parent 58ee9bc commit ebcddbf

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,16 @@ public void onNext(ByteBuffer byteBuffer) {
6161

6262
if (amountToReadFromByteBuffer > 0) {
6363
byte[] buf = BinaryUtils.copyBytesFrom(byteBuffer, amountToReadFromByteBuffer);
64-
outputBuffer = cipher.update(buf, 0, amountToReadFromByteBuffer);
64+
try {
65+
outputBuffer = cipher.update(buf, 0, amountToReadFromByteBuffer);
66+
} catch (final IllegalStateException exception) {
67+
// This happens when the stream is reset and the cipher is reused with the
68+
// same key/IV. It's actually fine here, because the data is the same, but any
69+
// sane implementation will throw an exception.
70+
// TODO: Implement retries. For now, forward and rethrow.
71+
this.onError(exception);
72+
throw exception;
73+
}
6574

6675
if (outputBuffer == null && amountToReadFromByteBuffer < cipher.getBlockSize()) {
6776
// The underlying data is too short to fill in the block cipher

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,16 @@ public void onNext(ByteBuffer byteBuffer) {
3535

3636
if (amountToReadFromByteBuffer > 0) {
3737
byte[] buf = BinaryUtils.copyBytesFrom(byteBuffer, amountToReadFromByteBuffer);
38-
outputBuffer = cipher.update(buf, 0, amountToReadFromByteBuffer);
38+
try {
39+
outputBuffer = cipher.update(buf, 0, amountToReadFromByteBuffer);
40+
} catch (final IllegalStateException exception) {
41+
// This happens when the stream is reset and the cipher is reused with the
42+
// same key/IV. It's actually fine here, because the data is the same, but any
43+
// sane implementation will throw an exception.
44+
// TODO: Implement retries. For now, forward and rethrow.
45+
this.onError(exception);
46+
throw exception;
47+
}
3948
if (outputBuffer == null && amountToReadFromByteBuffer < cipher.getBlockSize()) {
4049
// The underlying data is too short to fill in the block cipher
4150
// This is true at the end of the file, so complete to get the final

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ public void onStream(SdkPublisher<ByteBuffer> ciphertextPublisher) {
148148
throw new S3EncryptionClientException("Unknown algorithm: " + algorithmSuite.cipherName());
149149
}
150150

151-
if (algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CBC_IV16_NO_KDF) || _enableDelayedAuthentication) {
151+
if (algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CBC_IV16_NO_KDF)
152+
|| algorithmSuite.equals(AlgorithmSuite.ALG_AES_256_CTR_IV16_TAG16_NO_KDF)
153+
|| _enableDelayedAuthentication) {
152154
// CBC and GCM with delayed auth enabled use a standard publisher
153155
CipherPublisher plaintextPublisher = new CipherPublisher(cipher, ciphertextPublisher,
154156
getObjectResponse.contentLength(), desiredRange, contentMetadata.contentRange(), algorithmSuite.cipherTagLengthBits());

0 commit comments

Comments
 (0)