Added an initiator flag (bit 31) to the IV.

The flag is used to distinguish between the initiator and responder
directions of a stream-mode connection, allowing them to use the same
connection number without risking IV reuse.

The flag is also raised for batch-mode connections, which only have
one direction.
This commit is contained in:
akwizgran
2011-09-07 17:21:52 +01:00
parent 39be97a4d6
commit 7ed747b2a3
13 changed files with 85 additions and 76 deletions

View File

@@ -4,6 +4,6 @@ import java.io.InputStream;
public interface ConnectionReaderFactory { public interface ConnectionReaderFactory {
ConnectionReader createConnectionReader(InputStream in, int transportId, ConnectionReader createConnectionReader(InputStream in, boolean initiator,
long connection, byte[] secret); int transportId, long connection, byte[] secret);
} }

View File

@@ -4,6 +4,6 @@ import java.io.OutputStream;
public interface ConnectionWriterFactory { public interface ConnectionWriterFactory {
ConnectionWriter createConnectionWriter(OutputStream out, int transportId, ConnectionWriter createConnectionWriter(OutputStream out, boolean initiator,
long connection, byte[] secret); int transportId, long connection, byte[] secret);
} }

View File

@@ -20,8 +20,6 @@ import javax.crypto.spec.IvParameterSpec;
class ConnectionDecrypterImpl extends FilterInputStream class ConnectionDecrypterImpl extends FilterInputStream
implements ConnectionDecrypter { implements ConnectionDecrypter {
private final int transportId;
private final long connection;
private final Cipher frameCipher; private final Cipher frameCipher;
private final SecretKey frameKey; private final SecretKey frameKey;
private final byte[] buf, iv; private final byte[] buf, iv;
@@ -30,15 +28,13 @@ implements ConnectionDecrypter {
private long frame = 0L; private long frame = 0L;
private boolean betweenFrames = true; private boolean betweenFrames = true;
ConnectionDecrypterImpl(InputStream in, int transportId, long connection, ConnectionDecrypterImpl(InputStream in, boolean initiator, int transportId,
Cipher frameCipher, SecretKey frameKey) { long connection, Cipher frameCipher, SecretKey frameKey) {
super(in); super(in);
this.transportId = transportId;
this.connection = connection;
this.frameCipher = frameCipher; this.frameCipher = frameCipher;
this.frameKey = frameKey; this.frameKey = frameKey;
buf = new byte[IV_LENGTH]; buf = new byte[IV_LENGTH];
iv = new byte[IV_LENGTH]; iv = IvEncoder.encodeIv(initiator, transportId, connection);
} }
public InputStream getInputStream() { public InputStream getInputStream() {
@@ -132,8 +128,7 @@ implements ConnectionDecrypter {
private void initialiseCipher() { private void initialiseCipher() {
assert betweenFrames; assert betweenFrames;
if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
IvEncoder.encodeIv(iv, transportId, connection, frame); IvEncoder.updateIv(iv, frame);
// Use the plaintext IV to initialise the frame cipher
IvParameterSpec ivSpec = new IvParameterSpec(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv);
try { try {
frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec); frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec);
@@ -145,4 +140,4 @@ implements ConnectionDecrypter {
frame++; frame++;
betweenFrames = false; betweenFrames = false;
} }
} }

View File

@@ -18,25 +18,21 @@ import javax.crypto.spec.IvParameterSpec;
class ConnectionEncrypterImpl extends FilterOutputStream class ConnectionEncrypterImpl extends FilterOutputStream
implements ConnectionEncrypter { implements ConnectionEncrypter {
private final int transportId;
private final long connection;
private final Cipher ivCipher, frameCipher; private final Cipher ivCipher, frameCipher;
private final SecretKey frameKey; private final SecretKey frameKey;
private final byte[] iv; private final byte[] iv;
private long frame = 0L; private long frame = 0L;
private boolean started = false, betweenFrames = false; private boolean ivWritten = false, betweenFrames = false;
ConnectionEncrypterImpl(OutputStream out, int transportId, ConnectionEncrypterImpl(OutputStream out, boolean initiator,
long connection, Cipher ivCipher, Cipher frameCipher, int transportId, long connection, Cipher ivCipher,
SecretKey ivKey, SecretKey frameKey) { Cipher frameCipher, SecretKey ivKey, SecretKey frameKey) {
super(out); super(out);
this.transportId = transportId;
this.connection = connection;
this.ivCipher = ivCipher; this.ivCipher = ivCipher;
this.frameCipher = frameCipher; this.frameCipher = frameCipher;
this.frameKey = frameKey; this.frameKey = frameKey;
iv = new byte[IV_LENGTH]; iv = IvEncoder.encodeIv(initiator, transportId, connection);
try { try {
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey);
} catch(InvalidKeyException badKey) { } catch(InvalidKeyException badKey) {
@@ -51,7 +47,7 @@ implements ConnectionEncrypter {
} }
public void writeMac(byte[] mac) throws IOException { public void writeMac(byte[] mac) throws IOException {
if(!started || betweenFrames) throw new IllegalStateException(); if(!ivWritten || betweenFrames) throw new IllegalStateException();
try { try {
out.write(frameCipher.doFinal(mac)); out.write(frameCipher.doFinal(mac));
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
@@ -64,7 +60,7 @@ implements ConnectionEncrypter {
@Override @Override
public void write(int b) throws IOException { public void write(int b) throws IOException {
if(!started) writeIv(); if(!ivWritten) writeIv();
if(betweenFrames) initialiseCipher(); if(betweenFrames) initialiseCipher();
byte[] ciphertext = frameCipher.update(new byte[] {(byte) b}); byte[] ciphertext = frameCipher.update(new byte[] {(byte) b});
if(ciphertext != null) out.write(ciphertext); if(ciphertext != null) out.write(ciphertext);
@@ -77,16 +73,15 @@ implements ConnectionEncrypter {
@Override @Override
public void write(byte[] b, int off, int len) throws IOException { public void write(byte[] b, int off, int len) throws IOException {
if(!started) writeIv(); if(!ivWritten) writeIv();
if(betweenFrames) initialiseCipher(); if(betweenFrames) initialiseCipher();
byte[] ciphertext = frameCipher.update(b, off, len); byte[] ciphertext = frameCipher.update(b, off, len);
if(ciphertext != null) out.write(ciphertext); if(ciphertext != null) out.write(ciphertext);
} }
private void writeIv() throws IOException { private void writeIv() throws IOException {
assert !started; assert !ivWritten;
assert !betweenFrames; assert !betweenFrames;
IvEncoder.encodeIv(iv, transportId, connection, 0L);
try { try {
out.write(ivCipher.doFinal(iv)); out.write(ivCipher.doFinal(iv));
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
@@ -94,15 +89,15 @@ implements ConnectionEncrypter {
} catch(IllegalBlockSizeException badCipher) { } catch(IllegalBlockSizeException badCipher) {
throw new RuntimeException(badCipher); throw new RuntimeException(badCipher);
} }
started = true; ivWritten = true;
betweenFrames = true; betweenFrames = true;
} }
private void initialiseCipher() { private void initialiseCipher() {
assert started; assert ivWritten;
assert betweenFrames; assert betweenFrames;
if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
IvEncoder.encodeIv(iv, transportId, connection, frame); IvEncoder.updateIv(iv, frame);
IvParameterSpec ivSpec = new IvParameterSpec(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv);
try { try {
frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec);

View File

@@ -23,7 +23,8 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
} }
public ConnectionReader createConnectionReader(InputStream in, public ConnectionReader createConnectionReader(InputStream in,
int transportId, long connection, byte[] secret) { boolean initiator, int transportId, long connection,
byte[] secret) {
SecretKey macKey = crypto.deriveIncomingMacKey(secret); SecretKey macKey = crypto.deriveIncomingMacKey(secret);
SecretKey frameKey = crypto.deriveIncomingFrameKey(secret); SecretKey frameKey = crypto.deriveIncomingFrameKey(secret);
Cipher frameCipher = crypto.getFrameCipher(); Cipher frameCipher = crypto.getFrameCipher();
@@ -34,7 +35,7 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in, ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in,
transportId, connection, frameCipher, frameKey); initiator, transportId, connection, frameCipher, frameKey);
return new ConnectionReaderImpl(decrypter, mac); return new ConnectionReaderImpl(decrypter, mac);
} }
} }

View File

@@ -81,7 +81,7 @@ DatabaseListener {
} }
private synchronized byte[] encryptIv(ContactId c, long connection) { private synchronized byte[] encryptIv(ContactId c, long connection) {
byte[] iv = IvEncoder.encodeIv(transportId, connection); byte[] iv = IvEncoder.encodeIv(true, transportId, connection);
Cipher cipher = contactToCipher.get(c); Cipher cipher = contactToCipher.get(c);
assert cipher != null; assert cipher != null;
try { try {

View File

@@ -23,7 +23,8 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
} }
public ConnectionWriter createConnectionWriter(OutputStream out, public ConnectionWriter createConnectionWriter(OutputStream out,
int transportId, long connection, byte[] secret) { boolean initiator, int transportId, long connection,
byte[] secret) {
SecretKey macKey = crypto.deriveOutgoingMacKey(secret); SecretKey macKey = crypto.deriveOutgoingMacKey(secret);
SecretKey ivKey = crypto.deriveOutgoingIvKey(secret); SecretKey ivKey = crypto.deriveOutgoingIvKey(secret);
SecretKey frameKey = crypto.deriveOutgoingFrameKey(secret); SecretKey frameKey = crypto.deriveOutgoingFrameKey(secret);
@@ -36,8 +37,8 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
throw new IllegalArgumentException(badKey); throw new IllegalArgumentException(badKey);
} }
ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out, ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out,
transportId, connection, ivCipher, frameCipher, ivKey, initiator, transportId, connection, ivCipher, frameCipher,
frameKey); ivKey, frameKey);
return new ConnectionWriterImpl(encrypter, mac); return new ConnectionWriterImpl(encrypter, mac);
} }
} }

View File

@@ -5,8 +5,11 @@ import net.sf.briar.util.ByteUtils;
class IvEncoder { class IvEncoder {
static byte[] encodeIv(int transportId, long connection) { static byte[] encodeIv(boolean initiator, int transportId,
long connection) {
byte[] iv = new byte[IV_LENGTH]; byte[] iv = new byte[IV_LENGTH];
// Bit 31 is the initiator flag
if(initiator) iv[3] = 1;
// Encode the transport identifier as an unsigned 16-bit integer // Encode the transport identifier as an unsigned 16-bit integer
ByteUtils.writeUint16(transportId, iv, 4); ByteUtils.writeUint16(transportId, iv, 4);
// Encode the connection number as an unsigned 32-bit integer // Encode the connection number as an unsigned 32-bit integer
@@ -14,20 +17,9 @@ class IvEncoder {
return iv; return iv;
} }
static void encodeIv(byte[] iv, int transportId, long connection, static void updateIv(byte[] iv, long frame) {
long frame) {
if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); if(iv.length != IV_LENGTH) throw new IllegalArgumentException();
// The first 16 bits of the IV must be zero (reserved)
iv[0] = 0;
iv[1] = 0;
// Encode the transport identifier as an unsigned 16-bit integer
ByteUtils.writeUint16(transportId, iv, 4);
// Encode the connection number as an unsigned 32-bit integer
ByteUtils.writeUint32(connection, iv, 6);
// Encode the frame number as an unsigned 32-bit integer // Encode the frame number as an unsigned 32-bit integer
ByteUtils.writeUint32(frame, iv, 10); ByteUtils.writeUint32(frame, iv, 10);
// The last 16 bits of the IV must be zero (block number)
iv[14] = 0;
iv[15] = 0;
} }
} }

View File

@@ -135,7 +135,7 @@ public class FileReadWriteTest extends TestCase {
OutputStream out = new FileOutputStream(file); OutputStream out = new FileOutputStream(file);
// Use Alice's secret for writing // Use Alice's secret for writing
ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out, ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
transportId, connection, aliceSecret); true, transportId, connection, aliceSecret);
out = w.getOutputStream(); out = w.getOutputStream();
AckWriter a = protocolWriterFactory.createAckWriter(out); AckWriter a = protocolWriterFactory.createAckWriter(out);
@@ -194,7 +194,7 @@ public class FileReadWriteTest extends TestCase {
assertEquals(16, offset); assertEquals(16, offset);
// Use Bob's secret for reading // Use Bob's secret for reading
ConnectionReader r = connectionReaderFactory.createConnectionReader(in, ConnectionReader r = connectionReaderFactory.createConnectionReader(in,
transportId, connection, bobSecret); true, transportId, connection, bobSecret);
in = r.getInputStream(); in = r.getInputStream();
ProtocolReader protocolReader = ProtocolReader protocolReader =
protocolReaderFactory.createProtocolReader(in); protocolReaderFactory.createProtocolReader(in);

View File

@@ -1,7 +1,5 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.util.Arrays; import java.util.Arrays;
@@ -43,25 +41,33 @@ public class ConnectionDecrypterImplTest extends TestCase {
byte[] ciphertext = new byte[1 + MAC_LENGTH]; byte[] ciphertext = new byte[1 + MAC_LENGTH];
ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
// Check that one byte plus a MAC can be read // Check that one byte plus a MAC can be read
ConnectionDecrypter d = new ConnectionDecrypterImpl(in, transportId, ConnectionDecrypter d = new ConnectionDecrypterImpl(in, true,
connection, frameCipher, frameKey); transportId, connection, frameCipher, frameKey);
assertFalse(d.getInputStream().read() == -1); assertFalse(d.getInputStream().read() == -1);
d.readMac(new byte[MAC_LENGTH]); d.readMac(new byte[MAC_LENGTH]);
assertTrue(d.getInputStream().read() == -1); assertTrue(d.getInputStream().read() == -1);
} }
@Test @Test
public void testDecryption() throws Exception { public void testInitiatorDecryption() throws Exception {
testDecryption(true);
}
@Test
public void testResponderDecryption() throws Exception {
testDecryption(false);
}
private void testDecryption(boolean initiator) throws Exception {
// Calculate the expected plaintext for the first frame // Calculate the expected plaintext for the first frame
byte[] ciphertext = new byte[123]; byte[] ciphertext = new byte[123];
byte[] iv = new byte[IV_LENGTH]; byte[] iv = IvEncoder.encodeIv(initiator, transportId, connection);
IvEncoder.encodeIv(iv, transportId, connection, 0L);
IvParameterSpec ivSpec = new IvParameterSpec(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv);
frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec); frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec);
byte[] plaintext = frameCipher.doFinal(ciphertext); byte[] plaintext = frameCipher.doFinal(ciphertext);
// Calculate the expected plaintext for the second frame // Calculate the expected plaintext for the second frame
byte[] ciphertext1 = new byte[1234]; byte[] ciphertext1 = new byte[1234];
IvEncoder.encodeIv(iv, transportId, connection, 1L); IvEncoder.updateIv(iv, 1L);
ivSpec = new IvParameterSpec(iv); ivSpec = new IvParameterSpec(iv);
frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec); frameCipher.init(Cipher.DECRYPT_MODE, frameKey, ivSpec);
byte[] plaintext1 = frameCipher.doFinal(ciphertext1); byte[] plaintext1 = frameCipher.doFinal(ciphertext1);
@@ -72,8 +78,8 @@ public class ConnectionDecrypterImplTest extends TestCase {
out.write(ciphertext1); out.write(ciphertext1);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
// Use a ConnectionDecrypter to decrypt the ciphertext // Use a ConnectionDecrypter to decrypt the ciphertext
ConnectionDecrypter d = new ConnectionDecrypterImpl(in, transportId, ConnectionDecrypter d = new ConnectionDecrypterImpl(in, initiator,
connection, frameCipher, frameKey); transportId, connection, frameCipher, frameKey);
// First frame // First frame
byte[] decrypted = new byte[plaintext.length - MAC_LENGTH]; byte[] decrypted = new byte[plaintext.length - MAC_LENGTH];
TestUtils.readFully(d.getInputStream(), decrypted); TestUtils.readFully(d.getInputStream(), decrypted);

View File

@@ -40,17 +40,27 @@ public class ConnectionEncrypterImplTest extends TestCase {
@Test @Test
public void testSingleByteFrame() throws Exception { public void testSingleByteFrame() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionEncrypter e = new ConnectionEncrypterImpl(out, transportId, ConnectionEncrypter e = new ConnectionEncrypterImpl(out, true,
connection, ivCipher, frameCipher, ivKey, frameKey); transportId, connection, ivCipher, frameCipher, ivKey,
frameKey);
e.getOutputStream().write((byte) 0); e.getOutputStream().write((byte) 0);
e.writeMac(new byte[MAC_LENGTH]); e.writeMac(new byte[MAC_LENGTH]);
assertEquals(IV_LENGTH + 1 + MAC_LENGTH, out.toByteArray().length); assertEquals(IV_LENGTH + 1 + MAC_LENGTH, out.toByteArray().length);
} }
@Test @Test
public void testEncryption() throws Exception { public void testInitiatorEncryption() throws Exception {
testEncryption(true);
}
@Test
public void testResponderEncryption() throws Exception {
testEncryption(false);
}
private void testEncryption(boolean initiator) throws Exception {
// Calculate the expected ciphertext for the IV // Calculate the expected ciphertext for the IV
byte[] iv = IvEncoder.encodeIv(transportId, connection); byte[] iv = IvEncoder.encodeIv(initiator, transportId, connection);
assertEquals(IV_LENGTH, iv.length); assertEquals(IV_LENGTH, iv.length);
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] encryptedIv = ivCipher.doFinal(iv);
@@ -58,7 +68,6 @@ public class ConnectionEncrypterImplTest extends TestCase {
// Calculate the expected ciphertext for the first frame // Calculate the expected ciphertext for the first frame
byte[] plaintext = new byte[123]; byte[] plaintext = new byte[123];
byte[] plaintextMac = new byte[MAC_LENGTH]; byte[] plaintextMac = new byte[MAC_LENGTH];
IvEncoder.encodeIv(iv, transportId, connection, 0L);
IvParameterSpec ivSpec = new IvParameterSpec(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv);
frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec);
byte[] ciphertext = new byte[plaintext.length + plaintextMac.length]; byte[] ciphertext = new byte[plaintext.length + plaintextMac.length];
@@ -68,7 +77,7 @@ public class ConnectionEncrypterImplTest extends TestCase {
offset); offset);
// Calculate the expected ciphertext for the second frame // Calculate the expected ciphertext for the second frame
byte[] plaintext1 = new byte[1234]; byte[] plaintext1 = new byte[1234];
IvEncoder.encodeIv(iv, transportId, connection, 1L); IvEncoder.updateIv(iv, 1L);
ivSpec = new IvParameterSpec(iv); ivSpec = new IvParameterSpec(iv);
frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec); frameCipher.init(Cipher.ENCRYPT_MODE, frameKey, ivSpec);
byte[] ciphertext1 = new byte[plaintext1.length + plaintextMac.length]; byte[] ciphertext1 = new byte[plaintext1.length + plaintextMac.length];
@@ -84,8 +93,9 @@ public class ConnectionEncrypterImplTest extends TestCase {
byte[] expected = out.toByteArray(); byte[] expected = out.toByteArray();
// Use a ConnectionEncrypter to encrypt the plaintext // Use a ConnectionEncrypter to encrypt the plaintext
out.reset(); out.reset();
ConnectionEncrypter e = new ConnectionEncrypterImpl(out, transportId, ConnectionEncrypter e = new ConnectionEncrypterImpl(out, initiator,
connection, ivCipher, frameCipher, ivKey, frameKey); transportId, connection, ivCipher, frameCipher, ivKey,
frameKey);
e.getOutputStream().write(plaintext); e.getOutputStream().write(plaintext);
e.writeMac(plaintextMac); e.writeMac(plaintextMac);
e.getOutputStream().write(plaintext1); e.getOutputStream().write(plaintext1);

View File

@@ -65,7 +65,7 @@ public class ConnectionRecogniserImplTest extends TestCase {
SecretKey ivKey = crypto.deriveIncomingIvKey(secret); SecretKey ivKey = crypto.deriveIncomingIvKey(secret);
Cipher ivCipher = crypto.getIvCipher(); Cipher ivCipher = crypto.getIvCipher();
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey);
byte[] iv = IvEncoder.encodeIv(transportId, 3L); byte[] iv = IvEncoder.encodeIv(true, transportId, 3L);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] encryptedIv = ivCipher.doFinal(iv);
Mockery context = new Mockery(); Mockery context = new Mockery();

View File

@@ -50,9 +50,18 @@ public class FrameReadWriteTest extends TestCase {
} }
@Test @Test
public void testWriteAndRead() throws Exception { public void testInitiatorWriteAndRead() throws Exception {
testWriteAndRead(true);
}
@Test
public void testResponderWriteAndRead() throws Exception {
testWriteAndRead(false);
}
private void testWriteAndRead(boolean initiator) throws Exception {
// Calculate the expected ciphertext for the IV // Calculate the expected ciphertext for the IV
byte[] iv = IvEncoder.encodeIv(transportId, connection); byte[] iv = IvEncoder.encodeIv(initiator, transportId, connection);
assertEquals(IV_LENGTH, iv.length); assertEquals(IV_LENGTH, iv.length);
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); ivCipher.init(Cipher.ENCRYPT_MODE, ivKey);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] encryptedIv = ivCipher.doFinal(iv);
@@ -65,8 +74,8 @@ public class FrameReadWriteTest extends TestCase {
// Write the frames // Write the frames
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out, ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out,
transportId, connection, ivCipher, frameCipher, ivKey, initiator, transportId, connection, ivCipher, frameCipher,
frameKey); ivKey, frameKey);
mac.init(macKey); mac.init(macKey);
ConnectionWriter writer = new ConnectionWriterImpl(encrypter, mac); ConnectionWriter writer = new ConnectionWriterImpl(encrypter, mac);
OutputStream out1 = writer.getOutputStream(); OutputStream out1 = writer.getOutputStream();
@@ -80,7 +89,7 @@ public class FrameReadWriteTest extends TestCase {
assertEquals(IV_LENGTH, in.read(recoveredIv)); assertEquals(IV_LENGTH, in.read(recoveredIv));
assertTrue(Arrays.equals(encryptedIv, recoveredIv)); assertTrue(Arrays.equals(encryptedIv, recoveredIv));
ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in, ConnectionDecrypter decrypter = new ConnectionDecrypterImpl(in,
transportId, connection, frameCipher, frameKey); initiator, transportId, connection, frameCipher, frameKey);
ConnectionReader reader = new ConnectionReaderImpl(decrypter, mac); ConnectionReader reader = new ConnectionReaderImpl(decrypter, mac);
InputStream in1 = reader.getInputStream(); InputStream in1 = reader.getInputStream();
byte[] recovered = new byte[frame.length]; byte[] recovered = new byte[frame.length];