diff --git a/api/net/sf/briar/api/plugins/FrameSink.java b/api/net/sf/briar/api/plugins/FrameSink.java new file mode 100644 index 0000000000000000000000000000000000000000..841eb81592de6a0be9586492eb2f6b4d3c3bab5c --- /dev/null +++ b/api/net/sf/briar/api/plugins/FrameSink.java @@ -0,0 +1,9 @@ +package net.sf.briar.api.plugins; + +import java.io.IOException; + +public interface FrameSink { + + /** Writes the given frame. */ + void writeFrame(byte[] b, int len) throws IOException; +} diff --git a/api/net/sf/briar/api/plugins/FrameSource.java b/api/net/sf/briar/api/plugins/FrameSource.java new file mode 100644 index 0000000000000000000000000000000000000000..59472821406614067106a27656e7170eb6beea85 --- /dev/null +++ b/api/net/sf/briar/api/plugins/FrameSource.java @@ -0,0 +1,12 @@ +package net.sf.briar.api.plugins; + +import java.io.IOException; + +public interface FrameSource { + + /** + * Reads a frame into the given buffer and returns its length, or -1 if no + * more frames can be read. + */ + int readFrame(byte[] b) throws IOException; +} diff --git a/api/net/sf/briar/api/plugins/duplex/DuplexSegmentedTransportConnection.java b/api/net/sf/briar/api/plugins/duplex/DuplexSegmentedTransportConnection.java index 3ff03462208d071c5309abc66144cf93605eacd3..3adad239866e3d75ad4c54838ec3284d12a2ba12 100644 --- a/api/net/sf/briar/api/plugins/duplex/DuplexSegmentedTransportConnection.java +++ b/api/net/sf/briar/api/plugins/duplex/DuplexSegmentedTransportConnection.java @@ -1,22 +1,15 @@ package net.sf.briar.api.plugins.duplex; -import java.io.IOException; +import net.sf.briar.api.plugins.FrameSink; +import net.sf.briar.api.plugins.FrameSource; /** * An interface for reading and writing data over a duplex segmented transport. * The connection is not responsible for encrypting/decrypting or authenticating * the data. */ -public interface DuplexSegmentedTransportConnection { - - /** - * Reads a frame into the given buffer and returns its length, or -1 if no - * more frames can be read. - */ - int readFrame(byte[] b) throws IOException; - - /** Writes the given frame to the transport. */ - void writeFrame(byte[] b, int len) throws IOException; +public interface DuplexSegmentedTransportConnection extends FrameSource, +FrameSink { /** * Returns true if the output stream should be flushed after each packet. diff --git a/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportReader.java b/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportReader.java index 0d9272d5584e5f76a7989a2ceaa2c97d2c343e86..66ab1a91c40234f26c49cd3148f5fde5cd81efe9 100644 --- a/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportReader.java +++ b/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportReader.java @@ -1,19 +1,13 @@ package net.sf.briar.api.plugins.simplex; -import java.io.IOException; +import net.sf.briar.api.plugins.FrameSource; /** * An interface for reading data from a simplex segmented transport. The reader * is not responsible for decrypting or authenticating the data before * returning it. */ -public interface SimplexSegmentedTransportReader { - - /** - * Reads a frame into the given buffer and returns its length, or -1 if no - * more frames can be read. - */ - int readFrame(byte[] b) throws IOException; +public interface SimplexSegmentedTransportReader extends FrameSource { /** * Closes the reader and disposes of any associated resources. The first diff --git a/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportWriter.java b/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportWriter.java index e6c09b3a3e8ba2b679955a36e59bf18bf9ce8f9b..ff909847eba576272a27e41e09c9709ed7ba6f70 100644 --- a/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportWriter.java +++ b/api/net/sf/briar/api/plugins/simplex/SimplexSegmentedTransportWriter.java @@ -1,7 +1,5 @@ package net.sf.briar.api.plugins.simplex; -import java.io.IOException; - /** * An interface for writing data to a simplex segmented transport. The writer is * not responsible for authenticating or encrypting the data before writing it. @@ -11,9 +9,6 @@ public interface SimplexSegmentedTransportWriter { /** Returns the capacity of the transport in bytes. */ long getCapacity(); - /** Writes the given frame to the transport. */ - void writeFrame(byte[] b, int len) throws IOException; - /** * Returns true if the output stream should be flushed after each packet. */ diff --git a/components/net/sf/briar/transport/ConnectionDecrypter.java b/components/net/sf/briar/transport/ConnectionDecrypter.java index e872f242fecccfdb61c60e8f3063f60ec6d88e40..c8facbdc74edef04b11c0f7dbc99dd53e308bdf9 100644 --- a/components/net/sf/briar/transport/ConnectionDecrypter.java +++ b/components/net/sf/briar/transport/ConnectionDecrypter.java @@ -1,13 +1,100 @@ package net.sf.briar.transport; +import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH; +import static net.sf.briar.api.transport.TransportConstants.MAX_FRAME_LENGTH; +import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; + +import java.io.EOFException; import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; + +import net.sf.briar.api.FormatException; +import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.FrameSource; + +class ConnectionDecrypter implements FrameSource { + + private final InputStream in; + private final Cipher frameCipher; + private final ErasableKey frameKey; + private final int macLength, blockSize; + private final byte[] iv; + + private long frame = 0L; -/** Decrypts unauthenticated data received over a connection. */ -interface ConnectionDecrypter { + ConnectionDecrypter(InputStream in, Cipher frameCipher, + ErasableKey frameKey, int macLength) { + this.in = in; + this.frameCipher = frameCipher; + this.frameKey = frameKey; + this.macLength = macLength; + blockSize = frameCipher.getBlockSize(); + if(blockSize < FRAME_HEADER_LENGTH) + throw new IllegalArgumentException(); + iv = IvEncoder.encodeIv(0, blockSize); + } - /** - * Reads and decrypts a frame into the given buffer and returns the length - * of the decrypted frame, or -1 if no more frames can be read. - */ - int readFrame(byte[] b) throws IOException; -} + public int readFrame(byte[] b) throws IOException { + if(b.length < MAX_FRAME_LENGTH) throw new IllegalArgumentException(); + if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); + // Initialise the cipher + IvEncoder.updateIv(iv, frame); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + try { + frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec); + } catch(GeneralSecurityException badIvOrKey) { + throw new RuntimeException(badIvOrKey); + } + try { + // Read the first block + int offset = 0; + while(offset < blockSize) { + int read = in.read(b, offset, blockSize - offset); + if(read == -1) { + if(offset == 0) return -1; + if(offset < blockSize) throw new EOFException(); + break; + } + offset += read; + } + // Decrypt the first block + try { + int decrypted = frameCipher.update(b, 0, blockSize, b); + assert decrypted == blockSize; + } catch(GeneralSecurityException badCipher) { + throw new RuntimeException(badCipher); + } + // Validate and parse the header + int max = MAX_FRAME_LENGTH - FRAME_HEADER_LENGTH - macLength; + if(!HeaderEncoder.validateHeader(b, frame, max)) + throw new FormatException(); + int payload = HeaderEncoder.getPayloadLength(b); + int padding = HeaderEncoder.getPaddingLength(b); + int length = FRAME_HEADER_LENGTH + payload + padding + macLength; + if(length > MAX_FRAME_LENGTH) throw new FormatException(); + // Read the remainder of the frame + while(offset < length) { + int read = in.read(b, offset, length - offset); + if(read == -1) throw new EOFException(); + offset += read; + } + // Decrypt the remainder of the frame + try { + int decrypted = frameCipher.doFinal(b, blockSize, + length - blockSize, b, blockSize); + assert decrypted == length - blockSize; + } catch(GeneralSecurityException badCipher) { + throw new RuntimeException(badCipher); + } + frame++; + return length; + } catch(IOException e) { + frameKey.erase(); + throw e; + } + } +} \ No newline at end of file diff --git a/components/net/sf/briar/transport/ConnectionEncrypter.java b/components/net/sf/briar/transport/ConnectionEncrypter.java index 11cf16e7c54c413448ca854ad7c1547a1cbc1141..930f1ee81988065ae27a53a6774664738bc7a853 100644 --- a/components/net/sf/briar/transport/ConnectionEncrypter.java +++ b/components/net/sf/briar/transport/ConnectionEncrypter.java @@ -2,11 +2,10 @@ package net.sf.briar.transport; import java.io.IOException; -/** Encrypts authenticated data to be sent over a connection. */ -interface ConnectionEncrypter { +import net.sf.briar.api.plugins.FrameSink; - /** Encrypts and writes the given frame. */ - void writeFrame(byte[] b, int len) throws IOException; +/** Encrypts authenticated data to be sent over a connection. */ +interface ConnectionEncrypter extends FrameSink { /** Flushes the output stream. */ void flush() throws IOException; diff --git a/components/net/sf/briar/transport/ConnectionEncrypterImpl.java b/components/net/sf/briar/transport/ConnectionEncrypterImpl.java index e7e161652414c6d76b2c5cddf4ed159bc569bc68..9370c20f9a1095f4ed2ae24dd583031e08eafdb7 100644 --- a/components/net/sf/briar/transport/ConnectionEncrypterImpl.java +++ b/components/net/sf/briar/transport/ConnectionEncrypterImpl.java @@ -1,6 +1,5 @@ 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; @@ -32,33 +31,37 @@ class ConnectionEncrypterImpl implements ConnectionEncrypter { // Encrypt the tag tag = TagEncoder.encodeTag(0, tagCipher, tagKey); tagKey.erase(); - if(tag.length != TAG_LENGTH) throw new IllegalArgumentException(); } public void writeFrame(byte[] b, int len) throws IOException { - try { - if(!tagWritten) { - out.write(tag); - capacity -= tag.length; - tagWritten = true; - } - if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); - IvEncoder.updateIv(iv, frame); - IvParameterSpec ivSpec = new IvParameterSpec(iv); + if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); + if(!tagWritten) { try { - frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); - int encrypted = frameCipher.doFinal(b, 0, len, b, 0); - assert encrypted == len; - } catch(GeneralSecurityException badCipher) { - throw new RuntimeException(badCipher); + out.write(tag); + } catch(IOException e) { + frameKey.erase(); + throw e; } + capacity -= tag.length; + tagWritten = true; + } + 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); + assert encrypted == len; + } catch(GeneralSecurityException badCipher) { + throw new RuntimeException(badCipher); + } + try { out.write(b, 0, len); - capacity -= len; - frame++; } catch(IOException e) { frameKey.erase(); throw e; } + capacity -= len; + frame++; } public void flush() throws IOException { diff --git a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java index a80769c984d9a7ad8edd78f20b3815fa4b6fb2cd..91c092932004664608ea55ce925e2b428f93f028 100644 --- a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.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.FrameSource; import net.sf.briar.api.transport.ConnectionReader; import net.sf.briar.api.transport.ConnectionReaderFactory; import net.sf.briar.util.ByteUtils; @@ -47,7 +48,7 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory { // Create the decrypter Cipher frameCipher = crypto.getFrameCipher(); Mac mac = crypto.getMac(); - ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in, + FrameSource decrypter = new ConnectionDecrypter(in, frameCipher, frameKey, mac.getMacLength()); // Create the reader return new ConnectionReaderImpl(decrypter, mac, macKey); diff --git a/components/net/sf/briar/transport/ConnectionReaderImpl.java b/components/net/sf/briar/transport/ConnectionReaderImpl.java index 4aef95b3fc909c6922e8bb94d919a39360b023a2..49928cd4e7ff41421c7d81987fcc1714b850f2c4 100644 --- a/components/net/sf/briar/transport/ConnectionReaderImpl.java +++ b/components/net/sf/briar/transport/ConnectionReaderImpl.java @@ -12,11 +12,12 @@ import javax.crypto.Mac; import net.sf.briar.api.FormatException; import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.FrameSource; import net.sf.briar.api.transport.ConnectionReader; class ConnectionReaderImpl extends InputStream implements ConnectionReader { - private final ConnectionDecrypter decrypter; + private final FrameSource decrypter; private final Mac mac; private final int macLength; private final byte[] buf; @@ -24,8 +25,7 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader { private long frame = 0L; private int bufOffset = 0, bufLength = 0; - ConnectionReaderImpl(ConnectionDecrypter decrypter, Mac mac, - ErasableKey macKey) { + ConnectionReaderImpl(FrameSource decrypter, Mac mac, ErasableKey macKey) { this.decrypter = decrypter; this.mac = mac; // Initialise the MAC diff --git a/components/net/sf/briar/transport/ConnectionDecrypterImpl.java b/components/net/sf/briar/transport/SegmentedConnectionDecrypter.java similarity index 63% rename from components/net/sf/briar/transport/ConnectionDecrypterImpl.java rename to components/net/sf/briar/transport/SegmentedConnectionDecrypter.java index b4d93232cefa587b673ad7302a2fd76057b53c2d..54d285d5ea2667d77497bd2f849a696343e5172e 100644 --- a/components/net/sf/briar/transport/ConnectionDecrypterImpl.java +++ b/components/net/sf/briar/transport/SegmentedConnectionDecrypter.java @@ -4,9 +4,7 @@ import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH; import static net.sf.briar.api.transport.TransportConstants.MAX_FRAME_LENGTH; import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; -import java.io.EOFException; import java.io.IOException; -import java.io.InputStream; import java.security.GeneralSecurityException; import javax.crypto.Cipher; @@ -14,10 +12,11 @@ import javax.crypto.spec.IvParameterSpec; import net.sf.briar.api.FormatException; import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.FrameSource; -class ConnectionDecrypterImpl implements ConnectionDecrypter { +class SegmentedConnectionDecrypter implements FrameSource { - private final InputStream in; + private final FrameSource in; private final Cipher frameCipher; private final ErasableKey frameKey; private final int macLength, blockSize; @@ -25,7 +24,7 @@ class ConnectionDecrypterImpl implements ConnectionDecrypter { private long frame = 0L; - ConnectionDecrypterImpl(InputStream in, Cipher frameCipher, + SegmentedConnectionDecrypter(FrameSource in, Cipher frameCipher, ErasableKey frameKey, int macLength) { this.in = in; this.frameCipher = frameCipher; @@ -49,21 +48,16 @@ class ConnectionDecrypterImpl implements ConnectionDecrypter { throw new RuntimeException(badIvOrKey); } try { - // Read the first block - int offset = 0; - while(offset < blockSize) { - int read = in.read(b, offset, blockSize - offset); - if(read == -1) { - if(offset == 0) return -1; - if(offset < blockSize) throw new EOFException(); - break; - } - offset += read; - } - // Decrypt the first block + // Read the frame + int length = in.readFrame(b); + if(length == -1) return -1; + if(length > MAX_FRAME_LENGTH) throw new FormatException(); + if(length < FRAME_HEADER_LENGTH + macLength) + throw new FormatException(); + // Decrypt the frame try { - int decrypted = frameCipher.update(b, 0, blockSize, b); - assert decrypted == blockSize; + int decrypted = frameCipher.update(b, 0, length, b); + assert decrypted == length; } catch(GeneralSecurityException badCipher) { throw new RuntimeException(badCipher); } @@ -73,22 +67,8 @@ class ConnectionDecrypterImpl implements ConnectionDecrypter { throw new FormatException(); int payload = HeaderEncoder.getPayloadLength(b); int padding = HeaderEncoder.getPaddingLength(b); - int length = FRAME_HEADER_LENGTH + payload + padding + macLength; - if(length > MAX_FRAME_LENGTH) throw new FormatException(); - // Read the remainder of the frame - while(offset < length) { - int read = in.read(b, offset, length - offset); - if(read == -1) throw new EOFException(); - offset += read; - } - // Decrypt the remainder of the frame - try { - int decrypted = frameCipher.doFinal(b, blockSize, - length - blockSize, b, blockSize); - assert decrypted == length - blockSize; - } catch(GeneralSecurityException badCipher) { - throw new RuntimeException(badCipher); - } + if(length != FRAME_HEADER_LENGTH + payload + padding + macLength) + throw new FormatException(); frame++; return length; } catch(IOException e) { @@ -96,4 +76,4 @@ class ConnectionDecrypterImpl implements ConnectionDecrypter { throw e; } } -} \ No newline at end of file +} diff --git a/components/net/sf/briar/transport/SegmentedConnectionEncrypter.java b/components/net/sf/briar/transport/SegmentedConnectionEncrypter.java new file mode 100644 index 0000000000000000000000000000000000000000..f67d9b9d91be969bdfa89fc34ae8ce670477d95c --- /dev/null +++ b/components/net/sf/briar/transport/SegmentedConnectionEncrypter.java @@ -0,0 +1,72 @@ +package net.sf.briar.transport; + +import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; + +import net.sf.briar.api.crypto.ErasableKey; +import net.sf.briar.api.plugins.FrameSink; + +class SegmentedConnectionEncrypter implements ConnectionEncrypter { + + private final FrameSink out; + private final Cipher frameCipher; + private final ErasableKey frameKey; + private final byte[] iv, tag; + + private long capacity, frame = 0L; + private boolean tagWritten = false; + + SegmentedConnectionEncrypter(FrameSink out, long capacity, Cipher tagCipher, + Cipher frameCipher, ErasableKey tagKey, ErasableKey frameKey) { + this.out = out; + this.capacity = capacity; + this.frameCipher = frameCipher; + this.frameKey = frameKey; + iv = IvEncoder.encodeIv(0, frameCipher.getBlockSize()); + // Encrypt the tag + tag = TagEncoder.encodeTag(0, tagCipher, tagKey); + tagKey.erase(); + } + + public void writeFrame(byte[] b, int len) throws IOException { + if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); + int offset = 0; + if(!tagWritten) { + if(tag.length + len > b.length) + throw new IllegalArgumentException(); + System.arraycopy(b, 0, b, tag.length, len); + System.arraycopy(tag, 0, b, 0, tag.length); + capacity -= tag.length; + tagWritten = true; + offset = tag.length; + } + IvEncoder.updateIv(iv, frame); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + try { + frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); + int encrypted = frameCipher.doFinal(b, offset, len, b, offset); + assert encrypted == len; + } catch(GeneralSecurityException badCipher) { + throw new RuntimeException(badCipher); + } + try { + out.writeFrame(b, offset + len); + } catch(IOException e) { + frameKey.erase(); + throw e; + } + capacity -= len; + frame++; + } + + public void flush() throws IOException {} + + public long getRemainingCapacity() { + return capacity; + } +} \ No newline at end of file diff --git a/test/net/sf/briar/crypto/CounterModeTest.java b/test/net/sf/briar/crypto/CounterModeTest.java index d9f7131b672b8aa461975ad40aaf09a6bf47a8e9..07475d7d2a9bca0b4eb47c094b7b7b7b1b1d9707 100644 --- a/test/net/sf/briar/crypto/CounterModeTest.java +++ b/test/net/sf/briar/crypto/CounterModeTest.java @@ -55,7 +55,7 @@ public class CounterModeTest extends BriarTestCase { cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)]; - cipher.doFinal(plaintext, 0, plaintext.length, ciphertext, 0); + cipher.doFinal(plaintext, 0, plaintext.length, ciphertext); ciphertexts.add(new Bytes(ciphertext)); } // All the ciphertexts should be distinct using Arrays.equals() @@ -78,7 +78,7 @@ public class CounterModeTest extends BriarTestCase { cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)]; - cipher.doFinal(plaintext, 0, plaintext.length, ciphertext, 0); + cipher.doFinal(plaintext, 0, plaintext.length, ciphertext); ciphertexts.add(new Bytes(ciphertext)); } assertEquals(1, ciphertexts.size()); @@ -98,7 +98,7 @@ public class CounterModeTest extends BriarTestCase { Cipher cipher = Cipher.getInstance(CIPHER_MODE, PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)]; - cipher.doFinal(plaintext, 0, plaintext.length, ciphertext, 0); + cipher.doFinal(plaintext, 0, plaintext.length, ciphertext); // Make sure the IV array hasn't been modified assertEquals(0, ivBytes[BLOCK_SIZE_BYTES - 2]); assertEquals(0, ivBytes[BLOCK_SIZE_BYTES - 1]); @@ -109,7 +109,7 @@ public class CounterModeTest extends BriarTestCase { cipher = Cipher.getInstance(CIPHER_MODE, PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext1 = new byte[cipher.getOutputSize(plaintext.length)]; - cipher.doFinal(plaintext, 0, plaintext.length, ciphertext1, 0); + cipher.doFinal(plaintext, 0, plaintext.length, ciphertext1); // The last nine blocks of the first ciphertext should be identical to // the first nine blocks of the second ciphertext for(int i = 0; i < BLOCK_SIZE_BYTES * 9; i++) { @@ -132,7 +132,7 @@ public class CounterModeTest extends BriarTestCase { Cipher cipher = Cipher.getInstance(CIPHER_MODE, PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)]; - cipher.doFinal(plaintext, 0, plaintext.length, ciphertext, 0); + cipher.doFinal(plaintext, 0, plaintext.length, ciphertext); // Make sure the IV array hasn't been modified assertEquals(0, ivBytes[BLOCK_SIZE_BYTES - 3]); assertEquals((byte) 255, ivBytes[BLOCK_SIZE_BYTES - 2]); @@ -146,7 +146,7 @@ public class CounterModeTest extends BriarTestCase { cipher = Cipher.getInstance(CIPHER_MODE, PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext1 = new byte[cipher.getOutputSize(plaintext.length)]; - cipher.doFinal(plaintext, 0, plaintext.length, ciphertext1, 0); + cipher.doFinal(plaintext, 0, plaintext.length, ciphertext1); // The last nine blocks of the first ciphertext should be identical to // the first nine blocks of the second ciphertext for(int i = 0; i < BLOCK_SIZE_BYTES * 9; i++) { diff --git a/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java b/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java index e02447267a6d46a23ccad940d6eb7f051bbaf29a..c721d8b59b7150feb0b5a91813f2e30b39b16a4c 100644 --- a/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java +++ b/test/net/sf/briar/transport/ConnectionDecrypterImplTest.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.FrameSource; import net.sf.briar.crypto.CryptoModule; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -67,16 +68,16 @@ public class ConnectionDecrypterImplTest extends BriarTestCase { out.write(ciphertext1); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); // Use a ConnectionDecrypter to decrypt the ciphertext - ConnectionDecrypter d = new ConnectionDecrypterImpl(in, frameCipher, + FrameSource decrypter = new ConnectionDecrypter(in, frameCipher, frameKey, MAC_LENGTH); // First frame byte[] decrypted = new byte[MAX_FRAME_LENGTH]; - assertEquals(plaintext.length, d.readFrame(decrypted)); + assertEquals(plaintext.length, decrypter.readFrame(decrypted)); for(int i = 0; i < plaintext.length; i++) { assertEquals(plaintext[i], decrypted[i]); } // Second frame - assertEquals(plaintext1.length, d.readFrame(decrypted)); + assertEquals(plaintext1.length, decrypter.readFrame(decrypted)); for(int i = 0; i < plaintext1.length; i++) { assertEquals(plaintext1[i], decrypted[i]); } diff --git a/test/net/sf/briar/transport/ConnectionReaderImplTest.java b/test/net/sf/briar/transport/ConnectionReaderImplTest.java index 0711f4f21727851ec74c514f511828df209097db..7a6f8000ad130c2e263122195ccd03645e4a1af5 100644 --- a/test/net/sf/briar/transport/ConnectionReaderImplTest.java +++ b/test/net/sf/briar/transport/ConnectionReaderImplTest.java @@ -8,6 +8,7 @@ import java.io.ByteArrayInputStream; import net.sf.briar.TestUtils; import net.sf.briar.api.FormatException; +import net.sf.briar.api.plugins.FrameSource; import net.sf.briar.api.transport.ConnectionReader; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -31,7 +32,7 @@ public class ConnectionReaderImplTest extends TransportTest { mac.doFinal(frame, FRAME_HEADER_LENGTH + payloadLength); // Read the frame ByteArrayInputStream in = new ByteArrayInputStream(frame); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); // There should be no bytes available before EOF assertEquals(-1, r.getInputStream().read()); @@ -49,7 +50,7 @@ public class ConnectionReaderImplTest extends TransportTest { mac.doFinal(frame, FRAME_HEADER_LENGTH + payloadLength); // Read the frame ByteArrayInputStream in = new ByteArrayInputStream(frame); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); // There should be one byte available before EOF assertEquals(0, r.getInputStream().read()); @@ -75,7 +76,7 @@ public class ConnectionReaderImplTest extends TransportTest { out.write(frame1); // Read the first frame ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); byte[] read = new byte[maxPayloadLength]; TestUtils.readFully(r.getInputStream(), read); @@ -109,7 +110,7 @@ public class ConnectionReaderImplTest extends TransportTest { out.write(frame1); // Read the first frame ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); byte[] read = new byte[maxPayloadLength - paddingLength]; TestUtils.readFully(r.getInputStream(), read); @@ -135,7 +136,7 @@ public class ConnectionReaderImplTest extends TransportTest { mac.doFinal(frame, FRAME_HEADER_LENGTH + payloadLength + paddingLength); // Read the frame ByteArrayInputStream in = new ByteArrayInputStream(frame); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); // The non-zero padding should be rejected try { @@ -167,7 +168,7 @@ public class ConnectionReaderImplTest extends TransportTest { out.write(frame1); // Read the frames ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); byte[] read = new byte[payloadLength]; TestUtils.readFully(r.getInputStream(), read); @@ -191,7 +192,7 @@ public class ConnectionReaderImplTest extends TransportTest { frame[12] ^= 1; // Try to read the frame - not a single byte should be read ByteArrayInputStream in = new ByteArrayInputStream(frame); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); try { r.getInputStream().read(); @@ -213,7 +214,7 @@ public class ConnectionReaderImplTest extends TransportTest { frame[17] ^= 1; // Try to read the frame - not a single byte should be read ByteArrayInputStream in = new ByteArrayInputStream(frame); - ConnectionDecrypter d = new NullConnectionDecrypter(in, macLength); + FrameSource d = new NullConnectionDecrypter(in, macLength); ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey); try { r.getInputStream().read(); diff --git a/test/net/sf/briar/transport/FrameReadWriteTest.java b/test/net/sf/briar/transport/FrameReadWriteTest.java index b59b3dd144db60420d31bef8b42f11b6fddbd7fb..ac51080048affe9549f54043f830b99d7e19e367 100644 --- a/test/net/sf/briar/transport/FrameReadWriteTest.java +++ b/test/net/sf/briar/transport/FrameReadWriteTest.java @@ -15,6 +15,7 @@ import javax.crypto.Mac; 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.FrameSource; import net.sf.briar.api.transport.ConnectionReader; import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.crypto.CryptoModule; @@ -89,8 +90,8 @@ public class FrameReadWriteTest extends BriarTestCase { assertArrayEquals(tag, recoveredTag); assertTrue(TagEncoder.validateTag(tag, 0, tagCipher, tagKey)); // Read the frames back - ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in, - frameCipher, frameKey, mac.getMacLength()); + FrameSource decrypter = new ConnectionDecrypter(in, frameCipher, + frameKey, mac.getMacLength()); ConnectionReader reader = new ConnectionReaderImpl(decrypter, mac, macKey); InputStream in1 = reader.getInputStream(); diff --git a/test/net/sf/briar/transport/NullConnectionDecrypter.java b/test/net/sf/briar/transport/NullConnectionDecrypter.java index 68d378469e437127dcf4ed602eebdc4c83408e4e..319df394cc3f4f4988c6c1843734a46c717f4cdf 100644 --- a/test/net/sf/briar/transport/NullConnectionDecrypter.java +++ b/test/net/sf/briar/transport/NullConnectionDecrypter.java @@ -8,9 +8,10 @@ import java.io.IOException; import java.io.InputStream; import net.sf.briar.api.FormatException; +import net.sf.briar.api.plugins.FrameSource; -/** A ConnectionDecrypter that performs no decryption. */ -class NullConnectionDecrypter implements ConnectionDecrypter { +/** A connection decrypter that performs no decryption. */ +class NullConnectionDecrypter implements FrameSource { private final InputStream in; private final int macLength;