From 6085b70b85f423bdf7152d72548d53bc6b01ee5d Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Tue, 17 Jan 2012 20:29:30 +0000
Subject: [PATCH] Factory methods for segmented connection writers.

---
 .../transport/ConnectionWriterFactory.java    | 17 +++++----
 .../duplex/IncomingDuplexConnection.java      |  2 +-
 .../duplex/OutgoingDuplexConnection.java      |  3 +-
 .../simplex/OutgoingSimplexConnection.java    |  2 +-
 .../ConnectionWriterFactoryImpl.java          | 38 +++++++++++--------
 .../net/sf/briar/ProtocolIntegrationTest.java |  2 +-
 .../briar/transport/ConnectionWriterTest.java |  2 +-
 7 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java
index 13fbbb2303..be3d55747f 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 75e6554cdf..898cefd8aa 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 aee3b4d83b..ffc60361d9 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 f7e404bf0a..8d1082f8f1 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 f2530acd68..a3f7f1ed61 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 4545552503..db5f968cef 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 6c84bb12d3..58ec3a92b1 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);
-- 
GitLab