diff --git a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java index 85daf0053a42667e7286022b39473bbbfd617af4..f2530acd689777f783563072496a66e3ca7966cd 100644 --- a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java @@ -50,8 +50,11 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { 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(encrypter, mac, macKey); + return new ConnectionWriterImpl(correcter, mac, macKey); } } diff --git a/components/net/sf/briar/transport/ConnectionWriterImpl.java b/components/net/sf/briar/transport/ConnectionWriterImpl.java index 017572791679b905ab2484273dac6af93130486b..9a7ad2efca1ddd919ac03bc28424d1b5c1ab185c 100644 --- a/components/net/sf/briar/transport/ConnectionWriterImpl.java +++ b/components/net/sf/briar/transport/ConnectionWriterImpl.java @@ -23,16 +23,16 @@ import net.sf.briar.api.transport.ConnectionWriter; */ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter { - private final OutgoingEncryptionLayer encrypter; + private final OutgoingErrorCorrectionLayer out; private final Mac mac; - private final byte[] buf; + private final Frame frame; - private int length = FRAME_HEADER_LENGTH; - private long frame = 0L; + private int offset = FRAME_HEADER_LENGTH; + private long frameNumber = 0L; - ConnectionWriterImpl(OutgoingEncryptionLayer encrypter, Mac mac, + ConnectionWriterImpl(OutgoingErrorCorrectionLayer out, Mac mac, ErasableKey macKey) { - this.encrypter = encrypter; + this.out = out; this.mac = mac; // Initialise the MAC try { @@ -43,7 +43,7 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter { macKey.erase(); if(mac.getMacLength() != MAC_LENGTH) throw new IllegalArgumentException(); - buf = new byte[MAX_FRAME_LENGTH]; + frame = new Frame(); } public OutputStream getOutputStream() { @@ -51,10 +51,10 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter { } public long getRemainingCapacity() { - long capacity = encrypter.getRemainingCapacity(); + long capacity = out.getRemainingCapacity(); // If there's any data buffered, subtract it and its overhead - if(length > FRAME_HEADER_LENGTH) - capacity -= length + MAC_LENGTH; + if(offset > FRAME_HEADER_LENGTH) + capacity -= offset + MAC_LENGTH; // Subtract the overhead from the remaining capacity long frames = (long) Math.ceil((double) capacity / MAX_FRAME_LENGTH); int overheadPerFrame = FRAME_HEADER_LENGTH + MAC_LENGTH; @@ -63,14 +63,14 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter { @Override public void flush() throws IOException { - if(length > FRAME_HEADER_LENGTH) writeFrame(); - encrypter.flush(); + if(offset > FRAME_HEADER_LENGTH) writeFrame(); + out.flush(); } @Override public void write(int b) throws IOException { - buf[length++] = (byte) b; - if(length + MAC_LENGTH == MAX_FRAME_LENGTH) writeFrame(); + frame.getBuffer()[offset++] = (byte) b; + if(offset + MAC_LENGTH == MAX_FRAME_LENGTH) writeFrame(); } @Override @@ -80,32 +80,35 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter { @Override public void write(byte[] b, int off, int len) throws IOException { - int available = MAX_FRAME_LENGTH - length - MAC_LENGTH; + byte[] buf = frame.getBuffer(); + int available = MAX_FRAME_LENGTH - offset - MAC_LENGTH; while(available <= len) { - System.arraycopy(b, off, buf, length, available); - length += available; + System.arraycopy(b, off, buf, offset, available); + offset += available; writeFrame(); off += available; len -= available; - available = MAX_FRAME_LENGTH - length - MAC_LENGTH; + available = MAX_FRAME_LENGTH - offset - MAC_LENGTH; } - System.arraycopy(b, off, buf, length, len); - length += len; + System.arraycopy(b, off, buf, offset, len); + offset += len; } private void writeFrame() throws IOException { - if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); - int payloadLength = length - FRAME_HEADER_LENGTH; + if(frameNumber > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); + byte[] buf = frame.getBuffer(); + int payloadLength = offset - FRAME_HEADER_LENGTH; assert payloadLength > 0; - HeaderEncoder.encodeHeader(buf, frame, payloadLength, 0); - mac.update(buf, 0, length); + HeaderEncoder.encodeHeader(buf, frameNumber, payloadLength, 0); + mac.update(buf, 0, offset); try { - mac.doFinal(buf, length); + mac.doFinal(buf, offset); } catch(ShortBufferException badMac) { throw new RuntimeException(badMac); } - encrypter.writeFrame(buf, length + MAC_LENGTH); - length = FRAME_HEADER_LENGTH; - frame++; + frame.setLength(offset + MAC_LENGTH); + out.writeFrame(frame); + offset = FRAME_HEADER_LENGTH; + frameNumber++; } } diff --git a/components/net/sf/briar/transport/IncomingEncryptionLayerImpl.java b/components/net/sf/briar/transport/IncomingEncryptionLayerImpl.java index cdfd11e99526281e2b9b46df6c13d90b13a8cd46..447656ab66aa1b5b9bcb2b13365b636252ceb058 100644 --- a/components/net/sf/briar/transport/IncomingEncryptionLayerImpl.java +++ b/components/net/sf/briar/transport/IncomingEncryptionLayerImpl.java @@ -42,7 +42,7 @@ class IncomingEncryptionLayerImpl implements IncomingEncryptionLayer { blockSize = frameCipher.getBlockSize(); if(blockSize < FRAME_HEADER_LENGTH) throw new IllegalArgumentException(); - iv = IvEncoder.encodeIv(0, blockSize); + iv = IvEncoder.encodeIv(0L, blockSize); ciphertext = new byte[MAX_SEGMENT_LENGTH]; } diff --git a/components/net/sf/briar/transport/IncomingSegmentedEncryptionLayer.java b/components/net/sf/briar/transport/IncomingSegmentedEncryptionLayer.java index 00652bd49ebb15a6e27955f24857968bac90b282..21caee2ce62e915b11bcc53ad437947660840b82 100644 --- a/components/net/sf/briar/transport/IncomingSegmentedEncryptionLayer.java +++ b/components/net/sf/briar/transport/IncomingSegmentedEncryptionLayer.java @@ -41,7 +41,7 @@ class IncomingSegmentedEncryptionLayer implements IncomingEncryptionLayer { blockSize = frameCipher.getBlockSize(); if(blockSize < FRAME_HEADER_LENGTH) throw new IllegalArgumentException(); - iv = IvEncoder.encodeIv(0, blockSize); + iv = IvEncoder.encodeIv(0L, blockSize); segment = new SegmentImpl(); } diff --git a/components/net/sf/briar/transport/NullOutgoingErrorCorrectionLayer.java b/components/net/sf/briar/transport/NullOutgoingErrorCorrectionLayer.java new file mode 100644 index 0000000000000000000000000000000000000000..9bf37eac5253a85a8d649128e7907c2ebb55fd57 --- /dev/null +++ b/components/net/sf/briar/transport/NullOutgoingErrorCorrectionLayer.java @@ -0,0 +1,39 @@ +package net.sf.briar.transport; + +import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; + +import java.io.IOException; + +import net.sf.briar.api.plugins.Segment; + +class NullOutgoingErrorCorrectionLayer implements OutgoingErrorCorrectionLayer { + + private final OutgoingEncryptionLayer out; + private final Segment segment; + + private long segmentNumber = 0L; + + public NullOutgoingErrorCorrectionLayer(OutgoingEncryptionLayer out) { + this.out = out; + segment = new SegmentImpl(); + } + + public void writeFrame(Frame f) throws IOException { + if(segmentNumber > MAX_32_BIT_UNSIGNED) + throw new IllegalStateException(); + int length = f.getLength(); + // FIXME: Unnecessary copy + System.arraycopy(f.getBuffer(), 0, segment.getBuffer(), 0, length); + segment.setLength(length); + segment.setSegmentNumber(segmentNumber++); + out.writeSegment(segment); + } + + public void flush() throws IOException { + out.flush(); + } + + public long getRemainingCapacity() { + return out.getRemainingCapacity(); + } +} diff --git a/components/net/sf/briar/transport/OutgoingEncryptionLayer.java b/components/net/sf/briar/transport/OutgoingEncryptionLayer.java index bd902736a2e23db7b857461cc75512e96d4386cc..fecc03d286118d8f86ef08b4b0fc99f7a8649d20 100644 --- a/components/net/sf/briar/transport/OutgoingEncryptionLayer.java +++ b/components/net/sf/briar/transport/OutgoingEncryptionLayer.java @@ -2,13 +2,14 @@ package net.sf.briar.transport; import java.io.IOException; -/** Encrypts authenticated data to be sent over a connection. */ +import net.sf.briar.api.plugins.Segment; + interface OutgoingEncryptionLayer { - /** Writes the given frame. */ - void writeFrame(byte[] b, int len) throws IOException; + /** Writes the given segment. */ + void writeSegment(Segment s) throws IOException; - /** Flushes the output stream. */ + /** Flushes the stack. */ void flush() throws IOException; /** Returns the maximum number of bytes that can be written. */ diff --git a/components/net/sf/briar/transport/OutgoingEncryptionLayerImpl.java b/components/net/sf/briar/transport/OutgoingEncryptionLayerImpl.java index 33cb929435b8c46d5ca894d18ad0902ad98e5f08..5a3ff9d0927b9148fd5d153a068cb7bb3641eeaf 100644 --- a/components/net/sf/briar/transport/OutgoingEncryptionLayerImpl.java +++ b/components/net/sf/briar/transport/OutgoingEncryptionLayerImpl.java @@ -1,7 +1,7 @@ package net.sf.briar.transport; +import static net.sf.briar.api.transport.TransportConstants.MAX_SEGMENT_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH; -import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; import java.io.IOException; import java.io.OutputStream; @@ -11,6 +11,7 @@ import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.Segment; class OutgoingEncryptionLayerImpl implements OutgoingEncryptionLayer { @@ -18,13 +19,13 @@ class OutgoingEncryptionLayerImpl implements OutgoingEncryptionLayer { private final Cipher tagCipher, frameCipher; private final ErasableKey tagKey, frameKey; private final boolean tagEverySegment; - private final byte[] iv, tag; + private final byte[] iv, ciphertext; - private long capacity, frame = 0L; + private long capacity; - OutgoingEncryptionLayerImpl(OutputStream out, long capacity, Cipher tagCipher, - Cipher frameCipher, ErasableKey tagKey, ErasableKey frameKey, - boolean tagEverySegment) { + OutgoingEncryptionLayerImpl(OutputStream out, long capacity, + Cipher tagCipher, Cipher frameCipher, ErasableKey tagKey, + ErasableKey frameKey, boolean tagEverySegment) { this.out = out; this.capacity = capacity; this.tagCipher = tagCipher; @@ -32,35 +33,37 @@ class OutgoingEncryptionLayerImpl implements OutgoingEncryptionLayer { this.tagKey = tagKey; this.frameKey = frameKey; this.tagEverySegment = tagEverySegment; - iv = IvEncoder.encodeIv(0, frameCipher.getBlockSize()); - tag = new byte[TAG_LENGTH]; + iv = IvEncoder.encodeIv(0L, frameCipher.getBlockSize()); + ciphertext = new byte[MAX_SEGMENT_LENGTH]; } - public void writeFrame(byte[] b, int len) throws IOException { - if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); + public void writeSegment(Segment s) throws IOException { + byte[] plaintext = s.getBuffer(); + int length = s.getLength(); + long segmentNumber = s.getSegmentNumber(); + int offset = 0; + if(tagEverySegment || segmentNumber == 0) { + TagEncoder.encodeTag(ciphertext, segmentNumber, tagCipher, tagKey); + offset = TAG_LENGTH; + } + IvEncoder.updateIv(iv, segmentNumber); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + try { + frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); + int encrypted = frameCipher.doFinal(plaintext, 0, length, + ciphertext, offset); + if(encrypted != length) throw new RuntimeException(); + } catch(GeneralSecurityException badCipher) { + throw new RuntimeException(badCipher); + } try { - if(tagEverySegment || frame == 0) { - TagEncoder.encodeTag(tag, frame, tagCipher, tagKey); - out.write(tag); - capacity -= tag.length; - } - IvEncoder.updateIv(iv, frame); - IvParameterSpec ivSpec = new IvParameterSpec(iv); - try { - frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); - int encrypted = frameCipher.doFinal(b, 0, len, b); - if(encrypted != len) throw new RuntimeException(); - } catch(GeneralSecurityException badCipher) { - throw new RuntimeException(badCipher); - } - out.write(b, 0, len); - capacity -= len; - frame++; + out.write(ciphertext, 0, offset + length); } catch(IOException e) { frameKey.erase(); tagKey.erase(); throw e; } + capacity -= offset + length; } public void flush() throws IOException { diff --git a/components/net/sf/briar/transport/OutgoingErrorCorrectionLayer.java b/components/net/sf/briar/transport/OutgoingErrorCorrectionLayer.java new file mode 100644 index 0000000000000000000000000000000000000000..206a594df3e0e9704e85e3e24b586ec38a8843c2 --- /dev/null +++ b/components/net/sf/briar/transport/OutgoingErrorCorrectionLayer.java @@ -0,0 +1,15 @@ +package net.sf.briar.transport; + +import java.io.IOException; + +interface OutgoingErrorCorrectionLayer { + + /** Writes the given frame. */ + void writeFrame(Frame f) throws IOException; + + /** Flushes the stack. */ + void flush() throws IOException; + + /** Returns the maximum number of bytes that can be written. */ + long getRemainingCapacity(); +} diff --git a/components/net/sf/briar/transport/OutgoingSegmentedEncryptionLayer.java b/components/net/sf/briar/transport/OutgoingSegmentedEncryptionLayer.java index 8d7708aaa2e88f3ff13b793883ab1539a24c0c80..2bf1864454a209019cd261376ff3c8f4d80482d3 100644 --- a/components/net/sf/briar/transport/OutgoingSegmentedEncryptionLayer.java +++ b/components/net/sf/briar/transport/OutgoingSegmentedEncryptionLayer.java @@ -1,7 +1,6 @@ package net.sf.briar.transport; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH; -import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; import java.io.IOException; import java.security.GeneralSecurityException; @@ -22,7 +21,7 @@ class OutgoingSegmentedEncryptionLayer implements OutgoingEncryptionLayer { private final byte[] iv; private final Segment segment; - private long capacity, frame = 0L; + private long capacity; OutgoingSegmentedEncryptionLayer(SegmentSink out, long capacity, Cipher tagCipher, Cipher frameCipher, ErasableKey tagKey, @@ -34,29 +33,30 @@ class OutgoingSegmentedEncryptionLayer implements OutgoingEncryptionLayer { this.tagKey = tagKey; this.frameKey = frameKey; this.tagEverySegment = tagEverySegment; - iv = IvEncoder.encodeIv(0, frameCipher.getBlockSize()); + iv = IvEncoder.encodeIv(0L, frameCipher.getBlockSize()); segment = new SegmentImpl(); } - public void writeFrame(byte[] b, int len) throws IOException { - if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); + public void writeSegment(Segment s) throws IOException { + byte[] plaintext = s.getBuffer(), ciphertext = segment.getBuffer(); + int length = s.getLength(); + long segmentNumber = s.getSegmentNumber(); int offset = 0; - if(tagEverySegment || frame == 0) { - TagEncoder.encodeTag(segment.getBuffer(), frame, tagCipher, tagKey); + if(tagEverySegment || segmentNumber == 0) { + TagEncoder.encodeTag(ciphertext, segmentNumber, tagCipher, tagKey); offset = TAG_LENGTH; - capacity -= TAG_LENGTH; } - IvEncoder.updateIv(iv, frame); + IvEncoder.updateIv(iv, segmentNumber); IvParameterSpec ivSpec = new IvParameterSpec(iv); try { frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); - int encrypted = frameCipher.doFinal(b, 0, len, segment.getBuffer(), - offset); - if(encrypted != len) throw new RuntimeException(); + int encrypted = frameCipher.doFinal(plaintext, 0, length, + ciphertext, offset); + if(encrypted != length) throw new RuntimeException(); } catch(GeneralSecurityException badCipher) { throw new RuntimeException(badCipher); } - segment.setLength(offset + len); + segment.setLength(offset + length); try { out.writeSegment(segment); } catch(IOException e) { @@ -64,8 +64,7 @@ class OutgoingSegmentedEncryptionLayer implements OutgoingEncryptionLayer { tagKey.erase(); throw e; } - capacity -= len; - frame++; + capacity -= offset + length; } public void flush() throws IOException {} diff --git a/components/net/sf/briar/transport/TagEncoder.java b/components/net/sf/briar/transport/TagEncoder.java index 3ca17ea6208b8fb93771c3d117568a2a3bcdd0cd..e7a223f2a3cee537515e093c8e7dc5400b56d9f7 100644 --- a/components/net/sf/briar/transport/TagEncoder.java +++ b/components/net/sf/briar/transport/TagEncoder.java @@ -17,6 +17,8 @@ class TagEncoder { if(tag.length < TAG_LENGTH) throw new IllegalArgumentException(); if(segmentNumber < 0 || segmentNumber > MAX_32_BIT_UNSIGNED) throw new IllegalArgumentException(); + // Clear the tag + for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0; // Encode the segment number as a uint32 at the end of the tag ByteUtils.writeUint32(segmentNumber, tag, TAG_LENGTH - 4); try { diff --git a/test/net/sf/briar/transport/ConnectionWriterImplTest.java b/test/net/sf/briar/transport/ConnectionWriterImplTest.java index 030fa28d19fa64e65757199e03058d4787f74d7a..4259d717b5c524045e7517784f32b0e31c98ab65 100644 --- a/test/net/sf/briar/transport/ConnectionWriterImplTest.java +++ b/test/net/sf/briar/transport/ConnectionWriterImplTest.java @@ -21,8 +21,11 @@ public class ConnectionWriterImplTest extends TransportTest { @Test public void testFlushWithoutWriteProducesNothing() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutgoingEncryptionLayer encrypter = new NullOutgoingEncryptionLayer(out); - ConnectionWriter w = new ConnectionWriterImpl(encrypter, mac, macKey); + OutgoingEncryptionLayer encrypter = + new NullOutgoingEncryptionLayer(out); + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + ConnectionWriter w = new ConnectionWriterImpl(correcter, mac, macKey); w.getOutputStream().flush(); w.getOutputStream().flush(); w.getOutputStream().flush(); @@ -41,8 +44,11 @@ public class ConnectionWriterImplTest extends TransportTest { mac.doFinal(frame, FRAME_HEADER_LENGTH + payloadLength); // Check that the ConnectionWriter gets the same results ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutgoingEncryptionLayer encrypter = new NullOutgoingEncryptionLayer(out); - ConnectionWriter w = new ConnectionWriterImpl(encrypter, mac, macKey); + OutgoingEncryptionLayer encrypter = + new NullOutgoingEncryptionLayer(out); + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + ConnectionWriter w = new ConnectionWriterImpl(correcter, mac, macKey); w.getOutputStream().write(0); w.getOutputStream().flush(); assertArrayEquals(frame, out.toByteArray()); @@ -51,8 +57,11 @@ public class ConnectionWriterImplTest extends TransportTest { @Test public void testWriteByteToMaxLengthWritesFrame() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutgoingEncryptionLayer encrypter = new NullOutgoingEncryptionLayer(out); - ConnectionWriter w = new ConnectionWriterImpl(encrypter, mac, macKey); + OutgoingEncryptionLayer encrypter = + new NullOutgoingEncryptionLayer(out); + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + ConnectionWriter w = new ConnectionWriterImpl(correcter, mac, macKey); OutputStream out1 = w.getOutputStream(); // The first maxPayloadLength - 1 bytes should be buffered for(int i = 0; i < MAX_PAYLOAD_LENGTH - 1; i++) out1.write(0); @@ -65,8 +74,11 @@ public class ConnectionWriterImplTest extends TransportTest { @Test public void testWriteArrayToMaxLengthWritesFrame() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutgoingEncryptionLayer encrypter = new NullOutgoingEncryptionLayer(out); - ConnectionWriter w = new ConnectionWriterImpl(encrypter, mac, macKey); + OutgoingEncryptionLayer encrypter = + new NullOutgoingEncryptionLayer(out); + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + ConnectionWriter w = new ConnectionWriterImpl(correcter, mac, macKey); OutputStream out1 = w.getOutputStream(); // The first maxPayloadLength - 1 bytes should be buffered out1.write(new byte[MAX_PAYLOAD_LENGTH - 1]); @@ -100,8 +112,11 @@ public class ConnectionWriterImplTest extends TransportTest { byte[] expected = out.toByteArray(); // Check that the ConnectionWriter gets the same results out.reset(); - OutgoingEncryptionLayer encrypter = new NullOutgoingEncryptionLayer(out); - ConnectionWriter w = new ConnectionWriterImpl(encrypter, mac, macKey); + OutgoingEncryptionLayer encrypter = + new NullOutgoingEncryptionLayer(out); + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + ConnectionWriter w = new ConnectionWriterImpl(correcter, mac, macKey); w.getOutputStream().write(new byte[123]); w.getOutputStream().flush(); w.getOutputStream().write(new byte[1234]); diff --git a/test/net/sf/briar/transport/FrameReadWriteTest.java b/test/net/sf/briar/transport/FrameReadWriteTest.java index 4699597f901a96b5aaff5fc151ed066853bdc078..465e85e3ebcf87ef4ac97e2618af0774cacc913c 100644 --- a/test/net/sf/briar/transport/FrameReadWriteTest.java +++ b/test/net/sf/briar/transport/FrameReadWriteTest.java @@ -77,7 +77,9 @@ public class FrameReadWriteTest extends BriarTestCase { OutgoingEncryptionLayer encrypter = new OutgoingEncryptionLayerImpl(out, Long.MAX_VALUE, tagCipher, frameCipher, tagCopy, frameCopy, false); - ConnectionWriter writer = new ConnectionWriterImpl(encrypter, mac, + OutgoingErrorCorrectionLayer correcter = + new NullOutgoingErrorCorrectionLayer(encrypter); + ConnectionWriter writer = new ConnectionWriterImpl(correcter, mac, macCopy); OutputStream out1 = writer.getOutputStream(); out1.write(frame); @@ -93,9 +95,9 @@ public class FrameReadWriteTest extends BriarTestCase { // Read the frames back IncomingEncryptionLayer decrypter = new IncomingEncryptionLayerImpl(in, tagCipher, frameCipher, tagKey, frameKey, false); - IncomingErrorCorrectionLayer correcter = + IncomingErrorCorrectionLayer correcter1 = new NullIncomingErrorCorrectionLayer(decrypter); - ConnectionReader reader = new ConnectionReaderImpl(correcter, mac, + ConnectionReader reader = new ConnectionReaderImpl(correcter1, mac, macKey); InputStream in1 = reader.getInputStream(); byte[] recovered = new byte[frame.length]; diff --git a/test/net/sf/briar/transport/NullOutgoingEncryptionLayer.java b/test/net/sf/briar/transport/NullOutgoingEncryptionLayer.java index 8d2448433aec570b489a6ade7524b1141f01ad7e..ed8ff5d55956654d62973fb027ba9b4ae7de3aa5 100644 --- a/test/net/sf/briar/transport/NullOutgoingEncryptionLayer.java +++ b/test/net/sf/briar/transport/NullOutgoingEncryptionLayer.java @@ -3,6 +3,8 @@ package net.sf.briar.transport; import java.io.IOException; import java.io.OutputStream; +import net.sf.briar.api.plugins.Segment; + /** An encryption layer that performs no encryption. */ class NullOutgoingEncryptionLayer implements OutgoingEncryptionLayer { @@ -20,9 +22,9 @@ class NullOutgoingEncryptionLayer implements OutgoingEncryptionLayer { this.capacity = capacity; } - public void writeFrame(byte[] b, int len) throws IOException { - out.write(b, 0, len); - capacity -= len; + public void writeSegment(Segment s) throws IOException { + out.write(s.getBuffer(), 0, s.getLength()); + capacity -= s.getLength(); } public void flush() throws IOException { diff --git a/test/net/sf/briar/transport/OutgoingEncryptionLayerImplTest.java b/test/net/sf/briar/transport/OutgoingEncryptionLayerImplTest.java index 6e16d1aa7245e92424550d978b347e1b80c9b112..bd1246e965560f5434b5bf48cf7284e3097712bc 100644 --- a/test/net/sf/briar/transport/OutgoingEncryptionLayerImplTest.java +++ b/test/net/sf/briar/transport/OutgoingEncryptionLayerImplTest.java @@ -11,6 +11,7 @@ import javax.crypto.spec.IvParameterSpec; import net.sf.briar.BriarTestCase; import net.sf.briar.api.crypto.CryptoComponent; import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.Segment; import net.sf.briar.crypto.CryptoModule; import org.junit.Test; @@ -63,8 +64,15 @@ public class OutgoingEncryptionLayerImplTest extends BriarTestCase { OutgoingEncryptionLayer encrypter = new OutgoingEncryptionLayerImpl(out, Long.MAX_VALUE, tagCipher, frameCipher, tagKey, frameKey, false); - encrypter.writeFrame(plaintext, plaintext.length); - encrypter.writeFrame(plaintext1, plaintext1.length); + Segment s = new SegmentImpl(); + System.arraycopy(plaintext, 0, s.getBuffer(), 0, plaintext.length); + s.setLength(plaintext.length); + s.setSegmentNumber(0L); + encrypter.writeSegment(s); + System.arraycopy(plaintext1, 0, s.getBuffer(), 0, plaintext1.length); + s.setLength(plaintext1.length); + s.setSegmentNumber(1L); + encrypter.writeSegment(s); byte[] actual = out.toByteArray(); // Check that the actual ciphertext matches the expected ciphertext assertArrayEquals(expected, actual); @@ -103,8 +111,15 @@ public class OutgoingEncryptionLayerImplTest extends BriarTestCase { out.reset(); OutgoingEncryptionLayer encrypter = new OutgoingEncryptionLayerImpl(out, Long.MAX_VALUE, tagCipher, frameCipher, tagKey, frameKey, true); - encrypter.writeFrame(plaintext, plaintext.length); - encrypter.writeFrame(plaintext1, plaintext1.length); + Segment s = new SegmentImpl(); + System.arraycopy(plaintext, 0, s.getBuffer(), 0, plaintext.length); + s.setLength(plaintext.length); + s.setSegmentNumber(0L); + encrypter.writeSegment(s); + System.arraycopy(plaintext1, 0, s.getBuffer(), 0, plaintext1.length); + s.setLength(plaintext1.length); + s.setSegmentNumber(1L); + encrypter.writeSegment(s); byte[] actual = out.toByteArray(); // Check that the actual ciphertext matches the expected ciphertext assertArrayEquals(expected, actual); diff --git a/test/net/sf/briar/transport/OutgoingSegmentedEncryptionLayerTest.java b/test/net/sf/briar/transport/OutgoingSegmentedEncryptionLayerTest.java index 0fa64f2c0cc711c3ef8471ecd10eaaf7623354a3..42668013602ebd52c02c1bab33d215fbfd19b261 100644 --- a/test/net/sf/briar/transport/OutgoingSegmentedEncryptionLayerTest.java +++ b/test/net/sf/briar/transport/OutgoingSegmentedEncryptionLayerTest.java @@ -66,9 +66,15 @@ public class OutgoingSegmentedEncryptionLayerTest extends BriarTestCase { OutgoingEncryptionLayer encrypter = new OutgoingSegmentedEncryptionLayer(sink, Long.MAX_VALUE, tagCipher, frameCipher, tagKey, frameKey, false); - // The first frame's buffer must have enough space for the tag - encrypter.writeFrame(plaintext, plaintext.length); - encrypter.writeFrame(plaintext1, plaintext1.length); + Segment s = new SegmentImpl(); + System.arraycopy(plaintext, 0, s.getBuffer(), 0, plaintext.length); + s.setLength(plaintext.length); + s.setSegmentNumber(0L); + encrypter.writeSegment(s); + System.arraycopy(plaintext1, 0, s.getBuffer(), 0, plaintext1.length); + s.setLength(plaintext1.length); + s.setSegmentNumber(1L); + encrypter.writeSegment(s); byte[] actual = out.toByteArray(); // Check that the actual ciphertext matches the expected ciphertext assertArrayEquals(expected, actual); @@ -108,8 +114,15 @@ public class OutgoingSegmentedEncryptionLayerTest extends BriarTestCase { OutgoingEncryptionLayer encrypter = new OutgoingSegmentedEncryptionLayer(sink, Long.MAX_VALUE, tagCipher, frameCipher, tagKey, frameKey, true); - encrypter.writeFrame(plaintext, plaintext.length); - encrypter.writeFrame(plaintext1, plaintext1.length); + Segment s = new SegmentImpl(); + System.arraycopy(plaintext, 0, s.getBuffer(), 0, plaintext.length); + s.setLength(plaintext.length); + s.setSegmentNumber(0L); + encrypter.writeSegment(s); + System.arraycopy(plaintext1, 0, s.getBuffer(), 0, plaintext1.length); + s.setLength(plaintext1.length); + s.setSegmentNumber(1L); + encrypter.writeSegment(s); byte[] actual = out.toByteArray(); // Check that the actual ciphertext matches the expected ciphertext assertArrayEquals(expected, actual);