diff --git a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java index 13fbbb23039827f2780b4e808e11c857d2464502..be3d55747f93e0a754f686ab8872101956e6eaff 100644 --- a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java +++ b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java @@ -2,20 +2,21 @@ package net.sf.briar.api.transport; import java.io.OutputStream; +import net.sf.briar.api.plugins.SegmentSink; + public interface ConnectionWriterFactory { /** - * Creates a connection writer for a simplex connection or the initiator's - * side of a duplex connection. The secret is erased before this method - * returns. + * Creates a connection writer for a simplex connection or one side of a + * duplex connection. The secret is erased before this method returns. */ ConnectionWriter createConnectionWriter(OutputStream out, long capacity, - byte[] secret); + byte[] secret, boolean initiator); /** - * Creates a connection writer for the responder's side of a duplex - * connection. The secret is erased before this method returns. + * Creates a connection writer for a simplex connection or one side of a + * duplex connection. The secret is erased before this method returns. */ - ConnectionWriter createConnectionWriter(OutputStream out, long capacity, - byte[] secret, byte[] tag); + ConnectionWriter createConnectionWriter(SegmentSink out, long capacity, + byte[] secret, boolean initiator); } diff --git a/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java b/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java index 75e6554cdf315e219b3af0ef64d85417b3c12354..898cefd8aa08d67abb6ad46bb8b07eaec9ec81fa 100644 --- a/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java +++ b/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java @@ -48,6 +48,6 @@ class IncomingDuplexConnection extends DuplexConnection { protected ConnectionWriter createConnectionWriter() throws IOException { return connWriterFactory.createConnectionWriter( transport.getOutputStream(), Long.MAX_VALUE, ctx.getSecret(), - tag); + false); } } diff --git a/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java b/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java index aee3b4d83b4b6980e2ca2fc996bac0e6bfd1e97c..ffc60361d98f1ea24f192d1147ff7632c8d9d105 100644 --- a/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java +++ b/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java @@ -60,6 +60,7 @@ class OutgoingDuplexConnection extends DuplexConnection { ctx = db.getConnectionContext(contactId, transportIndex); } return connWriterFactory.createConnectionWriter( - transport.getOutputStream(), Long.MAX_VALUE, ctx.getSecret()); + transport.getOutputStream(), Long.MAX_VALUE, ctx.getSecret(), + true); } } diff --git a/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java b/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java index f7e404bf0af56b08812e7e1ccf00ad96e1eaf96b..8d1082f8f1c9a26119cf760e0da377c0871071d9 100644 --- a/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java +++ b/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java @@ -62,7 +62,7 @@ class OutgoingSimplexConnection { transportIndex); ConnectionWriter conn = connFactory.createConnectionWriter( transport.getOutputStream(), transport.getCapacity(), - ctx.getSecret()); + ctx.getSecret(), true); OutputStream out = conn.getOutputStream(); ProtocolWriter writer = protoFactory.createProtocolWriter(out, transport.shouldFlush()); diff --git a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java index f2530acd689777f783563072496a66e3ca7966cd..a3f7f1ed6107731e8a5242a3f5e5a877ca1b335c 100644 --- a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java @@ -7,6 +7,7 @@ import javax.crypto.Mac; import net.sf.briar.api.crypto.CryptoComponent; import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.SegmentSink; import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.api.transport.ConnectionWriterFactory; import net.sf.briar.util.ByteUtils; @@ -23,23 +24,27 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { } public ConnectionWriter createConnectionWriter(OutputStream out, - long capacity, byte[] secret) { - return createConnectionWriter(out, capacity, true, secret); - } - - public ConnectionWriter createConnectionWriter(OutputStream out, - long capacity, byte[] secret, byte[] tag) { - // Validate the tag + long capacity, byte[] secret, boolean initiator) { + // Derive the keys and erase the secret + ErasableKey tagKey = crypto.deriveTagKey(secret, initiator); + ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator); + ErasableKey macKey = crypto.deriveMacKey(secret, initiator); + ByteUtils.erase(secret); + // Create the encrypter Cipher tagCipher = crypto.getTagCipher(); - ErasableKey tagKey = crypto.deriveTagKey(secret, true); - long segmentNumber = TagEncoder.decodeTag(tag, tagCipher, tagKey); - tagKey.erase(); - if(segmentNumber != 0) throw new IllegalArgumentException(); - return createConnectionWriter(out, capacity, false, secret); + Cipher frameCipher = crypto.getFrameCipher(); + OutgoingEncryptionLayer encrypter = new OutgoingEncryptionLayerImpl(out, + capacity, tagCipher, frameCipher, tagKey, frameKey, false); + // No error correction + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + // Create the writer + Mac mac = crypto.getMac(); + return new ConnectionWriterImpl(correcter, mac, macKey); } - private ConnectionWriter createConnectionWriter(OutputStream out, - long capacity, boolean initiator, byte[] secret) { + public ConnectionWriter createConnectionWriter(SegmentSink out, + long capacity, byte[] secret, boolean initiator) { // Derive the keys and erase the secret ErasableKey tagKey = crypto.deriveTagKey(secret, initiator); ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator); @@ -48,8 +53,9 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { // Create the encrypter Cipher tagCipher = crypto.getTagCipher(); Cipher frameCipher = crypto.getFrameCipher(); - OutgoingEncryptionLayer encrypter = new OutgoingEncryptionLayerImpl(out, - capacity, tagCipher, frameCipher, tagKey, frameKey, false); + OutgoingEncryptionLayer encrypter = + new OutgoingSegmentedEncryptionLayer(out, capacity, tagCipher, + frameCipher, tagKey, frameKey, false); // No error correction OutgoingErrorCorrectionLayer correcter = new NullOutgoingErrorCorrectionLayer(encrypter); diff --git a/test/net/sf/briar/ProtocolIntegrationTest.java b/test/net/sf/briar/ProtocolIntegrationTest.java index 45455525034b2f775449722b114160704d3ce4e9..db5f968cef7d1439b74b704942876f2dc069c6d2 100644 --- a/test/net/sf/briar/ProtocolIntegrationTest.java +++ b/test/net/sf/briar/ProtocolIntegrationTest.java @@ -136,7 +136,7 @@ public class ProtocolIntegrationTest extends BriarTestCase { private byte[] write() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ConnectionWriter conn = connectionWriterFactory.createConnectionWriter( - out, Long.MAX_VALUE, secret.clone()); + out, Long.MAX_VALUE, secret.clone(), true); OutputStream out1 = conn.getOutputStream(); ProtocolWriter writer = protocolWriterFactory.createProtocolWriter(out1, false); diff --git a/test/net/sf/briar/transport/ConnectionWriterTest.java b/test/net/sf/briar/transport/ConnectionWriterTest.java index 6c84bb12d36263a745c9dcf2f7d4a2b53ae5c21d..58ec3a92b1335de557241176945693c61c1c0d02 100644 --- a/test/net/sf/briar/transport/ConnectionWriterTest.java +++ b/test/net/sf/briar/transport/ConnectionWriterTest.java @@ -45,7 +45,7 @@ public class ConnectionWriterTest extends BriarTestCase { ByteArrayOutputStream out = new ByteArrayOutputStream(MIN_CONNECTION_LENGTH); ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out, - MIN_CONNECTION_LENGTH, secret); + MIN_CONNECTION_LENGTH, secret, true); // Check that the connection writer thinks there's room for a packet long capacity = w.getRemainingCapacity(); assertTrue(capacity >= MAX_PACKET_LENGTH);