Merge branch '112-transport-properties-manager' into 'master'

Transport properties manager facade, key manager refactoring. #112

Refactoring for #112: decouple the invitation and plugin code from the database with a TransportPropertiesManager facade (which will become a BSP client), and move some key management logic from the invitation code to the KeyManager. Update the integration tests to use the new FooManager facades.

See merge request !49
This commit is contained in:
akwizgran
2016-01-12 11:35:18 +00:00
22 changed files with 347 additions and 166 deletions

View File

@@ -13,6 +13,7 @@
<item>org.briarproject.lifecycle.LifecycleModule</item>
<item>org.briarproject.messaging.MessagingModule</item>
<item>org.briarproject.plugins.AndroidPluginsModule</item>
<item>org.briarproject.property.PropertyModule</item>
<item>org.briarproject.sync.SyncModule</item>
<item>org.briarproject.system.AndroidSystemModule</item>
<item>org.briarproject.transport.TransportModule</item>

View File

@@ -30,11 +30,11 @@ import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.util.StringUtils;
import java.io.File;
@@ -84,7 +84,7 @@ public class TestingActivity extends BriarActivity implements OnClickListener {
@Inject private AndroidExecutor androidExecutor;
@Inject private PluginManager pluginManager;
@Inject private LifecycleManager lifecycleManager;
@Inject private DatabaseComponent db;
@Inject private TransportPropertyManager transportPropertyManager;
private ScrollView scroll = null;
private ListLoadingProgressBar progress = null;
private LinearLayout status = null;
@@ -364,7 +364,7 @@ public class TestingActivity extends BriarActivity implements OnClickListener {
Map<TransportId, TransportProperties> props = Collections.emptyMap();
try {
lifecycleManager.waitForDatabase();
props = db.getLocalProperties();
props = transportPropertyManager.getLocalProperties();
} catch (InterruptedException e) {
LOG.info("Interrupted while waiting for database");
Thread.currentThread().interrupt();

View File

@@ -1,6 +1,7 @@
package org.briarproject.api.messaging;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
@@ -10,6 +11,12 @@ import java.util.Collection;
public interface MessagingManager {
/**
* Informs the messaging manager that a new contact has been added.
* Creates a private conversation with the contact.
*/
void addContact(ContactId c, SecretKey master) throws DbException;
/** Stores a local private message. */
void addLocalMessage(Message m) throws DbException;

View File

@@ -0,0 +1,36 @@
package org.briarproject.api.property;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
import java.util.Map;
public interface TransportPropertyManager {
/** Returns the local transport properties for all transports. */
Map<TransportId, TransportProperties> getLocalProperties()
throws DbException;
/** Returns the local transport properties for the given transport. */
TransportProperties getLocalProperties(TransportId t) throws DbException;
/** Returns all remote transport properties for the given transport. */
Map<ContactId, TransportProperties> getRemoteProperties(TransportId t)
throws DbException;
/**
* Merges the given properties with the existing local properties for the
* given transport.
*/
void mergeLocalProperties(TransportId t, TransportProperties p)
throws DbException;
/**
* Sets the remote transport properties for the given contact, replacing
* any existing properties.
*/
void setRemoteProperties(ContactId c,
Map<TransportId, TransportProperties> p) throws DbException;
}

View File

@@ -2,7 +2,7 @@ package org.briarproject.api.sync;
import java.util.Collection;
/** A packet acknowledging receipt of one or more {@link Message}s. */
/** A packet acknowledging receipt of one or more {@link Message Messages}. */
public class Ack {
private final Collection<MessageId> acked;

View File

@@ -2,7 +2,7 @@ package org.briarproject.api.sync;
import java.util.Collection;
/** A packet offering the recipient one or more {@link Message}s. */
/** A packet offering the recipient one or more {@link Message Messages}. */
public class Offer {
private final Collection<MessageId> offered;

View File

@@ -2,7 +2,9 @@ package org.briarproject.api.sync;
import java.util.Collection;
/** A packet requesting one or more {@link Message}s from the recipient. */
/**
* A packet requesting one or more {@link Message Messages} from the recipient.
*/
public class Request {
private final Collection<org.briarproject.api.sync.MessageId> requested;

View File

@@ -2,7 +2,7 @@ package org.briarproject.api.transport;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.lifecycle.Service;
import java.util.Collection;
@@ -14,11 +14,13 @@ import java.util.Collection;
public interface KeyManager extends Service {
/**
* Informs the key manager that a new contact has been added.
* Informs the key manager that a new contact has been added. Derives and
* stores transport keys for communicating with the contact.
* {@link StreamContext StreamContexts} for the contact can be created
* after this method has returned.
*/
void contactAdded(ContactId c, Collection<TransportKeys> keys);
void addContact(ContactId c, Collection<TransportId> transports,
SecretKey master, long timestamp, boolean alice);
/**
* Returns a {@link StreamContext} for sending a stream to the given
@@ -29,8 +31,8 @@ public interface KeyManager extends Service {
/**
* Looks up the given tag and returns a {@link StreamContext} for reading
* from the corresponding stream if the tag was expected, or null if the
* tag was unexpected.
* from the corresponding stream, or null if an error occurs or the tag was
* unexpected.
*/
StreamContext recogniseTag(TransportId t, byte[] tag) throws DbException;
StreamContext getStreamContext(TransportId t, byte[] tag);
}

View File

@@ -2,6 +2,7 @@ package org.briarproject.invitation;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.crypto.SecretKey;
@@ -9,14 +10,15 @@ import org.briarproject.api.data.Reader;
import org.briarproject.api.data.ReaderFactory;
import org.briarproject.api.data.Writer;
import org.briarproject.api.data.WriterFactory;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -39,20 +41,24 @@ class AliceConnector extends Connector {
private static final Logger LOG =
Logger.getLogger(AliceConnector.class.getName());
AliceConnector(CryptoComponent crypto, DatabaseComponent db,
AliceConnector(CryptoComponent crypto,
ReaderFactory readerFactory, WriterFactory writerFactory,
StreamReaderFactory streamReaderFactory,
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
Clock clock, boolean reuseConnection, ConnectorGroup group,
DuplexPlugin plugin, LocalAuthor localAuthor,
ContactManager contactManager, MessagingManager messagingManager,
TransportPropertyManager transportPropertyManager, Clock clock,
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
LocalAuthor localAuthor,
Map<TransportId, TransportProperties> localProps,
PseudoRandom random) {
super(crypto, db, readerFactory, writerFactory, streamReaderFactory,
super(crypto, readerFactory, writerFactory, streamReaderFactory,
streamWriterFactory, authorFactory, groupFactory,
keyManager, connectionManager, clock, reuseConnection, group,
plugin, localAuthor, localProps, random);
keyManager, connectionManager, contactManager,
messagingManager, transportPropertyManager, clock,
reuseConnection, group, plugin, localAuthor, localProps,
random);
}
@Override

View File

@@ -2,6 +2,7 @@ package org.briarproject.invitation;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.crypto.SecretKey;
@@ -9,14 +10,15 @@ import org.briarproject.api.data.Reader;
import org.briarproject.api.data.ReaderFactory;
import org.briarproject.api.data.Writer;
import org.briarproject.api.data.WriterFactory;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -39,20 +41,24 @@ class BobConnector extends Connector {
private static final Logger LOG =
Logger.getLogger(BobConnector.class.getName());
BobConnector(CryptoComponent crypto, DatabaseComponent db,
BobConnector(CryptoComponent crypto,
ReaderFactory readerFactory, WriterFactory writerFactory,
StreamReaderFactory streamReaderFactory,
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
Clock clock, boolean reuseConnection, ConnectorGroup group,
DuplexPlugin plugin, LocalAuthor localAuthor,
ContactManager contactManager, MessagingManager messagingManager,
TransportPropertyManager transportPropertyManager, Clock clock,
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
LocalAuthor localAuthor,
Map<TransportId, TransportProperties> localProps,
PseudoRandom random) {
super(crypto, db, readerFactory, writerFactory, streamReaderFactory,
super(crypto, readerFactory, writerFactory, streamReaderFactory,
streamWriterFactory, authorFactory, groupFactory,
keyManager, connectionManager, clock, reuseConnection, group,
plugin, localAuthor, localProps, random);
keyManager, connectionManager, contactManager,
messagingManager, transportPropertyManager, clock,
reuseConnection, group, plugin, localAuthor, localProps,
random);
}
@Override

View File

@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.KeyParser;
@@ -15,28 +16,25 @@ import org.briarproject.api.data.Reader;
import org.briarproject.api.data.ReaderFactory;
import org.briarproject.api.data.Writer;
import org.briarproject.api.data.WriterFactory;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.sync.Group;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
import org.briarproject.api.transport.TransportKeys;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
@@ -50,7 +48,6 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENG
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.api.invitation.InvitationConstants.CONNECTION_TIMEOUT;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
// FIXME: This class has way too many dependencies
abstract class Connector extends Thread {
@@ -59,7 +56,6 @@ abstract class Connector extends Thread {
Logger.getLogger(Connector.class.getName());
protected final CryptoComponent crypto;
protected final DatabaseComponent db;
protected final ReaderFactory readerFactory;
protected final WriterFactory writerFactory;
protected final StreamReaderFactory streamReaderFactory;
@@ -68,6 +64,9 @@ abstract class Connector extends Thread {
protected final GroupFactory groupFactory;
protected final KeyManager keyManager;
protected final ConnectionManager connectionManager;
protected final ContactManager contactManager;
protected final MessagingManager messagingManager;
protected final TransportPropertyManager transportPropertyManager;
protected final Clock clock;
protected final boolean reuseConnection;
protected final ConnectorGroup group;
@@ -83,19 +82,20 @@ abstract class Connector extends Thread {
private volatile ContactId contactId = null;
Connector(CryptoComponent crypto, DatabaseComponent db,
Connector(CryptoComponent crypto,
ReaderFactory readerFactory, WriterFactory writerFactory,
StreamReaderFactory streamReaderFactory,
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
Clock clock, boolean reuseConnection, ConnectorGroup group,
DuplexPlugin plugin, LocalAuthor localAuthor,
ContactManager contactManager, MessagingManager messagingManager,
TransportPropertyManager transportPropertyManager, Clock clock,
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
LocalAuthor localAuthor,
Map<TransportId, TransportProperties> localProps,
PseudoRandom random) {
super("Connector");
this.crypto = crypto;
this.db = db;
this.readerFactory = readerFactory;
this.writerFactory = writerFactory;
this.streamReaderFactory = streamReaderFactory;
@@ -104,6 +104,9 @@ abstract class Connector extends Thread {
this.groupFactory = groupFactory;
this.keyManager = keyManager;
this.connectionManager = connectionManager;
this.contactManager = contactManager;
this.messagingManager = messagingManager;
this.transportPropertyManager = transportPropertyManager;
this.clock = clock;
this.reuseConnection = reuseConnection;
this.group = group;
@@ -274,31 +277,15 @@ abstract class Connector extends Thread {
Map<TransportId, TransportProperties> remoteProps, SecretKey master,
long timestamp, boolean alice) throws DbException {
// Add the contact to the database
contactId = db.addContact(remoteAuthor, localAuthor.getId());
// Create and store the inbox group
byte[] salt = crypto.deriveGroupSalt(master);
Group inbox = groupFactory.createGroup("Inbox", salt);
db.addGroup(inbox);
db.setInboxGroup(contactId, inbox);
contactId = contactManager.addContact(remoteAuthor,
localAuthor.getId());
// Create a private messaging conversation
messagingManager.addContact(contactId, master);
// Store the remote transport properties
db.setRemoteProperties(contactId, remoteProps);
transportPropertyManager.setRemoteProperties(contactId, remoteProps);
// Derive transport keys for each transport shared with the contact
Map<TransportId, Integer> latencies = db.getTransportLatencies();
List<TransportKeys> keys = new ArrayList<TransportKeys>();
for (TransportId t : localProps.keySet()) {
if (remoteProps.containsKey(t) && latencies.containsKey(t)) {
// Work out what rotation period the timestamp belongs to
long latency = latencies.get(t);
long rotationPeriodLength = latency + MAX_CLOCK_DIFFERENCE;
long rotationPeriod = timestamp / rotationPeriodLength;
// Derive the transport keys
TransportKeys k = crypto.deriveTransportKeys(t, master,
rotationPeriod, alice);
db.addTransportKeys(contactId, k);
keys.add(k);
}
}
keyManager.contactAdded(contactId, keys);
keyManager.addContact(contactId, remoteProps.keySet(), master,
timestamp, alice);
}
protected void tryToClose(DuplexTransportConnection conn,

View File

@@ -2,22 +2,25 @@ package org.briarproject.invitation;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.data.ReaderFactory;
import org.briarproject.api.data.WriterFactory;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.invitation.InvitationListener;
import org.briarproject.api.invitation.InvitationState;
import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -45,7 +48,6 @@ class ConnectorGroup extends Thread implements InvitationTask {
Logger.getLogger(ConnectorGroup.class.getName());
private final CryptoComponent crypto;
private final DatabaseComponent db;
private final ReaderFactory readerFactory;
private final WriterFactory writerFactory;
private final StreamReaderFactory streamReaderFactory;
@@ -54,6 +56,10 @@ class ConnectorGroup extends Thread implements InvitationTask {
private final GroupFactory groupFactory;
private final KeyManager keyManager;
private final ConnectionManager connectionManager;
private final IdentityManager identityManager;
private final ContactManager contactManager;
private final MessagingManager messagingManager;
private final TransportPropertyManager transportPropertyManager;
private final Clock clock;
private final PluginManager pluginManager;
private final AuthorId localAuthorId;
@@ -71,18 +77,20 @@ class ConnectorGroup extends Thread implements InvitationTask {
private boolean localMatched = false, remoteMatched = false;
private String remoteName = null;
ConnectorGroup(CryptoComponent crypto, DatabaseComponent db,
ConnectorGroup(CryptoComponent crypto,
ReaderFactory readerFactory, WriterFactory writerFactory,
StreamReaderFactory streamReaderFactory,
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
Clock clock, PluginManager pluginManager, AuthorId localAuthorId,
IdentityManager identityManager, ContactManager contactManager,
MessagingManager messagingManager,
TransportPropertyManager transportPropertyManager, Clock clock,
PluginManager pluginManager, AuthorId localAuthorId,
int localInvitationCode, int remoteInvitationCode,
boolean reuseConnection) {
super("ConnectorGroup");
this.crypto = crypto;
this.db = db;
this.readerFactory = readerFactory;
this.writerFactory = writerFactory;
this.streamReaderFactory = streamReaderFactory;
@@ -91,6 +99,10 @@ class ConnectorGroup extends Thread implements InvitationTask {
this.groupFactory = groupFactory;
this.keyManager = keyManager;
this.connectionManager = connectionManager;
this.identityManager = identityManager;
this.contactManager = contactManager;
this.messagingManager = messagingManager;
this.transportPropertyManager = transportPropertyManager;
this.clock = clock;
this.pluginManager = pluginManager;
this.localAuthorId = localAuthorId;
@@ -130,8 +142,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
Map<TransportId, TransportProperties> localProps;
// Load the local pseudonym and transport properties
try {
localAuthor = db.getLocalAuthor(localAuthorId);
localProps = db.getLocalProperties();
localAuthor = identityManager.getLocalAuthor(localAuthorId);
localProps = transportPropertyManager.getLocalProperties();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
lock.lock();
@@ -185,9 +197,10 @@ class ConnectorGroup extends Thread implements InvitationTask {
Map<TransportId, TransportProperties> localProps) {
PseudoRandom random = crypto.getPseudoRandom(localInvitationCode,
remoteInvitationCode);
return new AliceConnector(crypto, db, readerFactory, writerFactory,
return new AliceConnector(crypto, readerFactory, writerFactory,
streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, clock,
groupFactory, keyManager, connectionManager, contactManager,
messagingManager, transportPropertyManager, clock,
reuseConnection, this, plugin, localAuthor, localProps, random);
}
@@ -196,9 +209,10 @@ class ConnectorGroup extends Thread implements InvitationTask {
Map<TransportId, TransportProperties> localProps) {
PseudoRandom random = crypto.getPseudoRandom(remoteInvitationCode,
localInvitationCode);
return new BobConnector(crypto, db, readerFactory, writerFactory,
return new BobConnector(crypto, readerFactory, writerFactory,
streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, clock,
groupFactory, keyManager, connectionManager, contactManager,
messagingManager, transportPropertyManager, clock,
reuseConnection, this, plugin, localAuthor, localProps, random);
}

View File

@@ -1,15 +1,18 @@
package org.briarproject.invitation;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.ReaderFactory;
import org.briarproject.api.data.WriterFactory;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.invitation.InvitationTaskFactory;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -21,7 +24,6 @@ import javax.inject.Inject;
class InvitationTaskFactoryImpl implements InvitationTaskFactory {
private final CryptoComponent crypto;
private final DatabaseComponent db;
private final ReaderFactory readerFactory;
private final WriterFactory writerFactory;
private final StreamReaderFactory streamReaderFactory;
@@ -30,19 +32,25 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
private final GroupFactory groupFactory;
private final KeyManager keyManager;
private final ConnectionManager connectionManager;
private final IdentityManager identityManager;
private final ContactManager contactManager;
private final MessagingManager messagingManager;
private final TransportPropertyManager transportPropertyManager;
private final Clock clock;
private final PluginManager pluginManager;
@Inject
InvitationTaskFactoryImpl(CryptoComponent crypto, DatabaseComponent db,
InvitationTaskFactoryImpl(CryptoComponent crypto,
ReaderFactory readerFactory, WriterFactory writerFactory,
StreamReaderFactory streamReaderFactory,
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
IdentityManager identityManager, ContactManager contactManager,
MessagingManager messagingManager,
TransportPropertyManager transportPropertyManager,
Clock clock, PluginManager pluginManager) {
this.crypto = crypto;
this.db = db;
this.readerFactory = readerFactory;
this.writerFactory = writerFactory;
this.streamReaderFactory = streamReaderFactory;
@@ -51,16 +59,21 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
this.groupFactory = groupFactory;
this.keyManager = keyManager;
this.connectionManager = connectionManager;
this.identityManager = identityManager;
this.contactManager = contactManager;
this.messagingManager = messagingManager;
this.transportPropertyManager = transportPropertyManager;
this.clock = clock;
this.pluginManager = pluginManager;
}
public InvitationTask createTask(AuthorId localAuthorId, int localCode,
int remoteCode, boolean reuseConnection) {
return new ConnectorGroup(crypto, db, readerFactory, writerFactory,
return new ConnectorGroup(crypto, readerFactory, writerFactory,
streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, clock,
pluginManager, localAuthorId, localCode, remoteCode,
groupFactory, keyManager, connectionManager, identityManager,
contactManager, messagingManager, transportPropertyManager,
clock, pluginManager, localAuthorId, localCode, remoteCode,
reuseConnection);
}
}

View File

@@ -3,11 +3,15 @@ package org.briarproject.messaging;
import com.google.inject.Inject;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateConversation;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageHeader;
@@ -22,10 +26,23 @@ import java.util.List;
class MessagingManagerImpl implements MessagingManager {
private final DatabaseComponent db;
private final CryptoComponent crypto;
private final GroupFactory groupFactory;
@Inject
MessagingManagerImpl(DatabaseComponent db) {
MessagingManagerImpl(DatabaseComponent db, CryptoComponent crypto,
GroupFactory groupFactory) {
this.db = db;
this.crypto = crypto;
this.groupFactory = groupFactory;
}
@Override
public void addContact(ContactId c, SecretKey master) throws DbException {
byte[] salt = crypto.deriveGroupSalt(master);
Group inbox = groupFactory.createGroup("Inbox", salt);
db.addGroup(inbox);
db.setInboxGroup(c, inbox);
}
@Override

View File

@@ -2,7 +2,6 @@ package org.briarproject.plugins;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.ConnectionRegistry;
@@ -130,15 +129,11 @@ class ConnectionManagerImpl implements ConnectionManager {
StreamContext ctx;
try {
byte[] tag = readTag(transportId, reader);
ctx = keyManager.recogniseTag(transportId, tag);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false);
return;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false);
return;
}
if (ctx == null) {
LOG.info("Unrecognised tag");
@@ -234,15 +229,11 @@ class ConnectionManagerImpl implements ConnectionManager {
StreamContext ctx;
try {
byte[] tag = readTag(transportId, reader);
ctx = keyManager.recogniseTag(transportId, tag);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false);
return;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false);
return;
}
if (ctx == null) {
LOG.info("Unrecognised tag");
@@ -363,15 +354,11 @@ class ConnectionManagerImpl implements ConnectionManager {
StreamContext ctx;
try {
byte[] tag = readTag(transportId, reader);
ctx = keyManager.recogniseTag(transportId, tag);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, true);
return;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, true);
return;
}
// Unrecognised tags are suspicious in this case
if (ctx == null) {

View File

@@ -25,6 +25,7 @@ import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.system.Clock;
import org.briarproject.api.ui.UiCallback;
@@ -58,6 +59,7 @@ class PluginManagerImpl implements PluginManager {
private final DatabaseComponent db;
private final Poller poller;
private final ConnectionManager connectionManager;
private final TransportPropertyManager transportPropertyManager;
private final UiCallback uiCallback;
private final Map<TransportId, Plugin> plugins;
private final List<SimplexPlugin> simplexPlugins;
@@ -68,7 +70,9 @@ class PluginManagerImpl implements PluginManager {
SimplexPluginConfig simplexPluginConfig,
DuplexPluginConfig duplexPluginConfig, Clock clock,
DatabaseComponent db, Poller poller,
ConnectionManager connectionManager, UiCallback uiCallback) {
ConnectionManager connectionManager,
TransportPropertyManager transportPropertyManager,
UiCallback uiCallback) {
this.ioExecutor = ioExecutor;
this.eventBus = eventBus;
this.simplexPluginConfig = simplexPluginConfig;
@@ -77,6 +81,7 @@ class PluginManagerImpl implements PluginManager {
this.db = db;
this.poller = poller;
this.connectionManager = connectionManager;
this.transportPropertyManager = transportPropertyManager;
this.uiCallback = uiCallback;
plugins = new ConcurrentHashMap<TransportId, Plugin>();
simplexPlugins = new CopyOnWriteArrayList<SimplexPlugin>();
@@ -320,7 +325,8 @@ class PluginManagerImpl implements PluginManager {
public TransportProperties getLocalProperties() {
try {
TransportProperties p = db.getLocalProperties(id);
TransportProperties p =
transportPropertyManager.getLocalProperties(id);
return p == null ? new TransportProperties() : p;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -330,7 +336,7 @@ class PluginManagerImpl implements PluginManager {
public Map<ContactId, TransportProperties> getRemoteProperties() {
try {
return db.getRemoteProperties(id);
return transportPropertyManager.getRemoteProperties(id);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return Collections.emptyMap();
@@ -347,7 +353,7 @@ class PluginManagerImpl implements PluginManager {
public void mergeLocalProperties(TransportProperties p) {
try {
db.mergeLocalProperties(id, p);
transportPropertyManager.mergeLocalProperties(id, p);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}

View File

@@ -0,0 +1,14 @@
package org.briarproject.property;
import com.google.inject.AbstractModule;
import org.briarproject.api.property.TransportPropertyManager;
public class PropertyModule extends AbstractModule {
@Override
protected void configure() {
bind(TransportPropertyManager.class).to(
TransportPropertyManagerImpl.class);
}
}

View File

@@ -0,0 +1,53 @@
package org.briarproject.property;
import com.google.inject.Inject;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.property.TransportPropertyManager;
import java.util.Map;
// Temporary facade during sync protocol refactoring
class TransportPropertyManagerImpl implements TransportPropertyManager {
private final DatabaseComponent db;
@Inject
TransportPropertyManagerImpl(DatabaseComponent db) {
this.db = db;
}
@Override
public Map<TransportId, TransportProperties> getLocalProperties()
throws DbException {
return db.getLocalProperties();
}
@Override
public TransportProperties getLocalProperties(TransportId t)
throws DbException {
return db.getLocalProperties(t);
}
@Override
public Map<ContactId, TransportProperties> getRemoteProperties(
TransportId t) throws DbException {
return db.getRemoteProperties(t);
}
@Override
public void mergeLocalProperties(TransportId t, TransportProperties p)
throws DbException {
db.mergeLocalProperties(t, p);
}
@Override
public void setRemoteProperties(ContactId c,
Map<TransportId, TransportProperties> p) throws DbException {
db.setRemoteProperties(c, p);
}
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.transport;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
@@ -16,7 +17,6 @@ import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.TransportKeys;
import java.util.Collection;
import java.util.Map;
@@ -73,10 +73,11 @@ class KeyManagerImpl implements KeyManager, EventListener {
return true;
}
public void contactAdded(ContactId c, Collection<TransportKeys> keys) {
for (TransportKeys k : keys) {
TransportKeyManager m = managers.get(k.getTransportId());
if (m != null) m.addContact(c, k);
public void addContact(ContactId c, Collection<TransportId> transports,
SecretKey master, long timestamp, boolean alice) {
for (TransportId t : transports) {
TransportKeyManager m = managers.get(t);
if (m != null) m.addContact(c, master, timestamp, alice);
}
}
@@ -85,8 +86,7 @@ class KeyManagerImpl implements KeyManager, EventListener {
return m == null ? null : m.getStreamContext(c);
}
public StreamContext recogniseTag(TransportId t, byte[] tag)
throws DbException {
public StreamContext getStreamContext(TransportId t, byte[] tag) {
TransportKeyManager m = managers.get(t);
return m == null ? null : m.recogniseTag(tag);
}

View File

@@ -4,6 +4,7 @@ import org.briarproject.api.Bytes;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.system.Clock;
@@ -98,9 +99,9 @@ class TransportKeyManager extends TimerTask {
} finally {
lock.unlock();
}
// Schedule a periodic task to rotate the keys
// Schedule the next key rotation
long delay = rotationPeriodLength - now % rotationPeriodLength;
timer.scheduleAtFixedRate(this, delay, rotationPeriodLength);
timer.schedule(this, delay);
}
// Locking: lock
@@ -136,16 +137,40 @@ class TransportKeyManager extends TimerTask {
});
}
void addContact(ContactId c, TransportKeys k) {
void addContact(ContactId c, SecretKey master, long timestamp,
boolean alice) {
// Work out what rotation period the timestamp belongs to
long rotationPeriod = timestamp / rotationPeriodLength;
// Derive the transport keys
TransportKeys k = crypto.deriveTransportKeys(transportId, master,
rotationPeriod, alice);
// Rotate the keys to the current rotation period if necessary
rotationPeriod = clock.currentTimeMillis() / rotationPeriodLength;
k = crypto.rotateTransportKeys(k, rotationPeriod);
lock.lock();
try {
// Initialise mutable state for the contact
addKeys(c, new MutableTransportKeys(k));
// Write the keys back to the DB
saveTransportKeys(c, k);
} finally {
lock.unlock();
}
}
private void saveTransportKeys(final ContactId c, final TransportKeys k) {
dbExecutor.execute(new Runnable() {
public void run() {
try {
db.addTransportKeys(c, k);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
void removeContact(ContactId c) {
lock.lock();
try {
@@ -308,6 +333,10 @@ class TransportKeyManager extends TimerTask {
} finally {
lock.unlock();
}
// Schedule the next key rotation
long now = clock.currentTimeMillis();
long delay = rotationPeriodLength - now % rotationPeriodLength;
timer.schedule(this, delay);
}
private static class TagContext {

View File

@@ -4,7 +4,6 @@ import org.briarproject.BriarTestCase;
import org.briarproject.api.TransportId;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
@@ -14,6 +13,7 @@ import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.system.Clock;
import org.briarproject.api.ui.UiCallback;
import org.briarproject.system.SystemClock;
@@ -41,8 +41,10 @@ public class PluginManagerImplTest extends BriarTestCase {
context.mock(DuplexPluginConfig.class);
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final Poller poller = context.mock(Poller.class);
final ConnectionManager dispatcher =
final ConnectionManager connectionManager =
context.mock(ConnectionManager.class);
final TransportPropertyManager transportPropertyManager =
context.mock(TransportPropertyManager.class);
final UiCallback uiCallback = context.mock(UiCallback.class);
// Two simplex plugin factories: both create plugins, one fails to start
final SimplexPluginFactory simplexFactory =
@@ -126,7 +128,7 @@ public class PluginManagerImplTest extends BriarTestCase {
}});
PluginManagerImpl p = new PluginManagerImpl(ioExecutor, eventBus,
simplexPluginConfig, duplexPluginConfig, clock, db, poller,
dispatcher, uiCallback);
connectionManager, transportPropertyManager, uiCallback);
// Two plugins should be started and stopped
assertTrue(p.start());

View File

@@ -10,7 +10,7 @@ import org.briarproject.TestSystemModule;
import org.briarproject.TestUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.Event;
@@ -19,11 +19,13 @@ import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateConversation;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.MessageVerifier;
import org.briarproject.api.sync.MessagingSession;
import org.briarproject.api.sync.PacketReader;
@@ -34,11 +36,13 @@ import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
import org.briarproject.api.transport.TransportKeys;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.plugins.ImmediateExecutor;
import org.briarproject.transport.TransportModule;
import org.junit.After;
@@ -53,8 +57,6 @@ import java.io.OutputStream;
import java.util.Collections;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -64,8 +66,6 @@ import static org.junit.Assert.assertTrue;
public class SimplexMessagingIntegrationTest extends BriarTestCase {
private static final int MAX_LATENCY = 2 * 60 * 1000; // 2 minutes
private static final long ROTATION_PERIOD_LENGTH =
MAX_LATENCY + MAX_CLOCK_DIFFERENCE;
private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice");
@@ -86,9 +86,9 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private Injector createInjector(File dir) {
return Guice.createInjector(new TestDatabaseModule(dir),
new TestLifecycleModule(), new TestSystemModule(),
new CryptoModule(), new DatabaseModule(), new EventModule(),
new SyncModule(), new DataModule(),
new TransportModule());
new ContactModule(), new CryptoModule(), new DatabaseModule(),
new DataModule(), new EventModule(), new IdentityModule(),
new SyncModule(), new MessagingModule(), new TransportModule());
}
@Test
@@ -100,40 +100,41 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
// Open Alice's database
DatabaseComponent db = alice.getInstance(DatabaseComponent.class);
assertFalse(db.open());
// Add the transport
db.addTransport(transportId, MAX_LATENCY);
// Start Alice's key manager
KeyManager keyManager = alice.getInstance(KeyManager.class);
keyManager.start();
// Add a local pseudonym for Alice
// Add an identity for Alice
AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
db.addLocalAuthor(aliceAuthor);
IdentityManager identityManager =
alice.getInstance(IdentityManager.class);
identityManager.addLocalAuthor(aliceAuthor);
// Add Bob as a contact
AuthorId bobId = new AuthorId(TestUtils.getRandomId());
Author bobAuthor = new Author(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = db.addContact(bobAuthor, aliceId);
// Add the inbox group
GroupFactory gf = alice.getInstance(GroupFactory.class);
Group group = gf.createGroup("Group", new byte[GROUP_SALT_LENGTH]);
db.addGroup(group);
db.setInboxGroup(contactId, group);
// Add the transport
db.addTransport(transportId, MAX_LATENCY);
ContactManager contactManager = alice.getInstance(ContactManager.class);
ContactId contactId = contactManager.addContact(bobAuthor, aliceId);
// Create the private conversation
MessagingManager messagingManager =
alice.getInstance(MessagingManager.class);
messagingManager.addContact(contactId, master);
// Derive and store the transport keys
long rotationPeriod = timestamp / ROTATION_PERIOD_LENGTH;
CryptoComponent crypto = alice.getInstance(CryptoComponent.class);
TransportKeys keys = crypto.deriveTransportKeys(transportId, master,
rotationPeriod, true);
db.addTransportKeys(contactId, keys);
keyManager.contactAdded(contactId, Collections.singletonList(keys));
keyManager.addContact(contactId, Collections.singletonList(transportId),
master, timestamp, true);
// Send Bob a message
String contentType = "text/plain";
byte[] body = "Hi Bob!".getBytes("UTF-8");
MessageFactory messageFactory = alice.getInstance(MessageFactory.class);
Message message = messageFactory.createAnonymousMessage(null, group,
contentType, timestamp, body);
db.addLocalMessage(message);
PrivateMessageFactory messageFactory =
alice.getInstance(PrivateMessageFactory.class);
GroupId groupId = messagingManager.getConversationId(contactId);
PrivateConversation conversation =
messagingManager.getConversation(groupId);
Message message = messageFactory.createPrivateMessage(null,
conversation, "text/plain", timestamp, body);
messagingManager.addLocalMessage(message);
// Get a stream context
StreamContext ctx = keyManager.getStreamContext(contactId, transportId);
assertNotNull(ctx);
@@ -143,13 +144,13 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
alice.getInstance(StreamWriterFactory.class);
OutputStream streamWriter =
streamWriterFactory.createStreamWriter(out, ctx);
// Create an outgoing messaging session
// Create an outgoing sync session
EventBus eventBus = alice.getInstance(EventBus.class);
PacketWriterFactory packetWriterFactory =
alice.getInstance(PacketWriterFactory.class);
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(
streamWriter);
MessagingSession session = new org.briarproject.sync.SimplexOutgoingSession(db,
MessagingSession session = new SimplexOutgoingSession(db,
new ImmediateExecutor(), eventBus, contactId, transportId,
MAX_LATENCY, packetWriter);
// Write whatever needs to be written
@@ -166,33 +167,31 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
// Open Bob's database
DatabaseComponent db = bob.getInstance(DatabaseComponent.class);
assertFalse(db.open());
// Add the transport
db.addTransport(transportId, MAX_LATENCY);
// Start Bob's key manager
KeyManager keyManager = bob.getInstance(KeyManager.class);
keyManager.start();
// Add a local pseudonym for Bob
// Add an identity for Bob
AuthorId bobId = new AuthorId(TestUtils.getRandomId());
LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
db.addLocalAuthor(bobAuthor);
IdentityManager identityManager =
bob.getInstance(IdentityManager.class);
identityManager.addLocalAuthor(bobAuthor);
// Add Alice as a contact
AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
Author aliceAuthor = new Author(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = db.addContact(aliceAuthor, bobId);
// Add the inbox group
GroupFactory gf = bob.getInstance(GroupFactory.class);
Group group = gf.createGroup("Group", new byte[GROUP_SALT_LENGTH]);
db.addGroup(group);
db.setInboxGroup(contactId, group);
// Add the transport
db.addTransport(transportId, MAX_LATENCY);
ContactManager contactManager = bob.getInstance(ContactManager.class);
ContactId contactId = contactManager.addContact(aliceAuthor, bobId);
// Create the private conversation
MessagingManager messagingManager =
bob.getInstance(MessagingManager.class);
messagingManager.addContact(contactId, master);
// Derive and store the transport keys
long rotationPeriod = timestamp / ROTATION_PERIOD_LENGTH;
CryptoComponent crypto = bob.getInstance(CryptoComponent.class);
TransportKeys keys = crypto.deriveTransportKeys(transportId, master,
rotationPeriod, false);
db.addTransportKeys(contactId, keys);
keyManager.contactAdded(contactId, Collections.singletonList(keys));
keyManager.addContact(contactId, Collections.singletonList(transportId),
master, timestamp, false);
// Set up an event listener
MessageListener listener = new MessageListener();
bob.getInstance(EventBus.class).addListener(listener);
@@ -201,14 +200,14 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
byte[] tag = new byte[TAG_LENGTH];
int read = in.read(tag);
assertEquals(tag.length, read);
StreamContext ctx = keyManager.recogniseTag(transportId, tag);
StreamContext ctx = keyManager.getStreamContext(transportId, tag);
assertNotNull(ctx);
// Create a stream reader
StreamReaderFactory streamReaderFactory =
bob.getInstance(StreamReaderFactory.class);
InputStream streamReader =
streamReaderFactory.createStreamReader(in, ctx);
// Create an incoming messaging session
// Create an incoming sync session
EventBus eventBus = bob.getInstance(EventBus.class);
MessageVerifier messageVerifier =
bob.getInstance(MessageVerifier.class);
@@ -216,7 +215,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
bob.getInstance(PacketReaderFactory.class);
PacketReader packetReader = packetReaderFactory.createPacketReader(
streamReader);
MessagingSession session = new org.briarproject.sync.IncomingSession(db,
MessagingSession session = new IncomingSession(db,
new ImmediateExecutor(), new ImmediateExecutor(), eventBus,
messageVerifier, contactId, transportId, packetReader);
// No messages should have been added yet