diff --git a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java index 0109c7f469e658559d37facaa23f437b92abe5df..741546d2a9eae31d702af0aa6bb99ebda7716a04 100644 --- a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java @@ -44,7 +44,9 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory { } ivKey.erase(); // Validate the IV - if(!IvEncoder.validateIv(iv, true, ctx)) + int index = ctx.getTransportIndex().getInt(); + long connection = ctx.getConnectionNumber(); + if(!IvEncoder.validateIv(iv, index, connection)) throw new IllegalArgumentException(); return createConnectionReader(in, true, ctx); } @@ -62,7 +64,9 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory { ErasableKey macKey = crypto.deriveMacKey(secret, initiator); ByteUtils.erase(secret); // Create the decrypter - byte[] iv = IvEncoder.encodeIv(initiator, ctx); + int index = ctx.getTransportIndex().getInt(); + long connection = ctx.getConnectionNumber(); + byte[] iv = IvEncoder.encodeIv(index, connection); Cipher frameCipher = crypto.getFrameCipher(); ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in, iv, frameCipher, frameKey); diff --git a/components/net/sf/briar/transport/ConnectionRecogniserImpl.java b/components/net/sf/briar/transport/ConnectionRecogniserImpl.java index 744333eca7c281d75306af8a88857685865b71e4..9150586b13ea02f70cec7020609e0d68ac739f43 100644 --- a/components/net/sf/briar/transport/ConnectionRecogniserImpl.java +++ b/components/net/sf/briar/transport/ConnectionRecogniserImpl.java @@ -103,7 +103,7 @@ DatabaseListener { // Locking: this private Bytes calculateIv(Context ctx, byte[] secret) { - byte[] iv = IvEncoder.encodeIv(true, ctx.transportIndex.getInt(), + byte[] iv = IvEncoder.encodeIv(ctx.transportIndex.getInt(), ctx.connection); ErasableKey ivKey = crypto.deriveIvKey(secret, true); try { diff --git a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java index 35b55f47c45ba97255943b36a36c61d7d29835bf..63cf1ba65ae858d9d100e59517b9c11ba31b6669 100644 --- a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java +++ b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java @@ -49,7 +49,9 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { } ivKey.erase(); // Validate the IV - if(!IvEncoder.validateIv(iv, true, ctx)) + int index = ctx.getTransportIndex().getInt(); + long connection = ctx.getConnectionNumber(); + if(!IvEncoder.validateIv(iv, index, connection)) throw new IllegalArgumentException(); return createConnectionWriter(out, capacity, false, ctx); } @@ -63,9 +65,11 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { ErasableKey macKey = crypto.deriveMacKey(secret, initiator); ByteUtils.erase(secret); // Create the encrypter + int index = ctx.getTransportIndex().getInt(); + long connection = ctx.getConnectionNumber(); + byte[] iv = IvEncoder.encodeIv(index, connection); Cipher ivCipher = crypto.getIvCipher(); Cipher frameCipher = crypto.getFrameCipher(); - byte[] iv = IvEncoder.encodeIv(initiator, ctx); ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out, capacity, iv, ivCipher, frameCipher, ivKey, frameKey); // Create the writer diff --git a/components/net/sf/briar/transport/IvEncoder.java b/components/net/sf/briar/transport/IvEncoder.java index 94aa963ffa65b3e3b7343e33c37b7f5fee7099f8..fdb6ea19797cb1e8d7a7d3ac736eb0305086a232 100644 --- a/components/net/sf/briar/transport/IvEncoder.java +++ b/components/net/sf/briar/transport/IvEncoder.java @@ -1,20 +1,12 @@ package net.sf.briar.transport; import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; -import net.sf.briar.api.transport.ConnectionContext; import net.sf.briar.util.ByteUtils; class IvEncoder { - static byte[] encodeIv(boolean initiator, ConnectionContext ctx) { - return encodeIv(initiator, ctx.getTransportIndex().getInt(), - ctx.getConnectionNumber()); - } - - static byte[] encodeIv(boolean initiator, int index, long connection) { + static byte[] encodeIv(int index, long connection) { byte[] iv = new byte[IV_LENGTH]; - // Bit 31 is the initiator flag - if(initiator) iv[3] = 1; // Encode the transport index as an unsigned 16-bit integer ByteUtils.writeUint16(index, iv, 4); // Encode the connection number as an unsigned 32-bit integer @@ -28,21 +20,11 @@ class IvEncoder { ByteUtils.writeUint32(frame, iv, 10); } - static boolean validateIv(byte[] iv, boolean initiator, - ConnectionContext ctx) { - return validateIv(iv, initiator, ctx.getTransportIndex().getInt(), - ctx.getConnectionNumber()); - } - - static boolean validateIv(byte[] iv, boolean initiator, int index, - long connection) { + static boolean validateIv(byte[] iv, int index, long connection) { if(iv.length != IV_LENGTH) return false; // Check that the reserved bits are all zero - for(int j = 0; j < 2; j++) if(iv[j] != 0) return false; - if(iv[3] != 0 && iv[3] != 1) return false; - for(int j = 10; j < iv.length; j++) if(iv[j] != 0) return false; - // Check that the initiator flag matches - if(initiator != getInitiatorFlag(iv)) return false; + for(int i = 0; i < 3; i++) if(iv[i] != 0) return false; + for(int i = 10; i < iv.length; i++) if(iv[i] != 0) return false; // Check that the transport index matches if(index != getTransportIndex(iv)) return false; // Check that the connection number matches @@ -51,11 +33,6 @@ class IvEncoder { return true; } - static boolean getInitiatorFlag(byte[] iv) { - if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); - return (iv[3] & 1) == 1; - } - static int getTransportIndex(byte[] iv) { if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); return ByteUtils.readUint16(iv, 4); diff --git a/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java b/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java index b12651a013f9e1c965c365c40e0df1c1a175e50e..b34e549408beac865f6ca791dea3678563016e49 100644 --- a/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java +++ b/test/net/sf/briar/transport/ConnectionDecrypterImplTest.java @@ -52,8 +52,7 @@ public class ConnectionDecrypterImplTest extends TestCase { private void testDecryption(boolean initiator) throws Exception { // Calculate the plaintext and ciphertext for the IV - byte[] iv = IvEncoder.encodeIv(initiator, transportIndex.getInt(), - connection); + byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); byte[] encryptedIv = ivCipher.doFinal(iv); assertEquals(IV_LENGTH, encryptedIv.length); @@ -86,8 +85,8 @@ public class ConnectionDecrypterImplTest extends TestCase { ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); // Use a ConnectionDecrypter to decrypt the ciphertext ConnectionDecrypter d = new ConnectionDecrypterImpl(in, - IvEncoder.encodeIv(initiator, transportIndex.getInt(), - connection), frameCipher, frameKey); + IvEncoder.encodeIv(transportIndex.getInt(), connection), + frameCipher, frameKey); // First frame byte[] decrypted = new byte[ciphertext.length]; TestUtils.readFully(d.getInputStream(), decrypted); diff --git a/test/net/sf/briar/transport/ConnectionEncrypterImplTest.java b/test/net/sf/briar/transport/ConnectionEncrypterImplTest.java index 0012ea8a8fb61939f0138aaf5b7d258c34a4c9dc..ecbf2cbf5b87a5771fe23fcb47ad1c1717f953c3 100644 --- a/test/net/sf/briar/transport/ConnectionEncrypterImplTest.java +++ b/test/net/sf/briar/transport/ConnectionEncrypterImplTest.java @@ -50,8 +50,7 @@ public class ConnectionEncrypterImplTest extends TestCase { private void testEncryption(boolean initiator) throws Exception { // Calculate the expected ciphertext for the IV - byte[] iv = IvEncoder.encodeIv(initiator, transportIndex.getInt(), - connection); + byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); byte[] encryptedIv = ivCipher.doFinal(iv); assertEquals(IV_LENGTH, encryptedIv.length); @@ -83,7 +82,7 @@ public class ConnectionEncrypterImplTest extends TestCase { byte[] expected = out.toByteArray(); // Use a ConnectionEncrypter to encrypt the plaintext out.reset(); - iv = IvEncoder.encodeIv(initiator, transportIndex.getInt(), connection); + iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); ConnectionEncrypter e = new ConnectionEncrypterImpl(out, Long.MAX_VALUE, iv, ivCipher, frameCipher, ivKey, frameKey); e.getOutputStream().write(plaintext); diff --git a/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java b/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java index e2eda1186c03612818455c0ed4ba720b3cd558c5..3883033dfb0116a8ec19bd7e9dc60027351758fa 100644 --- a/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java +++ b/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java @@ -618,7 +618,7 @@ public class ConnectionRecogniserImplTest extends TestCase { ErasableKey ivKey = crypto.deriveIvKey(secret, true); Cipher ivCipher = crypto.getIvCipher(); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); - byte[] iv = IvEncoder.encodeIv(true, remoteIndex.getInt(), 3); + byte[] iv = IvEncoder.encodeIv(remoteIndex.getInt(), 3); return ivCipher.doFinal(iv); } } diff --git a/test/net/sf/briar/transport/FrameReadWriteTest.java b/test/net/sf/briar/transport/FrameReadWriteTest.java index b7fc4f51d85292d7462ca5521a5ed3503b136c5e..f9d23a66096f300966d11ed36ce0222b3a01c5a2 100644 --- a/test/net/sf/briar/transport/FrameReadWriteTest.java +++ b/test/net/sf/briar/transport/FrameReadWriteTest.java @@ -64,8 +64,7 @@ public class FrameReadWriteTest extends TestCase { private void testWriteAndRead(boolean initiator) throws Exception { // Create and encrypt the IV - byte[] iv = IvEncoder.encodeIv(initiator, transportIndex.getInt(), - connection); + byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); byte[] encryptedIv = ivCipher.doFinal(iv); assertEquals(IV_LENGTH, encryptedIv.length); @@ -97,7 +96,7 @@ public class FrameReadWriteTest extends TestCase { // Decrypt the IV ivCipher.init(Cipher.DECRYPT_MODE, ivKey); byte[] recoveredIv = ivCipher.doFinal(recoveredEncryptedIv); - iv = IvEncoder.encodeIv(initiator, transportIndex.getInt(), connection); + iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); assertArrayEquals(iv, recoveredIv); // Read the frames back ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in, iv,