mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 04:39:54 +01:00
Protocol versioning for BTP.
This commit is contained in:
@@ -14,7 +14,8 @@ import static junit.framework.Assert.assertEquals;
|
||||
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_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_NONCE_LENGTH;
|
||||
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
@@ -22,7 +23,8 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
|
||||
private final AuthenticatedCipher cipher;
|
||||
private final SecretKey streamHeaderKey, frameKey;
|
||||
private final byte[] streamHeaderIv, payload;
|
||||
private final byte[] streamHeaderNonce, protocolVersionBytes;
|
||||
private final byte[] streamNumberBytes, payload;
|
||||
private final int payloadLength = 123, paddingLength = 234;
|
||||
private final long streamNumber = 1234;
|
||||
|
||||
@@ -30,7 +32,12 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
cipher = new TestAuthenticatedCipher(); // Null cipher
|
||||
streamHeaderKey = TestUtils.getSecretKey();
|
||||
frameKey = TestUtils.getSecretKey();
|
||||
streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH);
|
||||
streamHeaderNonce =
|
||||
TestUtils.getRandomBytes(STREAM_HEADER_NONCE_LENGTH);
|
||||
protocolVersionBytes = new byte[2];
|
||||
ByteUtils.writeUint16(PROTOCOL_VERSION, protocolVersionBytes, 0);
|
||||
streamNumberBytes = new byte[8];
|
||||
ByteUtils.writeUint64(streamNumber, streamNumberBytes, 0);
|
||||
payload = TestUtils.getRandomBytes(payloadLength);
|
||||
}
|
||||
|
||||
@@ -47,7 +54,9 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
byte[] payload1 = TestUtils.getRandomBytes(payloadLength1);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderIv);
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(protocolVersionBytes);
|
||||
out.write(streamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
@@ -76,6 +85,85 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
assertEquals(-1, s.readFrame(buffer));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void testWrongProtocolVersionThrowsException() throws Exception {
|
||||
byte[] wrongProtocolVersionBytes = new byte[2];
|
||||
ByteUtils.writeUint16(PROTOCOL_VERSION + 1, wrongProtocolVersionBytes,
|
||||
0);
|
||||
|
||||
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
|
||||
paddingLength);
|
||||
|
||||
byte[] frameHeader1 = new byte[FRAME_HEADER_LENGTH];
|
||||
int payloadLength1 = 345, paddingLength1 = 456;
|
||||
FrameEncoder.encodeHeader(frameHeader1, true, payloadLength1,
|
||||
paddingLength1);
|
||||
byte[] payload1 = TestUtils.getRandomBytes(payloadLength1);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(wrongProtocolVersionBytes);
|
||||
out.write(streamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
out.write(payload);
|
||||
out.write(new byte[paddingLength]);
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader1);
|
||||
out.write(payload1);
|
||||
out.write(new byte[paddingLength1]);
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
|
||||
streamNumber, streamHeaderKey);
|
||||
|
||||
// Try to read the first frame
|
||||
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
|
||||
s.readFrame(buffer);
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void testWrongStreamNumberThrowsException() throws Exception {
|
||||
byte[] wrongStreamNumberBytes = new byte[8];
|
||||
ByteUtils.writeUint64(streamNumber + 1, wrongStreamNumberBytes, 0);
|
||||
|
||||
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
|
||||
paddingLength);
|
||||
|
||||
byte[] frameHeader1 = new byte[FRAME_HEADER_LENGTH];
|
||||
int payloadLength1 = 345, paddingLength1 = 456;
|
||||
FrameEncoder.encodeHeader(frameHeader1, true, payloadLength1,
|
||||
paddingLength1);
|
||||
byte[] payload1 = TestUtils.getRandomBytes(payloadLength1);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(protocolVersionBytes);
|
||||
out.write(wrongStreamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
out.write(payload);
|
||||
out.write(new byte[paddingLength]);
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader1);
|
||||
out.write(payload1);
|
||||
out.write(new byte[paddingLength1]);
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
|
||||
streamNumber, streamHeaderKey);
|
||||
|
||||
// Try to read the first frame
|
||||
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
|
||||
s.readFrame(buffer);
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void testTruncatedFrameThrowsException() throws Exception {
|
||||
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -83,7 +171,9 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
paddingLength);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderIv);
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(protocolVersionBytes);
|
||||
out.write(streamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
@@ -111,7 +201,9 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
byte[] payload = TestUtils.getRandomBytes(payloadLength);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderIv);
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(protocolVersionBytes);
|
||||
out.write(streamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
@@ -138,7 +230,9 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
padding[paddingLength - 1] = 1;
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderIv);
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(protocolVersionBytes);
|
||||
out.write(streamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
@@ -162,7 +256,9 @@ public class StreamDecrypterImplTest extends BrambleTestCase {
|
||||
paddingLength);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(streamHeaderIv);
|
||||
out.write(streamHeaderNonce);
|
||||
out.write(protocolVersionBytes);
|
||||
out.write(streamNumberBytes);
|
||||
out.write(frameKey.getBytes());
|
||||
out.write(new byte[MAC_LENGTH]);
|
||||
out.write(frameHeader);
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.crypto;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -11,8 +12,9 @@ import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HE
|
||||
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.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_NONCE_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -21,7 +23,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
|
||||
private final AuthenticatedCipher cipher;
|
||||
private final SecretKey streamHeaderKey, frameKey;
|
||||
private final byte[] tag, streamHeaderIv, payload;
|
||||
private final byte[] tag, streamHeaderNonce, protocolVersionBytes;
|
||||
private final byte[] streamNumberBytes, payload;
|
||||
private final long streamNumber = 1234;
|
||||
private final int payloadLength = 123, paddingLength = 234;
|
||||
|
||||
@@ -30,7 +33,12 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
streamHeaderKey = TestUtils.getSecretKey();
|
||||
frameKey = TestUtils.getSecretKey();
|
||||
tag = TestUtils.getRandomBytes(TAG_LENGTH);
|
||||
streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH);
|
||||
streamHeaderNonce =
|
||||
TestUtils.getRandomBytes(STREAM_HEADER_NONCE_LENGTH);
|
||||
protocolVersionBytes = new byte[2];
|
||||
ByteUtils.writeUint16(PROTOCOL_VERSION, protocolVersionBytes, 0);
|
||||
streamNumberBytes = new byte[8];
|
||||
ByteUtils.writeUint64(streamNumber, streamNumberBytes, 0);
|
||||
payload = TestUtils.getRandomBytes(payloadLength);
|
||||
}
|
||||
|
||||
@@ -38,7 +46,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testRejectsNegativePayloadLength() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, -1, 0, false);
|
||||
}
|
||||
@@ -47,7 +56,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testRejectsNegativePaddingLength() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, 0, -1, false);
|
||||
}
|
||||
@@ -56,7 +66,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testRejectsMaxPayloadPlusPadding() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH + 1];
|
||||
s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH, 1, false);
|
||||
@@ -66,7 +77,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testAcceptsMaxPayloadIncludingPadding() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH];
|
||||
s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH - 1, 1, false);
|
||||
@@ -78,7 +90,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testAcceptsMaxPayloadWithoutPadding() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH];
|
||||
s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH, 0, false);
|
||||
@@ -90,14 +103,17 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWriteUnpaddedNonFinalFrameWithTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, 0, false);
|
||||
|
||||
// Expect the tag, stream header, frame header, payload and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -113,14 +129,17 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWriteUnpaddedFinalFrameWithTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, 0, true);
|
||||
|
||||
// Expect the tag, stream header, frame header, payload and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -136,13 +155,16 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWriteUnpaddedNonFinalFrameWithoutTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, null, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, 0, false);
|
||||
|
||||
// Expect the stream header, frame header, payload and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -158,13 +180,16 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWriteUnpaddedFinalFrameWithoutTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, null, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, 0, true);
|
||||
|
||||
// Expect the stream header, frame header, payload and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -180,14 +205,17 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWritePaddedNonFinalFrameWithTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, paddingLength, false);
|
||||
|
||||
// Expect the tag, stream header, frame header, payload, padding and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -205,14 +233,17 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWritePaddedFinalFrameWithTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, paddingLength, true);
|
||||
|
||||
// Expect the tag, stream header, frame header, payload, padding and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -230,13 +261,16 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWritePaddedNonFinalFrameWithoutTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, null, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, paddingLength, false);
|
||||
|
||||
// Expect the stream header, frame header, payload, padding and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -254,13 +288,16 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWritePaddedFinalFrameWithoutTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, null, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
s.writeFrame(payload, payloadLength, paddingLength, true);
|
||||
|
||||
// Expect the stream header, frame header, payload, padding and MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -278,7 +315,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testWriteTwoFramesWithTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
int payloadLength1 = 345, paddingLength1 = 456;
|
||||
byte[] payload1 = TestUtils.getRandomBytes(payloadLength1);
|
||||
|
||||
@@ -289,7 +327,9 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
// MAC, second frame header, payload, padding, MAC
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
byte[] expectedFrameHeader = new byte[FRAME_HEADER_LENGTH];
|
||||
@@ -315,7 +355,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
// Flush the stream once
|
||||
s.flush();
|
||||
@@ -323,7 +364,9 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
// Expect the tag and stream header
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
|
||||
@@ -335,7 +378,8 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, tag, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
// Flush the stream twice
|
||||
s.flush();
|
||||
@@ -344,7 +388,9 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
// Expect the tag and stream header
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(tag);
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
|
||||
@@ -355,14 +401,17 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
|
||||
public void testFlushDoesNotWriteTagIfNull() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
|
||||
streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
|
||||
streamNumber, null, streamHeaderNonce, streamHeaderKey,
|
||||
frameKey);
|
||||
|
||||
// Flush the stream once
|
||||
s.flush();
|
||||
|
||||
// Expect the stream header
|
||||
ByteArrayOutputStream expected = new ByteArrayOutputStream();
|
||||
expected.write(streamHeaderIv);
|
||||
expected.write(streamHeaderNonce);
|
||||
expected.write(protocolVersionBytes);
|
||||
expected.write(streamNumberBytes);
|
||||
expected.write(frameKey.getBytes());
|
||||
expected.write(new byte[MAC_LENGTH]);
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.TestSecureRandomProvider;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
|
||||
public class TagEncodingTest extends BrambleTestCase {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final SecretKey tagKey;
|
||||
private final long streamNumber = 1234567890;
|
||||
|
||||
public TagEncodingTest() {
|
||||
crypto = new CryptoComponentImpl(new TestSecureRandomProvider());
|
||||
tagKey = TestUtils.getSecretKey();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyAffectsTag() throws Exception {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
SecretKey tagKey = TestUtils.getSecretKey();
|
||||
crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION, streamNumber);
|
||||
assertTrue(set.add(new Bytes(tag)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtocolVersionAffectsTag() throws Exception {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION + i, streamNumber);
|
||||
assertTrue(set.add(new Bytes(tag)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStreamNumberAffectsTag() throws Exception {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION, streamNumber + i);
|
||||
assertTrue(set.add(new Bytes(tag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import java.util.Collection;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -115,7 +116,7 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
||||
private void read(byte[] connectionData) throws Exception {
|
||||
// Calculate the expected tag
|
||||
byte[] expectedTag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(expectedTag, tagKey, streamNumber);
|
||||
crypto.encodeTag(expectedTag, tagKey, PROTOCOL_VERSION, streamNumber);
|
||||
|
||||
// Read the tag
|
||||
InputStream in = new ByteArrayInputStream(connectionData);
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED;
|
||||
@@ -86,7 +87,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets per contact)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(6).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Save the keys that were rotated
|
||||
@@ -133,7 +134,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Save the keys
|
||||
@@ -199,7 +200,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Rotate the transport keys (the keys are unaffected)
|
||||
@@ -247,7 +248,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Rotate the transport keys (the keys are unaffected)
|
||||
@@ -306,7 +307,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Rotate the transport keys (the keys are unaffected)
|
||||
@@ -355,7 +356,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction(tags));
|
||||
}
|
||||
// Rotate the transport keys (the keys are unaffected)
|
||||
@@ -365,7 +366,8 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
||||
// Encode a new tag after sliding the window
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with((long) REORDERING_WINDOW_SIZE));
|
||||
with(tagKey), with(PROTOCOL_VERSION),
|
||||
with((long) REORDERING_WINDOW_SIZE));
|
||||
will(new EncodeTagAction(tags));
|
||||
// Save the reordering window (previous rotation period, base 1)
|
||||
oneOf(db).setReorderingWindow(txn, contactId, transportId, 999,
|
||||
@@ -428,7 +430,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Schedule key rotation at the start of the next rotation period
|
||||
@@ -450,7 +452,7 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(i));
|
||||
with(tagKey), with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
// Save the keys that were rotated
|
||||
|
||||
Reference in New Issue
Block a user