Commit d940c637 authored by akwizgran's avatar akwizgran

Fixed key derivation issues, moved tag encoding into crypto component.

parent 5628342c
...@@ -53,6 +53,10 @@ public interface CryptoComponent { ...@@ -53,6 +53,10 @@ public interface CryptoComponent {
*/ */
byte[] deriveNextSecret(byte[] secret, long period); byte[] deriveNextSecret(byte[] secret, long period);
/** Encodes the pseudo-random tag that is used to recognise a connection. */
void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
long connection);
KeyPair generateAgreementKeyPair(); KeyPair generateAgreementKeyPair();
KeyPair generateSignatureKeyPair(); KeyPair generateSignatureKeyPair();
......
...@@ -9,6 +9,7 @@ public class TemporarySecret extends ContactTransport { ...@@ -9,6 +9,7 @@ public class TemporarySecret extends ContactTransport {
private final long period, outgoing, centre; private final long period, outgoing, centre;
private final byte[] secret, bitmap; private final byte[] secret, bitmap;
/** Creates a temporary secret with the given connection window. */
public TemporarySecret(ContactId contactId, TransportId transportId, public TemporarySecret(ContactId contactId, TransportId transportId,
long epoch, long clockDiff, long latency, boolean alice, long epoch, long clockDiff, long latency, boolean alice,
long period, byte[] secret, long outgoing, long centre, long period, byte[] secret, long outgoing, long centre,
...@@ -21,14 +22,19 @@ public class TemporarySecret extends ContactTransport { ...@@ -21,14 +22,19 @@ public class TemporarySecret extends ContactTransport {
this.bitmap = bitmap; this.bitmap = bitmap;
} }
/** Creates a temporary secret with a new connection window. */
public TemporarySecret(ContactId contactId, TransportId transportId,
long epoch, long clockDiff, long latency, boolean alice,
long period, byte[] secret) {
this(contactId, transportId, epoch, clockDiff, latency, alice, period,
secret, 0L, 0L, new byte[CONNECTION_WINDOW_SIZE / 8]);
}
/** Creates a temporary secret derived from the given temporary secret. */
public TemporarySecret(TemporarySecret old, long period, byte[] secret) { public TemporarySecret(TemporarySecret old, long period, byte[] secret) {
super(old.getContactId(), old.getTransportId(), old.getEpoch(), this(old.getContactId(), old.getTransportId(), old.getEpoch(),
old.getClockDifference(), old.getLatency(), old.getAlice()); old.getClockDifference(), old.getLatency(), old.getAlice(),
this.period = period; period, secret);
this.secret = secret;
outgoing = 0L;
centre = 0L;
bitmap = new byte[CONNECTION_WINDOW_SIZE / 8];
} }
public long getPeriod() { public long getPeriod() {
......
...@@ -8,5 +8,5 @@ public interface ConnectionReaderFactory { ...@@ -8,5 +8,5 @@ public interface ConnectionReaderFactory {
* Creates a connection reader for one side of a connection. * Creates a connection reader for one side of a connection.
*/ */
ConnectionReader createConnectionReader(InputStream in, ConnectionReader createConnectionReader(InputStream in,
ConnectionContext ctx, boolean initiator); ConnectionContext ctx, boolean incoming, boolean initiator);
} }
...@@ -8,5 +8,5 @@ public interface ConnectionWriterFactory { ...@@ -8,5 +8,5 @@ public interface ConnectionWriterFactory {
* Creates a connection writer for one side of a connection. * Creates a connection writer for one side of a connection.
*/ */
ConnectionWriter createConnectionWriter(OutputStream out, long capacity, ConnectionWriter createConnectionWriter(OutputStream out, long capacity,
ConnectionContext ctx, boolean initiator); ConnectionContext ctx, boolean incoming, boolean initiator);
} }
package net.sf.briar.crypto; package net.sf.briar.crypto;
import static javax.crypto.Cipher.ENCRYPT_MODE;
import static net.sf.briar.api.plugins.InvitationConstants.CODE_BITS; import static net.sf.briar.api.plugins.InvitationConstants.CODE_BITS;
import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
...@@ -210,6 +212,23 @@ class CryptoComponentImpl implements CryptoComponent { ...@@ -210,6 +212,23 @@ class CryptoComponentImpl implements CryptoComponent {
return counterModeKdf(secret, ROTATE, period); return counterModeKdf(secret, ROTATE, period);
} }
public void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
long connection) {
if(tag.length < TAG_LENGTH) throw new IllegalArgumentException();
if(connection < 0 || connection > MAX_32_BIT_UNSIGNED)
throw new IllegalArgumentException();
for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
ByteUtils.writeUint32(connection, tag, 0);
try {
tagCipher.init(ENCRYPT_MODE, tagKey);
int encrypted = tagCipher.doFinal(tag, 0, TAG_LENGTH, tag);
if(encrypted != TAG_LENGTH) throw new IllegalArgumentException();
} catch(GeneralSecurityException e) {
// Unsuitable cipher or key
throw new IllegalArgumentException(e);
}
}
public int generateInvitationCode() { public int generateInvitationCode() {
int codeBytes = (int) Math.ceil(CODE_BITS / 8.0); int codeBytes = (int) Math.ceil(CODE_BITS / 8.0);
byte[] random = new byte[codeBytes]; byte[] random = new byte[codeBytes];
......
...@@ -34,12 +34,12 @@ class IncomingDuplexConnection extends DuplexConnection { ...@@ -34,12 +34,12 @@ class IncomingDuplexConnection extends DuplexConnection {
@Override @Override
protected ConnectionReader createConnectionReader() throws IOException { protected ConnectionReader createConnectionReader() throws IOException {
return connReaderFactory.createConnectionReader( return connReaderFactory.createConnectionReader(
transport.getInputStream(), ctx, true); transport.getInputStream(), ctx, true, true);
} }
@Override @Override
protected ConnectionWriter createConnectionWriter() throws IOException { protected ConnectionWriter createConnectionWriter() throws IOException {
return connWriterFactory.createConnectionWriter( return connWriterFactory.createConnectionWriter(
transport.getOutputStream(), Long.MAX_VALUE, ctx, false); transport.getOutputStream(), Long.MAX_VALUE, ctx, true, false);
} }
} }
...@@ -34,12 +34,12 @@ class OutgoingDuplexConnection extends DuplexConnection { ...@@ -34,12 +34,12 @@ class OutgoingDuplexConnection extends DuplexConnection {
@Override @Override
protected ConnectionReader createConnectionReader() throws IOException { protected ConnectionReader createConnectionReader() throws IOException {
return connReaderFactory.createConnectionReader( return connReaderFactory.createConnectionReader(
transport.getInputStream(), ctx, false); transport.getInputStream(), ctx, false, false);
} }
@Override @Override
protected ConnectionWriter createConnectionWriter() throws IOException { protected ConnectionWriter createConnectionWriter() throws IOException {
return connWriterFactory.createConnectionWriter( return connWriterFactory.createConnectionWriter(
transport.getOutputStream(), Long.MAX_VALUE, ctx, true); transport.getOutputStream(), Long.MAX_VALUE, ctx, false, true);
} }
} }
...@@ -65,7 +65,7 @@ class IncomingSimplexConnection { ...@@ -65,7 +65,7 @@ class IncomingSimplexConnection {
connRegistry.registerConnection(contactId, transportId); connRegistry.registerConnection(contactId, transportId);
try { try {
ConnectionReader conn = connFactory.createConnectionReader( ConnectionReader conn = connFactory.createConnectionReader(
transport.getInputStream(), ctx, true); transport.getInputStream(), ctx, true, true);
InputStream in = conn.getInputStream(); InputStream in = conn.getInputStream();
ProtocolReader reader = protoFactory.createProtocolReader(in); ProtocolReader reader = protoFactory.createProtocolReader(in);
// Read packets until EOF // Read packets until EOF
......
...@@ -59,7 +59,7 @@ class OutgoingSimplexConnection { ...@@ -59,7 +59,7 @@ class OutgoingSimplexConnection {
try { try {
ConnectionWriter conn = connFactory.createConnectionWriter( ConnectionWriter conn = connFactory.createConnectionWriter(
transport.getOutputStream(), transport.getCapacity(), transport.getOutputStream(), transport.getCapacity(),
ctx, true); ctx, false, true);
OutputStream out = conn.getOutputStream(); OutputStream out = conn.getOutputStream();
ProtocolWriter writer = protoFactory.createProtocolWriter(out, ProtocolWriter writer = protoFactory.createProtocolWriter(out,
transport.shouldFlush()); transport.shouldFlush());
......
...@@ -22,12 +22,13 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory { ...@@ -22,12 +22,13 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
} }
public ConnectionReader createConnectionReader(InputStream in, public ConnectionReader createConnectionReader(InputStream in,
ConnectionContext ctx, boolean initiator) { ConnectionContext ctx, boolean incoming, boolean initiator) {
byte[] secret = ctx.getSecret(); byte[] secret = ctx.getSecret();
long connection = ctx.getConnectionNumber(); long connection = ctx.getConnectionNumber();
boolean alice = ctx.getAlice(); boolean weAreAlice = ctx.getAlice();
ErasableKey frameKey = crypto.deriveFrameKey(secret, connection, alice, boolean initiatorIsAlice = incoming ? !weAreAlice : weAreAlice;
initiator); ErasableKey frameKey = crypto.deriveFrameKey(secret, connection,
initiatorIsAlice, initiator);
FrameReader encryption = new IncomingEncryptionLayer(in, FrameReader encryption = new IncomingEncryptionLayer(in,
crypto.getFrameCipher(), frameKey, MAX_FRAME_LENGTH); crypto.getFrameCipher(), frameKey, MAX_FRAME_LENGTH);
return new ConnectionReaderImpl(encryption, MAX_FRAME_LENGTH); return new ConnectionReaderImpl(encryption, MAX_FRAME_LENGTH);
......
...@@ -26,18 +26,20 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory { ...@@ -26,18 +26,20 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
} }
public ConnectionWriter createConnectionWriter(OutputStream out, public ConnectionWriter createConnectionWriter(OutputStream out,
long capacity, ConnectionContext ctx, boolean initiator) { long capacity, ConnectionContext ctx, boolean incoming,
boolean initiator) {
byte[] secret = ctx.getSecret(); byte[] secret = ctx.getSecret();
long connection = ctx.getConnectionNumber(); long connection = ctx.getConnectionNumber();
boolean alice = ctx.getAlice(); boolean weAreAlice = ctx.getAlice();
ErasableKey frameKey = crypto.deriveFrameKey(secret, connection, alice, boolean initiatorIsAlice = incoming ? !weAreAlice : weAreAlice;
initiator); ErasableKey frameKey = crypto.deriveFrameKey(secret, connection,
initiatorIsAlice, initiator);
FrameWriter encryption; FrameWriter encryption;
if(initiator) { if(initiator) {
byte[] tag = new byte[TAG_LENGTH]; byte[] tag = new byte[TAG_LENGTH];
Cipher tagCipher = crypto.getTagCipher(); Cipher tagCipher = crypto.getTagCipher();
ErasableKey tagKey = crypto.deriveTagKey(secret, alice); ErasableKey tagKey = crypto.deriveTagKey(secret, initiatorIsAlice);
TagEncoder.encodeTag(tag, tagCipher, tagKey, connection); crypto.encodeTag(tag, tagCipher, tagKey, connection);
encryption = new OutgoingEncryptionLayer(out, capacity, encryption = new OutgoingEncryptionLayer(out, capacity,
crypto.getFrameCipher(), frameKey, MAX_FRAME_LENGTH, tag); crypto.getFrameCipher(), frameKey, MAX_FRAME_LENGTH, tag);
} else { } else {
......
package net.sf.briar.transport;
import static javax.crypto.Cipher.ENCRYPT_MODE;
import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import net.sf.briar.api.crypto.ErasableKey;
import net.sf.briar.util.ByteUtils;
class TagEncoder {
static void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
long connection) {
if(tag.length < TAG_LENGTH) throw new IllegalArgumentException();
if(connection < 0 || connection > MAX_32_BIT_UNSIGNED)
throw new IllegalArgumentException();
for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
ByteUtils.writeUint32(connection, tag, 0);
try {
tagCipher.init(ENCRYPT_MODE, tagKey);
int encrypted = tagCipher.doFinal(tag, 0, TAG_LENGTH, tag);
if(encrypted != TAG_LENGTH) throw new IllegalArgumentException();
} catch(GeneralSecurityException e) {
// Unsuitable cipher or key
throw new IllegalArgumentException(e);
}
}
}
...@@ -51,10 +51,10 @@ class TransportConnectionRecogniser { ...@@ -51,10 +51,10 @@ class TransportConnectionRecogniser {
boolean alice = ctx.getAlice(); boolean alice = ctx.getAlice();
// Update the connection window and the expected tags // Update the connection window and the expected tags
Cipher cipher = crypto.getTagCipher(); Cipher cipher = crypto.getTagCipher();
ErasableKey key = crypto.deriveTagKey(secret, alice); ErasableKey key = crypto.deriveTagKey(secret, !alice);
for(long connection1 : window.setSeen(connection)) { for(long connection1 : window.setSeen(connection)) {
byte[] tag1 = new byte[TAG_LENGTH]; byte[] tag1 = new byte[TAG_LENGTH];
TagEncoder.encodeTag(tag1, cipher, key, connection1); crypto.encodeTag(tag1, cipher, key, connection1);
if(connection1 <= connection) { if(connection1 <= connection) {
WindowContext old = tagMap.remove(new Bytes(tag1)); WindowContext old = tagMap.remove(new Bytes(tag1));
assert old != null; assert old != null;
...@@ -84,11 +84,11 @@ class TransportConnectionRecogniser { ...@@ -84,11 +84,11 @@ class TransportConnectionRecogniser {
byte[] bitmap = s.getWindowBitmap(); byte[] bitmap = s.getWindowBitmap();
// Create the connection window and the expected tags // Create the connection window and the expected tags
Cipher cipher = crypto.getTagCipher(); Cipher cipher = crypto.getTagCipher();
ErasableKey key = crypto.deriveTagKey(secret, alice); ErasableKey key = crypto.deriveTagKey(secret, !alice);
ConnectionWindow window = new ConnectionWindow(centre, bitmap); ConnectionWindow window = new ConnectionWindow(centre, bitmap);
for(long connection : window.getUnseen()) { for(long connection : window.getUnseen()) {
byte[] tag = new byte[TAG_LENGTH]; byte[] tag = new byte[TAG_LENGTH];
TagEncoder.encodeTag(tag, cipher, key, connection); crypto.encodeTag(tag, cipher, key, connection);
ConnectionContext ctx = new ConnectionContext(contactId, ConnectionContext ctx = new ConnectionContext(contactId,
transportId, secret.clone(), connection, alice); transportId, secret.clone(), connection, alice);
WindowContext wctx = new WindowContext(window, ctx, period); WindowContext wctx = new WindowContext(window, ctx, period);
...@@ -113,10 +113,10 @@ class TransportConnectionRecogniser { ...@@ -113,10 +113,10 @@ class TransportConnectionRecogniser {
private void removeSecret(RemovalContext rctx) { private void removeSecret(RemovalContext rctx) {
// Remove the expected tags // Remove the expected tags
Cipher cipher = crypto.getTagCipher(); Cipher cipher = crypto.getTagCipher();
ErasableKey key = crypto.deriveTagKey(rctx.secret, rctx.alice); ErasableKey key = crypto.deriveTagKey(rctx.secret, !rctx.alice);
byte[] tag = new byte[TAG_LENGTH]; byte[] tag = new byte[TAG_LENGTH];
for(long connection : rctx.window.getUnseen()) { for(long connection : rctx.window.getUnseen()) {
TagEncoder.encodeTag(tag, cipher, key, connection); crypto.encodeTag(tag, cipher, key, connection);
WindowContext old = tagMap.remove(new Bytes(tag)); WindowContext old = tagMap.remove(new Bytes(tag));
assert old != null; assert old != null;
ByteUtils.erase(old.context.getSecret()); ByteUtils.erase(old.context.getSecret());
......
...@@ -144,7 +144,7 @@ public class ProtocolIntegrationTest extends BriarTestCase { ...@@ -144,7 +144,7 @@ public class ProtocolIntegrationTest extends BriarTestCase {
ConnectionContext ctx = new ConnectionContext(contactId, transportId, ConnectionContext ctx = new ConnectionContext(contactId, transportId,
secret.clone(), 0L, true); secret.clone(), 0L, true);
ConnectionWriter conn = connectionWriterFactory.createConnectionWriter( ConnectionWriter conn = connectionWriterFactory.createConnectionWriter(
out, Long.MAX_VALUE, ctx, true); out, Long.MAX_VALUE, ctx, false, true);
OutputStream out1 = conn.getOutputStream(); OutputStream out1 = conn.getOutputStream();
ProtocolWriter writer = protocolWriterFactory.createProtocolWriter(out1, ProtocolWriter writer = protocolWriterFactory.createProtocolWriter(out1,
false); false);
...@@ -191,9 +191,9 @@ public class ProtocolIntegrationTest extends BriarTestCase { ...@@ -191,9 +191,9 @@ public class ProtocolIntegrationTest extends BriarTestCase {
assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH)); assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH));
// FIXME: Check that the expected tag was received // FIXME: Check that the expected tag was received
ConnectionContext ctx = new ConnectionContext(contactId, transportId, ConnectionContext ctx = new ConnectionContext(contactId, transportId,
secret.clone(), 0L, true); secret.clone(), 0L, false);
ConnectionReader conn = connectionReaderFactory.createConnectionReader( ConnectionReader conn = connectionReaderFactory.createConnectionReader(
in, ctx, true); in, ctx, true, true);
InputStream in1 = conn.getInputStream(); InputStream in1 = conn.getInputStream();
ProtocolReader reader = protocolReaderFactory.createProtocolReader(in1); ProtocolReader reader = protocolReaderFactory.createProtocolReader(in1);
......
...@@ -13,7 +13,9 @@ import net.sf.briar.BriarTestCase; ...@@ -13,7 +13,9 @@ import net.sf.briar.BriarTestCase;
import net.sf.briar.TestDatabaseModule; import net.sf.briar.TestDatabaseModule;
import net.sf.briar.TestUtils; import net.sf.briar.TestUtils;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
import net.sf.briar.api.crypto.KeyManager;
import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.TemporarySecret;
import net.sf.briar.api.db.event.DatabaseEvent; import net.sf.briar.api.db.event.DatabaseEvent;
import net.sf.briar.api.db.event.DatabaseListener; import net.sf.briar.api.db.event.DatabaseListener;
import net.sf.briar.api.db.event.MessagesAddedEvent; import net.sf.briar.api.db.event.MessagesAddedEvent;
...@@ -48,11 +50,15 @@ import com.google.inject.Injector; ...@@ -48,11 +50,15 @@ import com.google.inject.Injector;
public class SimplexProtocolIntegrationTest extends BriarTestCase { public class SimplexProtocolIntegrationTest extends BriarTestCase {
private static final long CLOCK_DIFFERENCE = 60 * 1000L;
private static final long LATENCY = 60 * 1000L;
private final File testDir = TestUtils.getTestDirectory(); private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice"); private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob"); private final File bobDir = new File(testDir, "bob");
private final TransportId transportId; private final TransportId transportId;
private final byte[] aliceToBobSecret, bobToAliceSecret; private final byte[] secret;
private final long epoch;
private Injector alice, bob; private Injector alice, bob;
...@@ -60,11 +66,10 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase { ...@@ -60,11 +66,10 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
super(); super();
transportId = new TransportId(TestUtils.getRandomId()); transportId = new TransportId(TestUtils.getRandomId());
// Create matching secrets for Alice and Bob // Create matching secrets for Alice and Bob
Random r = new Random(); secret = new byte[32];
aliceToBobSecret = new byte[32]; new Random().nextBytes(secret);
r.nextBytes(aliceToBobSecret); long rotationPeriod = 2 * CLOCK_DIFFERENCE + LATENCY;
bobToAliceSecret = new byte[32]; epoch = System.currentTimeMillis() - 2 * rotationPeriod;
r.nextBytes(bobToAliceSecret);
} }
@Before @Before
...@@ -98,14 +103,22 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase { ...@@ -98,14 +103,22 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
// Open Alice's database // Open Alice's database
DatabaseComponent db = alice.getInstance(DatabaseComponent.class); DatabaseComponent db = alice.getInstance(DatabaseComponent.class);
db.open(false); db.open(false);
// Add Bob as a contact and send him a message // Add Bob as a contact
ContactId contactId = db.addContact(); ContactId contactId = db.addContact();
TemporarySecret s = new TemporarySecret(contactId, transportId, epoch,
CLOCK_DIFFERENCE, LATENCY, true, 0L, secret);
db.addContactTransport(s);
db.addSecrets(Collections.singletonList(s));
// Start Alice's key manager
KeyManager km = alice.getInstance(KeyManager.class);
km.start();
// Send Bob a message
String subject = "Hello"; String subject = "Hello";
byte[] body = "Hi Bob!".getBytes("UTF-8"); byte[] body = "Hi Bob!".getBytes("UTF-8");
MessageFactory messageFactory = alice.getInstance(MessageFactory.class); MessageFactory messageFactory = alice.getInstance(MessageFactory.class);
Message message = messageFactory.createMessage(null, subject, body); Message message = messageFactory.createMessage(null, subject, body);
db.addLocalPrivateMessage(message, contactId); db.addLocalPrivateMessage(message, contactId);
// Create an outgoing batch connection // Create an outgoing simplex connection
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionRegistry connRegistry = ConnectionRegistry connRegistry =
alice.getInstance(ConnectionRegistry.class); alice.getInstance(ConnectionRegistry.class);
...@@ -115,17 +128,18 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase { ...@@ -115,17 +128,18 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
alice.getInstance(ProtocolWriterFactory.class); alice.getInstance(ProtocolWriterFactory.class);
TestSimplexTransportWriter transport = new TestSimplexTransportWriter( TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
out, Long.MAX_VALUE, false); out, Long.MAX_VALUE, false);
ConnectionContext ctx = new ConnectionContext(contactId, transportId, ConnectionContext ctx = km.getConnectionContext(contactId, transportId);
aliceToBobSecret, 0L, true); assertNotNull(ctx);
OutgoingSimplexConnection simplex = new OutgoingSimplexConnection(db, OutgoingSimplexConnection simplex = new OutgoingSimplexConnection(db,
connRegistry, connFactory, protoFactory, ctx, transport); connRegistry, connFactory, protoFactory, ctx, transport);
// Write whatever needs to be written // Write whatever needs to be written
simplex.write(); simplex.write();
assertTrue(transport.getDisposed()); assertTrue(transport.getDisposed());
assertFalse(transport.getException()); assertFalse(transport.getException());
// Close Alice's database // Clean up
km.stop();
db.close(); db.close();
// Return the contents of the batch connection // Return the contents of the simplex connection
return out.toByteArray(); return out.toByteArray();
} }
...@@ -138,6 +152,13 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase { ...@@ -138,6 +152,13 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
db.addListener(listener); db.addListener(listener);
// Add Alice as a contact // Add Alice as a contact
ContactId contactId = db.addContact(); ContactId contactId = db.addContact();
TemporarySecret s = new TemporarySecret(contactId, transportId, epoch,
CLOCK_DIFFERENCE, LATENCY, false, 0L, secret);
db.addContactTransport(s);
db.addSecrets(Collections.singletonList(s));
// Start Bob's key manager
KeyManager km = bob.getInstance(KeyManager.class);
km.start();
// Fake a transport update from Alice // Fake a transport update from Alice
TransportUpdate transportUpdate = new TransportUpdate() { TransportUpdate transportUpdate = new TransportUpdate() {
...@@ -159,7 +180,6 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase { ...@@ -159,7 +180,6 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
assertEquals(tag.length, read); assertEquals(tag.length, read);
ConnectionContext ctx = rec.acceptConnection(transportId, tag); ConnectionContext ctx = rec.acceptConnection(transportId, tag);
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId());
// Create an incoming simplex connection // Create an incoming simplex connection
ConnectionRegistry connRegistry = ConnectionRegistry connRegistry =
bob.getInstance(ConnectionRegistry.class); bob.getInstance(ConnectionRegistry.class);
...@@ -181,7 +201,8 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase { ...@@ -181,7 +201,8 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
assertTrue(transport.getRecognised()); assertTrue(transport.getRecognised());
// The private message from Alice should have been added // The private message from Alice should have been added
assertTrue(listener.messagesAdded); assertTrue(listener.messagesAdded);
// Close Bob's database // Clean up
km.stop();
db.close(); db.close();
} }
......
...@@ -136,7 +136,7 @@ public class TransportIntegrationTest extends BriarTestCase { ...@@ -136,7 +136,7 @@ public class TransportIntegrationTest extends BriarTestCase {
ConnectionContext ctx = new ConnectionContext(contactId, transportId, ConnectionContext ctx = new ConnectionContext(contactId, transportId,
secret, 0L, true); secret, 0L, true);
ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out, ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
MIN_CONNECTION_LENGTH, ctx, true); MIN_CONNECTION_LENGTH, ctx, false, true);
// Check that the connection writer thinks there's room for a packet // Check that the connection writer thinks there's room for a packet
long capacity = w.getRemainingCapacity(); long capacity = w.getRemainingCapacity();
assertTrue(capacity > MAX_PACKET_LENGTH); assertTrue(capacity > MAX_PACKET_LENGTH);
...@@ -157,7 +157,7 @@ public class TransportIntegrationTest extends BriarTestCase { ...@@ -157,7 +157,7 @@ public class TransportIntegrationTest extends BriarTestCase {
ConnectionContext ctx = new ConnectionContext(contactId, transportId, ConnectionContext ctx = new ConnectionContext(contactId, transportId,
secret, 0L, true); secret, 0L, true);
ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out, ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
MIN_CONNECTION_LENGTH, ctx, false); MIN_CONNECTION_LENGTH, ctx, false, false);
// Check that the connection writer thinks there's room for a packet // Check that the connection writer thinks there's room for a packet
long capacity = w.getRemainingCapacity(); long capacity = w.getRemainingCapacity();
assertTrue(capacity > MAX_PACKET_LENGTH); assertTrue(capacity > MAX_PACKET_LENGTH);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment