Skip to content

Commit 87a4631

Browse files
committed
Merge branch '3.1.x' into upstream-3.1.x
2 parents 084ccef + 6de7fbf commit 87a4631

File tree

3 files changed

+70
-42
lines changed

3 files changed

+70
-42
lines changed

java-manta-client/src/main/java/com/joyent/manta/client/crypto/MantaEncryptedObjectInputStream.java

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import com.joyent.manta.http.MantaHttpHeaders;
1515
import com.joyent.manta.util.NotThreadSafe;
1616
import org.apache.commons.codec.binary.Hex;
17-
import org.apache.commons.io.IOUtils;
1817
import org.apache.commons.io.input.BoundedInputStream;
1918
import org.apache.commons.lang3.ObjectUtils;
2019
import org.apache.commons.lang3.Validate;
@@ -26,16 +25,16 @@
2625
import org.slf4j.Logger;
2726
import org.slf4j.LoggerFactory;
2827

29-
import javax.crypto.AEADBadTagException;
30-
import javax.crypto.Cipher;
31-
import javax.crypto.SecretKey;
3228
import java.io.IOException;
3329
import java.io.InputStream;
3430
import java.security.InvalidAlgorithmParameterException;
3531
import java.security.InvalidKeyException;
3632
import java.util.Arrays;
3733
import java.util.Base64;
3834
import java.util.function.Supplier;
35+
import javax.crypto.AEADBadTagException;
36+
import javax.crypto.Cipher;
37+
import javax.crypto.SecretKey;
3938

4039
/**
4140
* <p>An {@link InputStream} implementation that decrypts client-side encrypted
@@ -721,37 +720,39 @@ public void close() throws IOException {
721720
readRemainingBytes();
722721

723722
try {
724-
IOUtils.closeQuietly(cipherInputStream);
723+
cipherInputStream.close();
725724
} catch (Exception e) {
726725
LOGGER.warn("Error closing CipherInputStream", e);
727726
}
728727

729-
if (hmac != null && authenticateCiphertext) {
730-
byte[] checksum = new byte[hmac.getMacSize()];
731-
hmac.doFinal(checksum, 0);
732-
byte[] expected = readHmacFromEndOfStream();
733-
734-
if (LOGGER.isDebugEnabled()) {
735-
LOGGER.debug("Calculated HMAC is: {}", Hex.encodeHexString(checksum));
736-
}
728+
try {
729+
if (hmac != null && authenticateCiphertext) {
730+
byte[] checksum = new byte[hmac.getMacSize()];
731+
hmac.doFinal(checksum, 0);
732+
byte[] expected = readHmacFromEndOfStream();
737733

738-
if (super.getBackingStream().read() >= 0) {
739-
MantaIOException e = new MantaIOException("More bytes were available than the "
740-
+ "expected HMAC length");
741-
annotateException(e);
742-
throw e;
743-
}
734+
if (LOGGER.isDebugEnabled()) {
735+
LOGGER.debug("Calculated HMAC is: {}", Hex.encodeHexString(checksum));
736+
}
744737

745-
super.close();
738+
if (super.getBackingStream().read() >= 0) {
739+
MantaIOException e = new MantaIOException("More bytes were available than the "
740+
+ "expected HMAC length");
741+
annotateException(e);
742+
throw e;
743+
}
746744

747-
if (!Arrays.equals(expected, checksum)) {
748-
MantaClientEncryptionCiphertextAuthenticationException e =
749-
new MantaClientEncryptionCiphertextAuthenticationException();
750-
annotateException(e);
751-
e.setContextValue("expected", Hex.encodeHexString(expected));
752-
e.setContextValue("checksum", Hex.encodeHexString(checksum));
753-
throw e;
745+
if (!Arrays.equals(expected, checksum)) {
746+
MantaClientEncryptionCiphertextAuthenticationException e =
747+
new MantaClientEncryptionCiphertextAuthenticationException();
748+
annotateException(e);
749+
e.setContextValue("expected", Hex.encodeHexString(expected));
750+
e.setContextValue("checksum", Hex.encodeHexString(checksum));
751+
throw e;
752+
}
754753
}
754+
} finally {
755+
super.close();
755756
}
756757
}
757758

java-manta-client/src/test/java/com/joyent/manta/client/crypto/IncompleteByteReadInputStream.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ public int read(byte[] b, int off, int len) throws IOException {
4343
return wrapped.read(b, off, len);
4444
}
4545
}
46+
47+
@Override
48+
public void close() throws IOException {
49+
wrapped.close();
50+
}
4651
}

java-manta-client/src/test/java/com/joyent/manta/client/crypto/MantaEncryptedObjectInputStreamTest.java

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import org.testng.AssertJUnit;
2727
import org.testng.annotations.Test;
2828

29-
import javax.crypto.Cipher;
30-
import javax.crypto.SecretKey;
3129
import java.io.ByteArrayInputStream;
3230
import java.io.ByteArrayOutputStream;
3331
import java.io.File;
@@ -48,6 +46,8 @@
4846
import java.util.Arrays;
4947
import java.util.Base64;
5048
import java.util.UUID;
49+
import javax.crypto.Cipher;
50+
import javax.crypto.SecretKey;
5151

5252
import static java.nio.file.StandardOpenOption.READ;
5353
import static java.nio.file.StandardOpenOption.WRITE;
@@ -813,8 +813,10 @@ private void canCopyToOutputStreamWithLargeBuffer(SupportedCipherDetails cipherD
813813
final long ciphertextSize = encryptedFile.file.length();
814814

815815
InputStream backing = new FileInputStream(encryptedFile.file);
816+
final InputStream inSpy = Mockito.spy(backing);
817+
816818
MantaEncryptedObjectInputStream in = createEncryptedObjectInputStream(
817-
key, backing, ciphertextSize, cipherDetails, iv, authenticate,
819+
key, inSpy, ciphertextSize, cipherDetails, iv, authenticate,
818820
sourceLength);
819821
ByteArrayOutputStream out = new ByteArrayOutputStream();
820822

@@ -829,6 +831,7 @@ private void canCopyToOutputStreamWithLargeBuffer(SupportedCipherDetails cipherD
829831
}
830832

831833
AssertJUnit.assertArrayEquals(sourceBytes, out.toByteArray());
834+
Mockito.verify(inSpy, Mockito.atLeastOnce()).close();
832835
}
833836

834837
/**
@@ -897,8 +900,9 @@ private void canDecryptEntireObject(SupportedCipherDetails cipherDetails,
897900
EncryptedFile encryptedFile = encryptedFile(key, cipherDetails, this.plaintextSize);
898901
long ciphertextSize = encryptedFile.file.length();
899902

900-
FileInputStream in = new FileInputStream(encryptedFile.file);
901-
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, in,
903+
final FileInputStream in = new FileInputStream(encryptedFile.file);
904+
final FileInputStream inSpy = Mockito.spy(in);
905+
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, inSpy,
902906
ciphertextSize, cipherDetails, encryptedFile.cipher.getIV(), authenticate,
903907
(long)this.plaintextSize);
904908

@@ -911,6 +915,8 @@ private void canDecryptEntireObject(SupportedCipherDetails cipherDetails,
911915
} finally {
912916
min.close();
913917
}
918+
919+
Mockito.verify(inSpy, Mockito.atLeastOnce()).close();
914920
}
915921

916922
/**
@@ -1007,12 +1013,15 @@ private void canReadByteRange(SupportedCipherDetails cipherDetails,
10071013
byte[] rangedBytes = new byte[(int)ciphertextByteRangeLength];
10081014
randomAccessFile.read(rangedBytes);
10091015

1010-
try (ByteArrayInputStream bin = new ByteArrayInputStream(rangedBytes);
1016+
final ByteArrayInputStream bin = new ByteArrayInputStream(rangedBytes);
1017+
final ByteArrayInputStream binSpy = Mockito.spy(bin);
1018+
1019+
try (
10111020
/* When creating the fake stream, we feed it a content-length equal
10121021
* to the size of the byte range because that is what Manta would
10131022
* do. Also, we pass along the incorrect plaintext length and
10141023
* test how the stream handles incorrect values of plaintext length. */
1015-
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, bin,
1024+
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, binSpy,
10161025
ciphertextByteRangeLength, cipherDetails, encryptedFile.cipher.getIV(),
10171026
false, (long)this.plaintextSize,
10181027
initialSkipBytes,
@@ -1031,6 +1040,8 @@ private void canReadByteRange(SupportedCipherDetails cipherDetails,
10311040
new String(actual, StandardCharsets.UTF_8)));
10321041
}
10331042
}
1043+
1044+
Mockito.verify(binSpy, Mockito.atLeastOnce()).close();
10341045
}
10351046
}
10361047

@@ -1041,8 +1052,9 @@ private void canReadObject(SupportedCipherDetails cipherDetails,
10411052
EncryptedFile encryptedFile = encryptedFile(key, cipherDetails, this.plaintextSize);
10421053
long ciphertextSize = encryptedFile.file.length();
10431054

1044-
FileInputStream in = new FileInputStream(encryptedFile.file);
1045-
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, in,
1055+
final FileInputStream in = new FileInputStream(encryptedFile.file);
1056+
final FileInputStream inSpy = Mockito.spy(in);
1057+
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, inSpy,
10461058
ciphertextSize, cipherDetails, encryptedFile.cipher.getIV(),
10471059
authenticate, (long)this.plaintextSize);
10481060

@@ -1051,6 +1063,7 @@ private void canReadObject(SupportedCipherDetails cipherDetails,
10511063
readBytes.readAll(min, actual);
10521064
} finally {
10531065
min.close();
1066+
Mockito.verify(inSpy, Mockito.atLeastOnce()).close();
10541067
}
10551068
}
10561069

@@ -1070,8 +1083,9 @@ private void willThrowExceptionWhenCiphertextIsAltered(SupportedCipherDetails ci
10701083

10711084
boolean thrown = false;
10721085

1073-
FileInputStream in = new FileInputStream(encryptedFile.file);
1074-
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, in,
1086+
final FileInputStream in = new FileInputStream(encryptedFile.file);
1087+
final FileInputStream inSpy = Mockito.spy(in);
1088+
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, inSpy,
10751089
ciphertextSize, cipherDetails, encryptedFile.cipher.getIV(),
10761090
true, (long)this.plaintextSize);
10771091

@@ -1081,6 +1095,7 @@ private void willThrowExceptionWhenCiphertextIsAltered(SupportedCipherDetails ci
10811095
min.close();
10821096
} catch (MantaClientEncryptionCiphertextAuthenticationException e) {
10831097
thrown = true;
1098+
Mockito.verify(inSpy, Mockito.atLeastOnce()).close();
10841099
System.out.printf(" Exception thrown: %s\n", e.getMessage());
10851100
}
10861101

@@ -1096,8 +1111,10 @@ private void willErrorWhenMissingHMAC(final SupportedCipherDetails cipherDetails
10961111

10971112
boolean thrown = false;
10981113

1099-
try (FileInputStream fin = new FileInputStream(encryptedFile.file);
1100-
BoundedInputStream in = new BoundedInputStream(fin, ciphertextSizeWithoutHmac);
1114+
final FileInputStream fin = new FileInputStream(encryptedFile.file);
1115+
final FileInputStream finSpy = Mockito.spy(fin);
1116+
1117+
try (BoundedInputStream in = new BoundedInputStream(finSpy, ciphertextSizeWithoutHmac);
11011118
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, in,
11021119
ciphertextSize, cipherDetails, encryptedFile.cipher.getIV(),
11031120
true, (long)this.plaintextSize)) {
@@ -1112,6 +1129,7 @@ private void willErrorWhenMissingHMAC(final SupportedCipherDetails cipherDetails
11121129
}
11131130
}
11141131

1132+
Mockito.verify(finSpy, Mockito.atLeastOnce()).close();
11151133
Assert.assertTrue(thrown, "Expected MantaIOException was not thrown");
11161134
}
11171135

@@ -1121,15 +1139,19 @@ private void willValidateIfHmacIsReadInMultipleReads(final SupportedCipherDetail
11211139
EncryptedFile encryptedFile = encryptedFile(key, cipherDetails, this.plaintextSize);
11221140
long ciphertextSize = encryptedFile.file.length();
11231141

1124-
try (FileInputStream fin = new FileInputStream(encryptedFile.file);
1125-
IncompleteByteReadInputStream ibrin = new IncompleteByteReadInputStream(fin);
1142+
final FileInputStream fin = new FileInputStream(encryptedFile.file);
1143+
final FileInputStream finSpy = Mockito.spy(fin);
1144+
try (IncompleteByteReadInputStream ibrin = new IncompleteByteReadInputStream(finSpy);
11261145
MantaEncryptedObjectInputStream min = createEncryptedObjectInputStream(key, ibrin,
11271146
ciphertextSize, cipherDetails, encryptedFile.cipher.getIV(),
11281147
true, (long)this.plaintextSize);
11291148
OutputStream out = new NullOutputStream()) {
11301149

11311150
IOUtils.copy(min, out);
11321151
}
1152+
1153+
fin.close();
1154+
Mockito.verify(finSpy, Mockito.atLeastOnce()).close();
11331155
}
11341156

11351157
private EncryptedFile encryptedFile(

0 commit comments

Comments
 (0)