From 87e1c42bf8fa3bcf0229a795f6007c0ec22fc601 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Tue, 17 Jan 2012 17:37:38 +0000 Subject: [PATCH] Converted the outgoing encryption layer from frames to segments. --- .../ConnectionWriterFactoryImpl.java | 5 +- .../briar/transport/ConnectionWriterImpl.java | 59 ++++++++++--------- .../IncomingEncryptionLayerImpl.java | 2 +- .../IncomingSegmentedEncryptionLayer.java | 2 +- .../NullOutgoingErrorCorrectionLayer.java | 39 ++++++++++++ .../transport/OutgoingEncryptionLayer.java | 9 +-- .../OutgoingEncryptionLayerImpl.java | 57 +++++++++--------- .../OutgoingErrorCorrectionLayer.java | 15 +++++ .../OutgoingSegmentedEncryptionLayer.java | 29 +++++---- .../net/sf/briar/transport/TagEncoder.java | 2 + .../transport/ConnectionWriterImplTest.java | 35 +++++++---- .../briar/transport/FrameReadWriteTest.java | 8 ++- .../NullOutgoingEncryptionLayer.java | 8 ++- .../OutgoingEncryptionLayerImplTest.java | 23 ++++++-- .../OutgoingSegmentedEncryptionLayerTest.java | 23 ++++++-- 15 files changed, 214 insertions(+), 102 deletions(-) create mode 100644 components/net/sf/briar/transport/NullOutgoingErrorCorrectionLayer.java create mode 100644 components/net/sf/briar/transport/OutgoingErrorCorrectionLayer.java diff --git a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java index 85daf0053a..f2530acd68 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 0175727916..9a7ad2efca 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 cdfd11e995..447656ab66 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 00652bd49e..21caee2ce6 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 0000000000..9bf37eac52 --- /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 bd902736a2..fecc03d286 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 33cb929435..5a3ff9d092 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 0000000000..206a594df3 --- /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 8d7708aaa2..2bf1864454 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 3ca17ea620..e7a223f2a3 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 030fa28d19..4259d717b5 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 4699597f90..465e85e3eb 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 8d2448433a..ed8ff5d559 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 6e16d1aa72..bd1246e965 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 0fa64f2c0c..4266801360 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); -- GitLab