Skip to content

Commit e18d9e6

Browse files
fumiakiycody-signal
authored andcommitted
Take padded bytes into account when decrypting a stream of data.
Fixes #11573
1 parent cc99feb commit e18d9e6

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherInputStream.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,12 @@ public long skip(long byteCount) throws IOException {
162162

163163
private int readFinal(byte[] buffer, int offset, int length) throws IOException {
164164
try {
165-
int flourish = cipher.doFinal(buffer, offset);
165+
byte[] internal = new byte[buffer.length];
166+
int actualLength = Math.min(length, cipher.doFinal(internal, 0));
167+
System.arraycopy(internal, 0, buffer, offset, actualLength);
166168

167169
done = true;
168-
return flourish;
170+
return actualLength;
169171
} catch (IllegalBlockSizeException | BadPaddingException | ShortBufferException e) {
170172
throw new IOException(e);
171173
}

libsignal/service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
import org.junit.Test;
55
import org.whispersystems.libsignal.InvalidMessageException;
66
import org.whispersystems.libsignal.kdf.HKDFv3;
7+
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
8+
import org.whispersystems.signalservice.internal.push.http.AttachmentCipherOutputStreamFactory;
79
import org.whispersystems.signalservice.internal.util.Util;
810

11+
import java.io.ByteArrayInputStream;
912
import java.io.ByteArrayOutputStream;
1013
import java.io.File;
1114
import java.io.FileOutputStream;
@@ -103,6 +106,43 @@ public void attachment_decryptFailOnBadDigest() throws IOException{
103106
assertTrue(hitCorrectException);
104107
}
105108

109+
@Test
110+
public void attachment_encryptDecryptPaddedContent() throws IOException, InvalidMessageException {
111+
int[] lengths = { 531, 600, 724, 1019, 1024 };
112+
113+
for (int length : lengths) {
114+
byte[] plaintextInput = new byte[length];
115+
116+
for (int i = 0; i < length; i++) {
117+
plaintextInput[i] = (byte) 0x97;
118+
}
119+
120+
byte[] key = Util.getSecretBytes(64);
121+
ByteArrayInputStream inputStream = new ByteArrayInputStream(plaintextInput);
122+
InputStream dataStream = new PaddingInputStream(inputStream, length);
123+
ByteArrayOutputStream encryptedStream = new ByteArrayOutputStream();
124+
DigestingOutputStream digestStream = new AttachmentCipherOutputStreamFactory(key, null).createFor(encryptedStream);
125+
126+
Util.copy(dataStream, digestStream);
127+
digestStream.flush();
128+
129+
byte[] digest = digestStream.getTransmittedDigest();
130+
byte[] encryptedData = encryptedStream.toByteArray();
131+
132+
encryptedStream.close();
133+
inputStream.close();
134+
135+
File cipherFile = writeToFile(encryptedData);
136+
137+
InputStream decryptedStream = AttachmentCipherInputStream.createForAttachment(cipherFile, length, key, digest);
138+
byte[] plaintextOutput = readInputStreamFully(decryptedStream);
139+
140+
assertArrayEquals(plaintextInput, plaintextOutput);
141+
142+
cipherFile.delete();
143+
}
144+
}
145+
106146
@Test
107147
public void attachment_decryptFailOnNullDigest() throws IOException {
108148
File cipherFile = null;

0 commit comments

Comments
 (0)