Massive refactoring to merge handling of simplex and duplex connections.

This commit is contained in:
akwizgran
2014-11-04 16:51:25 +00:00
parent b24f153704
commit 7b8181e309
67 changed files with 1981 additions and 2288 deletions

View File

@@ -1,12 +1,11 @@
package org.briarproject.transport;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MIN_STREAM_LENGTH;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
@@ -14,13 +13,9 @@ import java.util.Random;
import org.briarproject.BriarTestCase;
import org.briarproject.TestLifecycleModule;
import org.briarproject.TestSystemModule;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.crypto.AuthenticatedCipher;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamWriter;
import org.briarproject.api.transport.StreamWriterFactory;
import org.briarproject.crypto.CryptoModule;
import org.junit.Test;
@@ -35,13 +30,10 @@ public class TransportIntegrationTest extends BriarTestCase {
private final int FRAME_LENGTH = 2048;
private final CryptoComponent crypto;
private final StreamWriterFactory streamWriterFactory;
private final ContactId contactId;
private final TransportId transportId;
private final AuthenticatedCipher frameCipher;
private final Random random;
private final byte[] secret;
private final SecretKey frameKey;
private final SecretKey tagKey, frameKey;
public TransportIntegrationTest() {
Module testModule = new AbstractModule() {
@@ -54,15 +46,13 @@ public class TransportIntegrationTest extends BriarTestCase {
Injector i = Guice.createInjector(testModule, new CryptoModule(),
new TestLifecycleModule(), new TestSystemModule());
crypto = i.getInstance(CryptoComponent.class);
streamWriterFactory = i.getInstance(StreamWriterFactory.class);
contactId = new ContactId(234);
transportId = new TransportId("id");
frameCipher = crypto.getFrameCipher();
random = new Random();
// Since we're sending frames to ourselves, we only need outgoing keys
secret = new byte[32];
random.nextBytes(secret);
frameKey = crypto.deriveFrameKey(secret, 0, true, true);
tagKey = crypto.deriveTagKey(secret, true);
frameKey = crypto.deriveFrameKey(secret, 0, true);
}
@Test
@@ -76,6 +66,9 @@ public class TransportIntegrationTest extends BriarTestCase {
}
private void testWriteAndRead(boolean initiator) throws Exception {
// Encode the tag
byte[] tag = new byte[TAG_LENGTH];
crypto.encodeTag(tag, tagKey, 0);
// Generate two random frames
byte[] frame = new byte[1234];
random.nextBytes(frame);
@@ -83,87 +76,46 @@ public class TransportIntegrationTest extends BriarTestCase {
random.nextBytes(frame1);
// Copy the frame key - the copy will be erased
SecretKey frameCopy = frameKey.copy();
// Write the frames
// Write the tag and the frames
ByteArrayOutputStream out = new ByteArrayOutputStream();
FrameWriter encryptionOut = new OutgoingEncryptionLayer(out,
Long.MAX_VALUE, frameCipher, frameCopy, FRAME_LENGTH);
StreamWriterImpl writer = new StreamWriterImpl(encryptionOut,
FrameWriter frameWriter = new OutgoingEncryptionLayer(out,
frameCipher, frameCopy, FRAME_LENGTH, tag);
StreamWriterImpl streamWriter = new StreamWriterImpl(frameWriter,
FRAME_LENGTH);
OutputStream out1 = writer.getOutputStream();
OutputStream out1 = streamWriter.getOutputStream();
out1.write(frame);
out1.flush();
out1.write(frame1);
out1.flush();
byte[] output = out.toByteArray();
assertEquals(FRAME_LENGTH * 2, output.length);
// Read the tag and the frames back
assertEquals(TAG_LENGTH + FRAME_LENGTH * 2, output.length);
// Read the tag back
ByteArrayInputStream in = new ByteArrayInputStream(output);
FrameReader encryptionIn = new IncomingEncryptionLayer(in, frameCipher,
byte[] recoveredTag = new byte[tag.length];
read(in, recoveredTag);
assertArrayEquals(tag, recoveredTag);
// Read the frames back
FrameReader frameReader = new IncomingEncryptionLayer(in, frameCipher,
frameKey, FRAME_LENGTH);
StreamReaderImpl reader = new StreamReaderImpl(encryptionIn,
StreamReaderImpl streamReader = new StreamReaderImpl(frameReader,
FRAME_LENGTH);
InputStream in1 = reader.getInputStream();
byte[] recovered = new byte[frame.length];
InputStream in1 = streamReader.getInputStream();
byte[] recoveredFrame = new byte[frame.length];
read(in1, recoveredFrame);
assertArrayEquals(frame, recoveredFrame);
byte[] recoveredFrame1 = new byte[frame1.length];
read(in1, recoveredFrame1);
assertArrayEquals(frame1, recoveredFrame1);
streamWriter.close();
streamReader.close();
}
private void read(InputStream in, byte[] dest) throws IOException {
int offset = 0;
while(offset < recovered.length) {
int read = in1.read(recovered, offset, recovered.length - offset);
while(offset < dest.length) {
int read = in.read(dest, offset, dest.length - offset);
if(read == -1) break;
offset += read;
}
assertEquals(recovered.length, offset);
assertArrayEquals(frame, recovered);
byte[] recovered1 = new byte[frame1.length];
offset = 0;
while(offset < recovered1.length) {
int read = in1.read(recovered1, offset, recovered1.length - offset);
if(read == -1) break;
offset += read;
}
assertEquals(recovered1.length, offset);
assertArrayEquals(frame1, recovered1);
writer.close();
reader.close();
}
@Test
public void testOverheadWithTag() throws Exception {
ByteArrayOutputStream out =
new ByteArrayOutputStream(MIN_STREAM_LENGTH);
StreamContext ctx = new StreamContext(contactId, transportId,
secret, 0, true);
StreamWriter w = streamWriterFactory.createStreamWriter(out,
MAX_FRAME_LENGTH, MIN_STREAM_LENGTH, ctx, false, true);
// Check that the connection writer thinks there's room for a packet
long capacity = w.getRemainingCapacity();
assertTrue(capacity > MAX_PACKET_LENGTH);
assertTrue(capacity < MIN_STREAM_LENGTH);
// Check that there really is room for a packet
byte[] payload = new byte[MAX_PACKET_LENGTH];
w.getOutputStream().write(payload);
w.getOutputStream().close();
long used = out.size();
assertTrue(used > MAX_PACKET_LENGTH);
assertTrue(used <= MIN_STREAM_LENGTH);
}
@Test
public void testOverheadWithoutTag() throws Exception {
ByteArrayOutputStream out =
new ByteArrayOutputStream(MIN_STREAM_LENGTH);
StreamContext ctx = new StreamContext(contactId, transportId,
secret, 0, true);
StreamWriter w = streamWriterFactory.createStreamWriter(out,
MAX_FRAME_LENGTH, MIN_STREAM_LENGTH, ctx, false, false);
// Check that the connection writer thinks there's room for a packet
long capacity = w.getRemainingCapacity();
assertTrue(capacity > MAX_PACKET_LENGTH);
assertTrue(capacity < MIN_STREAM_LENGTH);
// Check that there really is room for a packet
byte[] payload = new byte[MAX_PACKET_LENGTH];
w.getOutputStream().write(payload);
w.getOutputStream().close();
long used = out.size();
assertTrue(used > MAX_PACKET_LENGTH);
assertTrue(used <= MIN_STREAM_LENGTH);
}
}