diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java index cb708eb4cf54ab2a913248fa891fc49776afbe1f..59afd8531f6f3cdc011b2da46d5d6994dbb0bcd2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java @@ -62,6 +62,8 @@ class StreamEncrypterImpl implements StreamEncrypter { @Override public void writeFrame(byte[] payload, int payloadLength, int paddingLength, boolean finalFrame) throws IOException { + if (payloadLength < 0 || paddingLength < 0) + throw new IllegalArgumentException(); if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH) throw new IllegalArgumentException(); // Don't allow the frame counter to wrap diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java index 8ed35336d4523771f65848eb82fa3f5b7fb317b1..c13749f684170dcc55593cb616fc23f5e9331938 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java @@ -9,9 +9,13 @@ import java.io.ByteArrayOutputStream; import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.MAC_LENGTH; +import static org.briarproject.bramble.api.transport.TransportConstants.MAX_FRAME_LENGTH; +import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH; +import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; public class StreamEncrypterImplTest extends BrambleTestCase { @@ -30,6 +34,58 @@ public class StreamEncrypterImplTest extends BrambleTestCase { payload = TestUtils.getRandomBytes(payloadLength); } + @Test(expected = IllegalArgumentException.class) + public void testRejectsNegativePayloadLength() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, + streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey); + + s.writeFrame(payload, -1, 0, false); + } + + @Test(expected = IllegalArgumentException.class) + public void testRejectsNegativePaddingLength() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, + streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey); + + s.writeFrame(payload, 0, -1, false); + } + + @Test(expected = IllegalArgumentException.class) + public void testRejectsMaxPayloadPlusPadding() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, + streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey); + + byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH + 1]; + s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH, 1, false); + } + + @Test + public void testAcceptsMaxPayloadIncludingPadding() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, + streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey); + + byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH]; + s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH - 1, 1, false); + assertEquals(TAG_LENGTH + STREAM_HEADER_LENGTH + MAX_FRAME_LENGTH, + out.size()); + } + + @Test + public void testAcceptsMaxPayloadWithoutPadding() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, + streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey); + + byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH]; + s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH, 0, false); + assertEquals(TAG_LENGTH + STREAM_HEADER_LENGTH + MAX_FRAME_LENGTH, + out.size()); + } + @Test public void testWriteUnpaddedNonFinalFrameWithTag() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream();