diff --git a/api/net/sf/briar/api/transport/ConnectionReaderFactory.java b/api/net/sf/briar/api/transport/ConnectionReaderFactory.java index ab65da7fec106a0e314976669c96613601fcaf51..fc6f9418ba45cd5c35441a9659dbde79a4565790 100644 --- a/api/net/sf/briar/api/transport/ConnectionReaderFactory.java +++ b/api/net/sf/briar/api/transport/ConnectionReaderFactory.java @@ -6,15 +6,15 @@ public interface ConnectionReaderFactory { /** * Creates a connection reader for a batch-mode connection or the - * initiator's side of a stream-mode connection. + * initiator's side of a stream-mode connection. The secret is erased + * before this method returns. */ - ConnectionReader createConnectionReader(InputStream in, - ConnectionContext ctx, byte[] tag); + ConnectionReader createConnectionReader(InputStream in, byte[] secret, + byte[] tag); /** * Creates a connection reader for the responder's side of a stream-mode - * connection. + * connection. The secret is erased before this method returns. */ - ConnectionReader createConnectionReader(InputStream in, - ConnectionContext ctx); + ConnectionReader createConnectionReader(InputStream in, byte[] secret); } diff --git a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java index 0713e3724c1a783961a6f2f3334460f661dbb2d9..13b03fa38714530786c0d6dd897b0d5fade14963 100644 --- a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java +++ b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java @@ -6,15 +6,16 @@ public interface ConnectionWriterFactory { /** * Creates a connection writer for a batch-mode connection or the - * initiator's side of a stream-mode connection. + * initiator's side of a stream-mode connection. The secret is erased + * before this method returns. */ ConnectionWriter createConnectionWriter(OutputStream out, long capacity, - ConnectionContext ctx); + byte[] secret); /** * Creates a connection writer for the responder's side of a stream-mode - * connection. + * connection. The secret is erased before this method returns. */ ConnectionWriter createConnectionWriter(OutputStream out, long capacity, - ConnectionContext ctx, byte[] tag); + byte[] secret, byte[] tag); } diff --git a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java index 837ce54087d6ace4ec3c16626a9e15403f8d130f..d73a45931cbcb32bb239174f2794d3014a850182 100644 --- a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java @@ -7,7 +7,6 @@ import javax.crypto.Mac; import net.sf.briar.api.crypto.CryptoComponent; import net.sf.briar.api.crypto.ErasableKey; -import net.sf.briar.api.transport.ConnectionContext; import net.sf.briar.api.transport.ConnectionReader; import net.sf.briar.api.transport.ConnectionReaderFactory; import net.sf.briar.util.ByteUtils; @@ -24,25 +23,24 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory { } public ConnectionReader createConnectionReader(InputStream in, - ConnectionContext ctx, byte[] tag) { + byte[] secret, byte[] tag) { // Validate the tag Cipher tagCipher = crypto.getTagCipher(); - ErasableKey tagKey = crypto.deriveTagKey(ctx.getSecret(), true); + ErasableKey tagKey = crypto.deriveTagKey(secret, true); boolean valid = TagEncoder.validateTag(tag, 0, tagCipher, tagKey); tagKey.erase(); if(!valid) throw new IllegalArgumentException(); - return createConnectionReader(in, true, ctx); + return createConnectionReader(in, true, secret); } public ConnectionReader createConnectionReader(InputStream in, - ConnectionContext ctx) { - return createConnectionReader(in, false, ctx); + byte[] secret) { + return createConnectionReader(in, false, secret); } private ConnectionReader createConnectionReader(InputStream in, - boolean initiator, ConnectionContext ctx) { + boolean initiator, byte[] secret) { // Derive the keys and erase the secret - byte[] secret = ctx.getSecret(); ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator); ErasableKey macKey = crypto.deriveMacKey(secret, initiator); ByteUtils.erase(secret); diff --git a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java index 694db4ae77b080e3ca7c1d5562e146d109266963..e0b5288c678e2117bdddc998c4a77e35b47b011b 100644 --- a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java @@ -7,7 +7,6 @@ import javax.crypto.Mac; import net.sf.briar.api.crypto.CryptoComponent; import net.sf.briar.api.crypto.ErasableKey; -import net.sf.briar.api.transport.ConnectionContext; import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.api.transport.ConnectionWriterFactory; import net.sf.briar.util.ByteUtils; @@ -24,25 +23,24 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { } public ConnectionWriter createConnectionWriter(OutputStream out, - long capacity, ConnectionContext ctx) { - return createConnectionWriter(out, capacity, true, ctx); + long capacity, byte[] secret) { + return createConnectionWriter(out, capacity, true, secret); } public ConnectionWriter createConnectionWriter(OutputStream out, - long capacity, ConnectionContext ctx, byte[] tag) { + long capacity, byte[] secret, byte[] tag) { // Decrypt the tag Cipher tagCipher = crypto.getTagCipher(); - ErasableKey tagKey = crypto.deriveTagKey(ctx.getSecret(), true); + ErasableKey tagKey = crypto.deriveTagKey(secret, true); boolean valid = TagEncoder.validateTag(tag, 0, tagCipher, tagKey); tagKey.erase(); if(!valid) throw new IllegalArgumentException(); - return createConnectionWriter(out, capacity, false, ctx); + return createConnectionWriter(out, capacity, false, secret); } private ConnectionWriter createConnectionWriter(OutputStream out, - long capacity, boolean initiator, ConnectionContext ctx) { + long capacity, boolean initiator, byte[] secret) { // Derive the keys and erase the secret - byte[] secret = ctx.getSecret(); ErasableKey tagKey = crypto.deriveTagKey(secret, initiator); ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator); ErasableKey macKey = crypto.deriveMacKey(secret, initiator); diff --git a/components/net/sf/briar/transport/batch/IncomingBatchConnection.java b/components/net/sf/briar/transport/batch/IncomingBatchConnection.java index e7a0b3686bce2115c58f17d10af368a9255303e7..fdcc60541fbc233d9671c95440e9da526e4c5572 100644 --- a/components/net/sf/briar/transport/batch/IncomingBatchConnection.java +++ b/components/net/sf/briar/transport/batch/IncomingBatchConnection.java @@ -45,7 +45,7 @@ class IncomingBatchConnection { void read() { try { ConnectionReader conn = connFactory.createConnectionReader( - reader.getInputStream(), ctx, tag); + reader.getInputStream(), ctx.getSecret(), tag); ProtocolReader proto = protoFactory.createProtocolReader( conn.getInputStream()); ContactId c = ctx.getContactId(); diff --git a/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java b/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java index 88f0f127f361d20b7c81ee08c96d94898a8e1453..84c32cce5e7d429ef7ca2ffffcf686f0cd017c9c 100644 --- a/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java +++ b/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java @@ -50,7 +50,8 @@ class OutgoingBatchConnection { ConnectionContext ctx = db.getConnectionContext(contactId, transportIndex); ConnectionWriter conn = connFactory.createConnectionWriter( - writer.getOutputStream(), writer.getCapacity(), ctx); + writer.getOutputStream(), writer.getCapacity(), + ctx.getSecret()); OutputStream out = conn.getOutputStream(); // There should be enough space for a packet long capacity = conn.getRemainingCapacity(); diff --git a/components/net/sf/briar/transport/stream/IncomingStreamConnection.java b/components/net/sf/briar/transport/stream/IncomingStreamConnection.java index 405001957ea094baa28b1f86498f87eabec6fb5f..16da6c795264aedca9e74e71e9f115a9492cc517 100644 --- a/components/net/sf/briar/transport/stream/IncomingStreamConnection.java +++ b/components/net/sf/briar/transport/stream/IncomingStreamConnection.java @@ -34,13 +34,14 @@ class IncomingStreamConnection extends StreamConnection { protected ConnectionReader createConnectionReader() throws DbException, IOException { return connReaderFactory.createConnectionReader( - connection.getInputStream(), ctx, tag); + connection.getInputStream(), ctx.getSecret(), tag); } @Override protected ConnectionWriter createConnectionWriter() throws DbException, IOException { return connWriterFactory.createConnectionWriter( - connection.getOutputStream(), Long.MAX_VALUE, ctx, tag); + connection.getOutputStream(), Long.MAX_VALUE, ctx.getSecret(), + tag); } } diff --git a/components/net/sf/briar/transport/stream/OutgoingStreamConnection.java b/components/net/sf/briar/transport/stream/OutgoingStreamConnection.java index ba37e28def8261a5ece29bcdc17cac8adb950242..64d61e1306fd879420a18830a45b6117240ae9c0 100644 --- a/components/net/sf/briar/transport/stream/OutgoingStreamConnection.java +++ b/components/net/sf/briar/transport/stream/OutgoingStreamConnection.java @@ -40,7 +40,7 @@ class OutgoingStreamConnection extends StreamConnection { ctx = db.getConnectionContext(contactId, transportIndex); } return connReaderFactory.createConnectionReader( - connection.getInputStream(), ctx); + connection.getInputStream(), ctx.getSecret()); } @Override @@ -51,6 +51,6 @@ class OutgoingStreamConnection extends StreamConnection { ctx = db.getConnectionContext(contactId, transportIndex); } return connWriterFactory.createConnectionWriter( - connection.getOutputStream(), Long.MAX_VALUE, ctx); + connection.getOutputStream(), Long.MAX_VALUE, ctx.getSecret()); } } diff --git a/test/net/sf/briar/ProtocolIntegrationTest.java b/test/net/sf/briar/ProtocolIntegrationTest.java index 1aba7e21cba14d8df7a51686c58d7dd255bc18fe..c83a081d6a5d73f79566906c6ba6f31ddb2ad98b 100644 --- a/test/net/sf/briar/ProtocolIntegrationTest.java +++ b/test/net/sf/briar/ProtocolIntegrationTest.java @@ -1,5 +1,6 @@ package net.sf.briar; +import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH; import static org.junit.Assert.assertArrayEquals; import java.io.ByteArrayInputStream; @@ -18,7 +19,6 @@ import java.util.concurrent.Executor; import java.util.concurrent.ScheduledThreadPoolExecutor; import junit.framework.TestCase; -import net.sf.briar.api.ContactId; import net.sf.briar.api.crypto.CryptoComponent; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.Author; @@ -46,13 +46,10 @@ import net.sf.briar.api.protocol.writers.ProtocolWriterFactory; import net.sf.briar.api.protocol.writers.RequestWriter; import net.sf.briar.api.protocol.writers.SubscriptionUpdateWriter; import net.sf.briar.api.protocol.writers.TransportUpdateWriter; -import net.sf.briar.api.transport.ConnectionContext; -import net.sf.briar.api.transport.ConnectionContextFactory; import net.sf.briar.api.transport.ConnectionReader; import net.sf.briar.api.transport.ConnectionReaderFactory; import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.api.transport.ConnectionWriterFactory; -import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH; import net.sf.briar.crypto.CryptoModule; import net.sf.briar.db.DatabaseModule; import net.sf.briar.lifecycle.LifecycleModule; @@ -63,7 +60,6 @@ import net.sf.briar.transport.TransportModule; import net.sf.briar.transport.batch.TransportBatchModule; import net.sf.briar.transport.stream.TransportStreamModule; -import org.bouncycastle.util.Arrays; import org.junit.Test; import com.google.inject.AbstractModule; @@ -76,16 +72,13 @@ public class ProtocolIntegrationTest extends TestCase { private final BatchId ack = new BatchId(TestUtils.getRandomId()); private final long timestamp = System.currentTimeMillis(); - private final ConnectionContextFactory connectionContextFactory; private final ConnectionReaderFactory connectionReaderFactory; private final ConnectionWriterFactory connectionWriterFactory; private final ProtocolReaderFactory protocolReaderFactory; private final ProtocolWriterFactory protocolWriterFactory; private final CryptoComponent crypto; private final byte[] secret; - private final ContactId contactId = new ContactId(13); private final TransportIndex transportIndex = new TransportIndex(13); - private final long connection = 12345L; private final Author author; private final Group group, group1; private final Message message, message1, message2, message3; @@ -109,8 +102,6 @@ public class ProtocolIntegrationTest extends TestCase { new SerialModule(), new TestDatabaseModule(), new TransportBatchModule(), new TransportModule(), new TransportStreamModule()); - connectionContextFactory = - i.getInstance(ConnectionContextFactory.class); connectionReaderFactory = i.getInstance(ConnectionReaderFactory.class); connectionWriterFactory = i.getInstance(ConnectionWriterFactory.class); protocolReaderFactory = i.getInstance(ProtocolReaderFactory.class); @@ -158,11 +149,8 @@ public class ProtocolIntegrationTest extends TestCase { private byte[] write() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - ConnectionContext ctx = - connectionContextFactory.createConnectionContext(contactId, - transportIndex, connection, Arrays.clone(secret)); ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out, - Long.MAX_VALUE, ctx); + Long.MAX_VALUE, secret.clone()); OutputStream out1 = w.getOutputStream(); AckWriter a = protocolWriterFactory.createAckWriter(out1); @@ -209,11 +197,8 @@ public class ProtocolIntegrationTest extends TestCase { InputStream in = new ByteArrayInputStream(connectionData); byte[] tag = new byte[TAG_LENGTH]; assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH)); - ConnectionContext ctx = - connectionContextFactory.createConnectionContext(contactId, - transportIndex, connection, Arrays.clone(secret)); ConnectionReader r = connectionReaderFactory.createConnectionReader(in, - ctx, tag); + secret.clone(), tag); in = r.getInputStream(); ProtocolReader protocolReader = protocolReaderFactory.createProtocolReader(in); diff --git a/test/net/sf/briar/transport/ConnectionWriterTest.java b/test/net/sf/briar/transport/ConnectionWriterTest.java index 9e47c43b9418fa0ffc2ed28adc898f29241673d5..91718a68308297efd79a79f77467eb1b3b7aaa16 100644 --- a/test/net/sf/briar/transport/ConnectionWriterTest.java +++ b/test/net/sf/briar/transport/ConnectionWriterTest.java @@ -10,10 +10,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import junit.framework.TestCase; import net.sf.briar.TestDatabaseModule; -import net.sf.briar.api.ContactId; -import net.sf.briar.api.protocol.TransportIndex; -import net.sf.briar.api.transport.ConnectionContext; -import net.sf.briar.api.transport.ConnectionContextFactory; import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.api.transport.ConnectionWriterFactory; import net.sf.briar.crypto.CryptoModule; @@ -34,12 +30,8 @@ import com.google.inject.Module; public class ConnectionWriterTest extends TestCase { - private final ConnectionContextFactory connectionContextFactory; private final ConnectionWriterFactory connectionWriterFactory; private final byte[] secret; - private final ContactId contactId = new ContactId(13); - private final TransportIndex transportIndex = new TransportIndex(13); - private final long connection = 12345L; public ConnectionWriterTest() throws Exception { super(); @@ -56,8 +48,6 @@ public class ConnectionWriterTest extends TestCase { new SerialModule(), new TestDatabaseModule(), new TransportBatchModule(), new TransportModule(), new TransportStreamModule()); - connectionContextFactory = - i.getInstance(ConnectionContextFactory.class); connectionWriterFactory = i.getInstance(ConnectionWriterFactory.class); secret = new byte[32]; new Random().nextBytes(secret); @@ -67,11 +57,8 @@ public class ConnectionWriterTest extends TestCase { public void testOverhead() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(MIN_CONNECTION_LENGTH); - ConnectionContext ctx = - connectionContextFactory.createConnectionContext(contactId, - transportIndex, connection, secret); ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out, - MIN_CONNECTION_LENGTH, ctx); + MIN_CONNECTION_LENGTH, secret); // Check that the connection writer thinks there's room for a packet long capacity = w.getRemainingCapacity(); assertTrue(capacity >= MAX_PACKET_LENGTH);