Merge branch '329-btp-header' into 'master'

Include stream number in stream header nonce

See the corresponding change in the BTP spec for an explanation:
388e1d23c0

Closes #329

See merge request !320
This commit is contained in:
akwizgran
2016-09-21 08:58:36 +00:00
8 changed files with 96 additions and 82 deletions

View File

@@ -122,7 +122,7 @@ public class SyncIntegrationTest extends BriarTestCase {
// Create the readers // Create the readers
StreamContext ctx = new StreamContext(contactId, transportId, tagKey, StreamContext ctx = new StreamContext(contactId, transportId, tagKey,
headerKey, 0); headerKey, streamNumber);
InputStream streamReader = streamReaderFactory.createStreamReader(in, InputStream streamReader = streamReaderFactory.createStreamReader(in,
ctx); ctx);
PacketReader packetReader = packetReaderFactory.createPacketReader( PacketReader packetReader = packetReaderFactory.createPacketReader(

View File

@@ -8,11 +8,14 @@ public interface TransportConstants {
/** The length of the pseudo-random tag in bytes. */ /** The length of the pseudo-random tag in bytes. */
int TAG_LENGTH = 16; int TAG_LENGTH = 16;
/** The length of the message authentication code (MAC) in bytes. */ /** The length of the stream header nonce in bytes. */
int MAC_LENGTH = 16; int STREAM_HEADER_NONCE_LENGTH = 24;
/** The length of the stream header initialisation vector (IV) in bytes. */ /** The length of the stream header initialisation vector (IV) in bytes. */
int STREAM_HEADER_IV_LENGTH = 24; int STREAM_HEADER_IV_LENGTH = STREAM_HEADER_NONCE_LENGTH - 8;
/** The length of the message authentication code (MAC) in bytes. */
int MAC_LENGTH = 16;
/** The length of the stream header in bytes. */ /** The length of the stream header in bytes. */
int STREAM_HEADER_LENGTH = STREAM_HEADER_IV_LENGTH + SecretKey.LENGTH int STREAM_HEADER_LENGTH = STREAM_HEADER_IV_LENGTH + SecretKey.LENGTH
@@ -42,7 +45,8 @@ public interface TransportConstants {
* support. Streams may be shorter than this length, but all transport * support. Streams may be shorter than this length, but all transport
* plugins must support streams of at least this length. * plugins must support streams of at least this length.
*/ */
int MIN_STREAM_LENGTH = 64 * 1024; // 64 KiB int MIN_STREAM_LENGTH = STREAM_HEADER_LENGTH + FRAME_HEADER_LENGTH
+ MAC_LENGTH;
/** The maximum difference in milliseconds between two peers' clocks. */ /** The maximum difference in milliseconds between two peers' clocks. */
int MAX_CLOCK_DIFFERENCE = 24 * 60 * 60 * 1000; // 24 hours int MAX_CLOCK_DIFFERENCE = 24 * 60 * 60 * 1000; // 24 hours

View File

@@ -1,15 +1,15 @@
package org.briarproject.crypto; package org.briarproject.crypto;
import java.io.InputStream;
import javax.inject.Inject;
import javax.inject.Provider;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.crypto.StreamDecrypter; import org.briarproject.api.crypto.StreamDecrypter;
import org.briarproject.api.crypto.StreamDecrypterFactory; import org.briarproject.api.crypto.StreamDecrypterFactory;
import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.StreamContext;
import java.io.InputStream;
import javax.inject.Inject;
import javax.inject.Provider;
class StreamDecrypterFactoryImpl implements StreamDecrypterFactory { class StreamDecrypterFactoryImpl implements StreamDecrypterFactory {
private final Provider<AuthenticatedCipher> cipherProvider; private final Provider<AuthenticatedCipher> cipherProvider;
@@ -19,14 +19,17 @@ class StreamDecrypterFactoryImpl implements StreamDecrypterFactory {
this.cipherProvider = cipherProvider; this.cipherProvider = cipherProvider;
} }
@Override
public StreamDecrypter createStreamDecrypter(InputStream in, public StreamDecrypter createStreamDecrypter(InputStream in,
StreamContext ctx) { StreamContext ctx) {
AuthenticatedCipher cipher = cipherProvider.get(); AuthenticatedCipher cipher = cipherProvider.get();
return new StreamDecrypterImpl(in, cipher, ctx.getHeaderKey()); return new StreamDecrypterImpl(in, cipher, ctx.getStreamNumber(),
ctx.getHeaderKey());
} }
@Override
public StreamDecrypter createInvitationStreamDecrypter(InputStream in, public StreamDecrypter createInvitationStreamDecrypter(InputStream in,
SecretKey headerKey) { SecretKey headerKey) {
return new StreamDecrypterImpl(in, cipherProvider.get(), headerKey); return new StreamDecrypterImpl(in, cipherProvider.get(), 0, headerKey);
} }
} }

View File

@@ -3,6 +3,7 @@ package org.briarproject.crypto;
import org.briarproject.api.FormatException; import org.briarproject.api.FormatException;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.crypto.StreamDecrypter; import org.briarproject.api.crypto.StreamDecrypter;
import org.briarproject.util.ByteUtils;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
@@ -17,11 +18,14 @@ import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH
import static org.briarproject.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH; import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH;
import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_LENGTH; import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_LENGTH;
import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_NONCE_LENGTH;
import static org.briarproject.util.ByteUtils.INT_64_BYTES;
class StreamDecrypterImpl implements StreamDecrypter { class StreamDecrypterImpl implements StreamDecrypter {
private final InputStream in; private final InputStream in;
private final AuthenticatedCipher cipher; private final AuthenticatedCipher cipher;
private final long streamNumber;
private final SecretKey streamHeaderKey; private final SecretKey streamHeaderKey;
private final byte[] frameNonce, frameHeader, frameCiphertext; private final byte[] frameNonce, frameHeader, frameCiphertext;
@@ -30,9 +34,10 @@ class StreamDecrypterImpl implements StreamDecrypter {
private boolean finalFrame; private boolean finalFrame;
StreamDecrypterImpl(InputStream in, AuthenticatedCipher cipher, StreamDecrypterImpl(InputStream in, AuthenticatedCipher cipher,
SecretKey streamHeaderKey) { long streamNumber, SecretKey streamHeaderKey) {
this.in = in; this.in = in;
this.cipher = cipher; this.cipher = cipher;
this.streamNumber = streamNumber;
this.streamHeaderKey = streamHeaderKey; this.streamHeaderKey = streamHeaderKey;
frameNonce = new byte[FRAME_NONCE_LENGTH]; frameNonce = new byte[FRAME_NONCE_LENGTH];
frameHeader = new byte[FRAME_HEADER_PLAINTEXT_LENGTH]; frameHeader = new byte[FRAME_HEADER_PLAINTEXT_LENGTH];
@@ -42,6 +47,7 @@ class StreamDecrypterImpl implements StreamDecrypter {
finalFrame = false; finalFrame = false;
} }
@Override
public int readFrame(byte[] payload) throws IOException { public int readFrame(byte[] payload) throws IOException {
// The buffer must be big enough for a full-size frame // The buffer must be big enough for a full-size frame
if (payload.length < MAX_PAYLOAD_LENGTH) if (payload.length < MAX_PAYLOAD_LENGTH)
@@ -103,7 +109,6 @@ class StreamDecrypterImpl implements StreamDecrypter {
} }
private void readStreamHeader() throws IOException { private void readStreamHeader() throws IOException {
byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH];
byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH]; byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
byte[] streamHeaderPlaintext = new byte[SecretKey.LENGTH]; byte[] streamHeaderPlaintext = new byte[SecretKey.LENGTH];
// Read the stream header // Read the stream header
@@ -114,11 +119,14 @@ class StreamDecrypterImpl implements StreamDecrypter {
if (read == -1) throw new EOFException(); if (read == -1) throw new EOFException();
offset += read; offset += read;
} }
// The nonce consists of the stream number followed by the IV
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
ByteUtils.writeUint64(streamNumber, streamHeaderNonce, 0);
System.arraycopy(streamHeaderCiphertext, 0, streamHeaderNonce,
INT_64_BYTES, STREAM_HEADER_IV_LENGTH);
// Decrypt and authenticate the stream header // Decrypt and authenticate the stream header
System.arraycopy(streamHeaderCiphertext, 0, streamHeaderIv, 0,
STREAM_HEADER_IV_LENGTH);
try { try {
cipher.init(false, streamHeaderKey, streamHeaderIv); cipher.init(false, streamHeaderKey, streamHeaderNonce);
int decrypted = cipher.process(streamHeaderCiphertext, int decrypted = cipher.process(streamHeaderCiphertext,
STREAM_HEADER_IV_LENGTH, SecretKey.LENGTH + MAC_LENGTH, STREAM_HEADER_IV_LENGTH, SecretKey.LENGTH + MAC_LENGTH,
streamHeaderPlaintext, 0); streamHeaderPlaintext, 0);

View File

@@ -26,25 +26,28 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory {
this.cipherProvider = cipherProvider; this.cipherProvider = cipherProvider;
} }
@Override
public StreamEncrypter createStreamEncrypter(OutputStream out, public StreamEncrypter createStreamEncrypter(OutputStream out,
StreamContext ctx) { StreamContext ctx) {
AuthenticatedCipher cipher = cipherProvider.get(); AuthenticatedCipher cipher = cipherProvider.get();
long streamNumber = ctx.getStreamNumber();
byte[] tag = new byte[TAG_LENGTH]; byte[] tag = new byte[TAG_LENGTH];
crypto.encodeTag(tag, ctx.getTagKey(), ctx.getStreamNumber()); crypto.encodeTag(tag, ctx.getTagKey(), streamNumber);
byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH]; byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH];
crypto.getSecureRandom().nextBytes(streamHeaderIv); crypto.getSecureRandom().nextBytes(streamHeaderIv);
SecretKey frameKey = crypto.generateSecretKey(); SecretKey frameKey = crypto.generateSecretKey();
return new StreamEncrypterImpl(out, cipher, tag, streamHeaderIv, return new StreamEncrypterImpl(out, cipher, streamNumber, tag,
ctx.getHeaderKey(), frameKey); streamHeaderIv, ctx.getHeaderKey(), frameKey);
} }
@Override
public StreamEncrypter createInvitationStreamEncrypter(OutputStream out, public StreamEncrypter createInvitationStreamEncrypter(OutputStream out,
SecretKey headerKey) { SecretKey headerKey) {
AuthenticatedCipher cipher = cipherProvider.get(); AuthenticatedCipher cipher = cipherProvider.get();
byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH]; byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH];
crypto.getSecureRandom().nextBytes(streamHeaderIv); crypto.getSecureRandom().nextBytes(streamHeaderIv);
SecretKey frameKey = crypto.generateSecretKey(); SecretKey frameKey = crypto.generateSecretKey();
return new StreamEncrypterImpl(out, cipher, null, streamHeaderIv, return new StreamEncrypterImpl(out, cipher, 0, null, streamHeaderIv,
headerKey, frameKey); headerKey, frameKey);
} }
} }

View File

@@ -2,6 +2,8 @@ package org.briarproject.crypto;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.crypto.StreamEncrypter; import org.briarproject.api.crypto.StreamEncrypter;
import org.briarproject.util.ByteUtils;
import org.jetbrains.annotations.Nullable;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
@@ -15,23 +17,28 @@ import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH
import static org.briarproject.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH; import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH;
import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_LENGTH; import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_LENGTH;
import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_NONCE_LENGTH;
import static org.briarproject.util.ByteUtils.INT_64_BYTES;
class StreamEncrypterImpl implements StreamEncrypter { class StreamEncrypterImpl implements StreamEncrypter {
private final OutputStream out; private final OutputStream out;
private final AuthenticatedCipher cipher; private final AuthenticatedCipher cipher;
private final SecretKey streamHeaderKey, frameKey; private final SecretKey streamHeaderKey, frameKey;
private final long streamNumber;
private final byte[] tag, streamHeaderIv; private final byte[] tag, streamHeaderIv;
private final byte[] frameNonce, frameHeader, framePlaintext, frameCiphertext; private final byte[] frameNonce, frameHeader;
private final byte[] framePlaintext, frameCiphertext;
private long frameNumber; private long frameNumber;
private boolean writeTag, writeStreamHeader; private boolean writeTag, writeStreamHeader;
StreamEncrypterImpl(OutputStream out, AuthenticatedCipher cipher, StreamEncrypterImpl(OutputStream out, AuthenticatedCipher cipher,
byte[] tag, byte[] streamHeaderIv, SecretKey streamHeaderKey, long streamNumber, @Nullable byte[] tag, byte[] streamHeaderIv,
SecretKey frameKey) { SecretKey streamHeaderKey, SecretKey frameKey) {
this.out = out; this.out = out;
this.cipher = cipher; this.cipher = cipher;
this.streamNumber = streamNumber;
this.tag = tag; this.tag = tag;
this.streamHeaderIv = streamHeaderIv; this.streamHeaderIv = streamHeaderIv;
this.streamHeaderKey = streamHeaderKey; this.streamHeaderKey = streamHeaderKey;
@@ -45,6 +52,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
writeStreamHeader = true; writeStreamHeader = true;
} }
@Override
public void writeFrame(byte[] payload, int payloadLength, public void writeFrame(byte[] payload, int payloadLength,
int paddingLength, boolean finalFrame) throws IOException { int paddingLength, boolean finalFrame) throws IOException {
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH) if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
@@ -91,18 +99,24 @@ class StreamEncrypterImpl implements StreamEncrypter {
} }
private void writeTag() throws IOException { private void writeTag() throws IOException {
if (tag == null) throw new IllegalStateException();
out.write(tag, 0, tag.length); out.write(tag, 0, tag.length);
writeTag = false; writeTag = false;
} }
private void writeStreamHeader() throws IOException { private void writeStreamHeader() throws IOException {
// The nonce consists of the stream number followed by the IV
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
ByteUtils.writeUint64(streamNumber, streamHeaderNonce, 0);
System.arraycopy(streamHeaderIv, 0, streamHeaderNonce, INT_64_BYTES,
STREAM_HEADER_IV_LENGTH);
byte[] streamHeaderPlaintext = frameKey.getBytes(); byte[] streamHeaderPlaintext = frameKey.getBytes();
byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH]; byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
System.arraycopy(streamHeaderIv, 0, streamHeaderCiphertext, 0, System.arraycopy(streamHeaderIv, 0, streamHeaderCiphertext, 0,
STREAM_HEADER_IV_LENGTH); STREAM_HEADER_IV_LENGTH);
// Encrypt and authenticate the frame key // Encrypt and authenticate the frame key
try { try {
cipher.init(true, streamHeaderKey, streamHeaderIv); cipher.init(true, streamHeaderKey, streamHeaderNonce);
int encrypted = cipher.process(streamHeaderPlaintext, 0, int encrypted = cipher.process(streamHeaderPlaintext, 0,
SecretKey.LENGTH, streamHeaderCiphertext, SecretKey.LENGTH, streamHeaderCiphertext,
STREAM_HEADER_IV_LENGTH); STREAM_HEADER_IV_LENGTH);
@@ -115,6 +129,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
writeStreamHeader = false; writeStreamHeader = false;
} }
@Override
public void flush() throws IOException { public void flush() throws IOException {
// Write the tag if required // Write the tag if required
if (writeTag) writeTag(); if (writeTag) writeTag();

View File

@@ -22,22 +22,23 @@ public class StreamDecrypterImplTest extends BriarTestCase {
private final AuthenticatedCipher cipher; private final AuthenticatedCipher cipher;
private final SecretKey streamHeaderKey, frameKey; private final SecretKey streamHeaderKey, frameKey;
private final byte[] streamHeaderIv; private final byte[] streamHeaderIv, payload;
private final int payloadLength = 123, paddingLength = 234;
private final long streamNumber = 1234;
public StreamDecrypterImplTest() { public StreamDecrypterImplTest() {
cipher = new TestAuthenticatedCipher(); // Null cipher cipher = new TestAuthenticatedCipher(); // Null cipher
streamHeaderKey = TestUtils.getSecretKey(); streamHeaderKey = TestUtils.getSecretKey();
frameKey = TestUtils.getSecretKey(); frameKey = TestUtils.getSecretKey();
streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH); streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH);
payload = TestUtils.getRandomBytes(payloadLength);
} }
@Test @Test
public void testReadValidFrames() throws Exception { public void testReadValidFrames() throws Exception {
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH]; byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
int payloadLength = 123, paddingLength = 234;
FrameEncoder.encodeHeader(frameHeader, false, payloadLength, FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
paddingLength); paddingLength);
byte[] payload = TestUtils.getRandomBytes(payloadLength);
byte[] frameHeader1 = new byte[FRAME_HEADER_LENGTH]; byte[] frameHeader1 = new byte[FRAME_HEADER_LENGTH];
int payloadLength1 = 345, paddingLength1 = 456; int payloadLength1 = 345, paddingLength1 = 456;
@@ -60,7 +61,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher, StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
streamHeaderKey); streamNumber, streamHeaderKey);
// Read the first frame // Read the first frame
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH]; byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -78,10 +79,9 @@ public class StreamDecrypterImplTest extends BriarTestCase {
@Test(expected = IOException.class) @Test(expected = IOException.class)
public void testTruncatedFrameThrowsException() throws Exception { public void testTruncatedFrameThrowsException() throws Exception {
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH]; byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
int payloadLength = 123, paddingLength = 234;
FrameEncoder.encodeHeader(frameHeader, false, payloadLength, FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
paddingLength); paddingLength);
byte[] payload = TestUtils.getRandomBytes(payloadLength);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(streamHeaderIv); out.write(streamHeaderIv);
out.write(frameKey.getBytes()); out.write(frameKey.getBytes());
@@ -93,7 +93,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher, StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
streamHeaderKey); streamNumber, streamHeaderKey);
// Try to read the truncated frame // Try to read the truncated frame
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH]; byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -121,7 +121,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher, StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
streamHeaderKey); streamNumber, streamHeaderKey);
// Try to read the invalid frame // Try to read the invalid frame
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH]; byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -131,10 +131,8 @@ public class StreamDecrypterImplTest extends BriarTestCase {
@Test(expected = IOException.class) @Test(expected = IOException.class)
public void testNonZeroPaddingThrowsException() throws Exception { public void testNonZeroPaddingThrowsException() throws Exception {
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH]; byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
int payloadLength = 123, paddingLength = 234;
FrameEncoder.encodeHeader(frameHeader, false, payloadLength, FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
paddingLength); paddingLength);
byte[] payload = TestUtils.getRandomBytes(payloadLength);
// Set one of the padding bytes non-zero // Set one of the padding bytes non-zero
byte[] padding = new byte[paddingLength]; byte[] padding = new byte[paddingLength];
padding[paddingLength - 1] = 1; padding[paddingLength - 1] = 1;
@@ -150,7 +148,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher, StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
streamHeaderKey); streamNumber, streamHeaderKey);
// Try to read the invalid frame // Try to read the invalid frame
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH]; byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -160,10 +158,8 @@ public class StreamDecrypterImplTest extends BriarTestCase {
@Test @Test
public void testCannotReadBeyondFinalFrame() throws Exception { public void testCannotReadBeyondFinalFrame() throws Exception {
byte[] frameHeader = new byte[FRAME_HEADER_LENGTH]; byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
int payloadLength = 123, paddingLength = 234;
FrameEncoder.encodeHeader(frameHeader, true, payloadLength, FrameEncoder.encodeHeader(frameHeader, true, payloadLength,
paddingLength); paddingLength);
byte[] payload = TestUtils.getRandomBytes(payloadLength);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(streamHeaderIv); out.write(streamHeaderIv);
@@ -178,7 +174,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher, StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
streamHeaderKey); streamNumber, streamHeaderKey);
// Read the first frame // Read the first frame
byte[] buffer = new byte[MAX_PAYLOAD_LENGTH]; byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];

View File

@@ -17,7 +17,9 @@ public class StreamEncrypterImplTest extends BriarTestCase {
private final AuthenticatedCipher cipher; private final AuthenticatedCipher cipher;
private final SecretKey streamHeaderKey, frameKey; private final SecretKey streamHeaderKey, frameKey;
private final byte[] tag, streamHeaderIv; private final byte[] tag, streamHeaderIv, payload;
private final long streamNumber = 1234;
private final int payloadLength = 123, paddingLength = 234;
public StreamEncrypterImplTest() { public StreamEncrypterImplTest() {
cipher = new TestAuthenticatedCipher(); // Null cipher cipher = new TestAuthenticatedCipher(); // Null cipher
@@ -25,15 +27,14 @@ public class StreamEncrypterImplTest extends BriarTestCase {
frameKey = TestUtils.getSecretKey(); frameKey = TestUtils.getSecretKey();
tag = TestUtils.getRandomBytes(TAG_LENGTH); tag = TestUtils.getRandomBytes(TAG_LENGTH);
streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH); streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH);
payload = TestUtils.getRandomBytes(payloadLength);
} }
@Test @Test
public void testWriteUnpaddedNonFinalFrameWithTag() throws Exception { public void testWriteUnpaddedNonFinalFrameWithTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, 0, false); s.writeFrame(payload, payloadLength, 0, false);
@@ -55,10 +56,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWriteUnpaddedFinalFrameWithTag() throws Exception { public void testWriteUnpaddedFinalFrameWithTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, 0, true); s.writeFrame(payload, payloadLength, 0, true);
@@ -80,10 +79,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWriteUnpaddedNonFinalFrameWithoutTag() throws Exception { public void testWriteUnpaddedNonFinalFrameWithoutTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, 0, false); s.writeFrame(payload, payloadLength, 0, false);
@@ -104,10 +101,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWriteUnpaddedFinalFrameWithoutTag() throws Exception { public void testWriteUnpaddedFinalFrameWithoutTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, 0, true); s.writeFrame(payload, payloadLength, 0, true);
@@ -128,10 +123,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWritePaddedNonFinalFrameWithTag() throws Exception { public void testWritePaddedNonFinalFrameWithTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123, paddingLength = 234;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, paddingLength, false); s.writeFrame(payload, payloadLength, paddingLength, false);
@@ -155,10 +148,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWritePaddedFinalFrameWithTag() throws Exception { public void testWritePaddedFinalFrameWithTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123, paddingLength = 234;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, paddingLength, true); s.writeFrame(payload, payloadLength, paddingLength, true);
@@ -182,10 +173,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWritePaddedNonFinalFrameWithoutTag() throws Exception { public void testWritePaddedNonFinalFrameWithoutTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123, paddingLength = 234;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, paddingLength, false); s.writeFrame(payload, payloadLength, paddingLength, false);
@@ -208,10 +197,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWritePaddedFinalFrameWithoutTag() throws Exception { public void testWritePaddedFinalFrameWithoutTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123, paddingLength = 234;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
s.writeFrame(payload, payloadLength, paddingLength, true); s.writeFrame(payload, payloadLength, paddingLength, true);
@@ -234,10 +221,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testWriteTwoFramesWithTag() throws Exception { public void testWriteTwoFramesWithTag() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
int payloadLength = 123, paddingLength = 234;
byte[] payload = TestUtils.getRandomBytes(payloadLength);
int payloadLength1 = 345, paddingLength1 = 456; int payloadLength1 = 345, paddingLength1 = 456;
byte[] payload1 = TestUtils.getRandomBytes(payloadLength1); byte[] payload1 = TestUtils.getRandomBytes(payloadLength1);
@@ -273,8 +258,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
public void testFlushWritesTagAndStreamHeaderIfNotAlreadyWritten() public void testFlushWritesTagAndStreamHeaderIfNotAlreadyWritten()
throws Exception { throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
// Flush the stream once // Flush the stream once
s.flush(); s.flush();
@@ -293,8 +278,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
public void testFlushDoesNotWriteTagOrStreamHeaderIfAlreadyWritten() public void testFlushDoesNotWriteTagOrStreamHeaderIfAlreadyWritten()
throws Exception { throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
// Flush the stream twice // Flush the stream twice
s.flush(); s.flush();
@@ -313,8 +298,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
@Test @Test
public void testFlushDoesNotWriteTagIfNull() throws Exception { public void testFlushDoesNotWriteTagIfNull() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null, StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
streamHeaderIv, streamHeaderKey, frameKey); streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
// Flush the stream once // Flush the stream once
s.flush(); s.flush();