diff --git a/briar-android/res/values/roboguice.xml b/briar-android/res/values/roboguice.xml index 7f33cf6d5cbccb03cc89a9b36e70c2c06d6a34c5..25a6e1ffada620c8e03b0d52eee8fab069a3cb5a 100644 --- a/briar-android/res/values/roboguice.xml +++ b/briar-android/res/values/roboguice.xml @@ -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> diff --git a/briar-android/src/org/briarproject/android/TestingActivity.java b/briar-android/src/org/briarproject/android/TestingActivity.java index 9146f9759e29b5ca3e1161d4f01ccf37e75db0a1..fb9b7fb912532e0ed0487864010a1156375ed5a0 100644 --- a/briar-android/src/org/briarproject/android/TestingActivity.java +++ b/briar-android/src/org/briarproject/android/TestingActivity.java @@ -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(); diff --git a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java index 960bdd639341cf5b09f7fc9ee695fcf5c218ae93..ade6ab4c745d72044feb0f4592efd621d4c2b9ba 100644 --- a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java +++ b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java @@ -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; diff --git a/briar-api/src/org/briarproject/api/property/TransportPropertyManager.java b/briar-api/src/org/briarproject/api/property/TransportPropertyManager.java new file mode 100644 index 0000000000000000000000000000000000000000..ce7bc96e1814c9ee95ae3e1869efe0c5cec51c5a --- /dev/null +++ b/briar-api/src/org/briarproject/api/property/TransportPropertyManager.java @@ -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; +} diff --git a/briar-api/src/org/briarproject/api/sync/Ack.java b/briar-api/src/org/briarproject/api/sync/Ack.java index 70417fc1617c39dfba5076426af1193c7e8cb28e..21486a4ae23cf75d132d7f06f1d03400bd1089da 100644 --- a/briar-api/src/org/briarproject/api/sync/Ack.java +++ b/briar-api/src/org/briarproject/api/sync/Ack.java @@ -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; diff --git a/briar-api/src/org/briarproject/api/sync/Offer.java b/briar-api/src/org/briarproject/api/sync/Offer.java index 6611fda66b236c4312b8dc3e3c612e2062acdd41..dc107ed4ab00b3532f0e4edf60068b81ef8de7cb 100644 --- a/briar-api/src/org/briarproject/api/sync/Offer.java +++ b/briar-api/src/org/briarproject/api/sync/Offer.java @@ -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; diff --git a/briar-api/src/org/briarproject/api/sync/Request.java b/briar-api/src/org/briarproject/api/sync/Request.java index 3b562802dffbaae1756d8bbfdf3f5d27298f48a0..af6d2321f8b1f7dcafe8c77dfc54197adc32209d 100644 --- a/briar-api/src/org/briarproject/api/sync/Request.java +++ b/briar-api/src/org/briarproject/api/sync/Request.java @@ -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; diff --git a/briar-api/src/org/briarproject/api/transport/KeyManager.java b/briar-api/src/org/briarproject/api/transport/KeyManager.java index 4602584c17afd13a56c42535dee70b78d3ef92ba..e2f76f081b89d057eed77a873add5149e85afa41 100644 --- a/briar-api/src/org/briarproject/api/transport/KeyManager.java +++ b/briar-api/src/org/briarproject/api/transport/KeyManager.java @@ -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); } diff --git a/briar-core/src/org/briarproject/invitation/AliceConnector.java b/briar-core/src/org/briarproject/invitation/AliceConnector.java index 963aa10ff734321d61a33092f3b0e2ec5218955a..84de4fc5472296e847e66cedee8d2e868c90f4f3 100644 --- a/briar-core/src/org/briarproject/invitation/AliceConnector.java +++ b/briar-core/src/org/briarproject/invitation/AliceConnector.java @@ -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 diff --git a/briar-core/src/org/briarproject/invitation/BobConnector.java b/briar-core/src/org/briarproject/invitation/BobConnector.java index 826659fddf7cdfcefae541e66dafd924f18f99e7..f598e4a0034558ea79caaf5f8c7e3d2e4f67fdcb 100644 --- a/briar-core/src/org/briarproject/invitation/BobConnector.java +++ b/briar-core/src/org/briarproject/invitation/BobConnector.java @@ -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 diff --git a/briar-core/src/org/briarproject/invitation/Connector.java b/briar-core/src/org/briarproject/invitation/Connector.java index ed654fbd1e93f87ba28474ab9344eafd119f1835..1e22f0492605399947c79d12fa7e81a87b311a84 100644 --- a/briar-core/src/org/briarproject/invitation/Connector.java +++ b/briar-core/src/org/briarproject/invitation/Connector.java @@ -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, diff --git a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java index 564b86fa82668238a6350392b3ab4b2c6ff8038d..f4ed123527e3b3f479a0235f751d4780ed1ded83 100644 --- a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java +++ b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java @@ -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); } diff --git a/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java b/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java index 25cb8b8069f69afdbf519be83d1c541de4ebf88a..899b8c558dcdd3004902abfb435bd4cc8a81f53a 100644 --- a/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java +++ b/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java @@ -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); } } diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java index eca57c25dc514d3729866ebb10970aebbf374b46..712254c206f6039a01196c2af71bab0bc58153b0 100644 --- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java @@ -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 diff --git a/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java b/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java index f3a31c83bc7cd6d1af19a6493710d9836a68bae7..76bf5e8c48552f8ed803f081135df2862334b7d5 100644 --- a/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java +++ b/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java @@ -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) { diff --git a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java index e96254b04a4c127b24aa7840a6f54450004c4a3f..a780b887dc3a076baf76ad97bf2f797f4d2b292d 100644 --- a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java +++ b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java @@ -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); } diff --git a/briar-core/src/org/briarproject/property/PropertyModule.java b/briar-core/src/org/briarproject/property/PropertyModule.java new file mode 100644 index 0000000000000000000000000000000000000000..23c3499538aaee749c7050b21fb1ddf41a7fb5a2 --- /dev/null +++ b/briar-core/src/org/briarproject/property/PropertyModule.java @@ -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); + } +} diff --git a/briar-core/src/org/briarproject/property/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/property/TransportPropertyManagerImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..355ee55f18e8f689e5b67c7f5a95383cb8793354 --- /dev/null +++ b/briar-core/src/org/briarproject/property/TransportPropertyManagerImpl.java @@ -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); + } +} diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java index 7c7123637ab254f49620f7150ab753ae0d6a3fb5..c36e844d2efddcc5cb25fd42c7e3afced68321a5 100644 --- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java +++ b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java @@ -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); } diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManager.java b/briar-core/src/org/briarproject/transport/TransportKeyManager.java index 7b6b5011c078651a283c332e9f55b341016a9c76..7fd3c42bfcb1a77a27d7117a04c4a409d0e13917 100644 --- a/briar-core/src/org/briarproject/transport/TransportKeyManager.java +++ b/briar-core/src/org/briarproject/transport/TransportKeyManager.java @@ -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 { diff --git a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java index 1394a998b4a3f4f85d3993b3ca4d6e034d93ff2c..66a174dd61d63ab6a002fd309d0765c3382dab57 100644 --- a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java +++ b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java @@ -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()); diff --git a/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java b/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java index 7cb2ed9b351a2f0be7db32c5cddc6457cb7ecf0c..88ae60a383c9c83b4ccfce212c127b58d4269444 100644 --- a/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java +++ b/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java @@ -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