mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 05:09:53 +01:00
Merge branch 'add-contact-transaction' into 'master'
Add contact and transport keys in the same transaction This avoids a potential problem where the app crashes after adding the contact but before adding the transport keys, leaving the contact unusable. See merge request !112
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.api.contact;
|
package org.briarproject.api.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.identity.Author;
|
import org.briarproject.api.identity.Author;
|
||||||
@@ -19,8 +20,8 @@ public interface ContactManager {
|
|||||||
* Stores a contact associated with the given local and remote pseudonyms,
|
* Stores a contact associated with the given local and remote pseudonyms,
|
||||||
* and returns an ID for the contact.
|
* and returns an ID for the contact.
|
||||||
*/
|
*/
|
||||||
ContactId addContact(Author remote, AuthorId local, boolean active)
|
ContactId addContact(Author remote, AuthorId local, SecretKey master,
|
||||||
throws DbException;
|
long timestamp, boolean alice, boolean active) throws DbException;
|
||||||
|
|
||||||
/** Returns the contact with the given ID. */
|
/** Returns the contact with the given ID. */
|
||||||
Contact getContact(ContactId c) throws DbException;
|
Contact getContact(ContactId c) throws DbException;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.briarproject.api.transport;
|
|||||||
import org.briarproject.api.TransportId;
|
import org.briarproject.api.TransportId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.Transaction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for managing transport keys and recognising the pseudo-random
|
* Responsible for managing transport keys and recognising the pseudo-random
|
||||||
@@ -16,8 +18,8 @@ public interface KeyManager {
|
|||||||
* {@link StreamContext StreamContexts} for the contact can be created
|
* {@link StreamContext StreamContexts} for the contact can be created
|
||||||
* after this method has returned.
|
* after this method has returned.
|
||||||
*/
|
*/
|
||||||
void addContact(ContactId c, SecretKey master, long timestamp,
|
void addContact(Transaction txn, ContactId c, SecretKey master,
|
||||||
boolean alice);
|
long timestamp, boolean alice) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link StreamContext} for sending a stream to the given
|
* Returns a {@link StreamContext} for sending a stream to the given
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.google.inject.Inject;
|
|||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
@@ -12,6 +13,7 @@ import org.briarproject.api.identity.Author;
|
|||||||
import org.briarproject.api.identity.AuthorId;
|
import org.briarproject.api.identity.AuthorId;
|
||||||
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
|
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.api.transport.KeyManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -22,12 +24,14 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
|
private final KeyManager keyManager;
|
||||||
private final List<AddContactHook> addHooks;
|
private final List<AddContactHook> addHooks;
|
||||||
private final List<RemoveContactHook> removeHooks;
|
private final List<RemoveContactHook> removeHooks;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ContactManagerImpl(DatabaseComponent db) {
|
ContactManagerImpl(DatabaseComponent db, KeyManager keyManager) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
|
this.keyManager = keyManager;
|
||||||
addHooks = new CopyOnWriteArrayList<AddContactHook>();
|
addHooks = new CopyOnWriteArrayList<AddContactHook>();
|
||||||
removeHooks = new CopyOnWriteArrayList<RemoveContactHook>();
|
removeHooks = new CopyOnWriteArrayList<RemoveContactHook>();
|
||||||
}
|
}
|
||||||
@@ -43,12 +47,14 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContactId addContact(Author remote, AuthorId local, boolean active)
|
public ContactId addContact(Author remote, AuthorId local, SecretKey master,
|
||||||
|
long timestamp, boolean alice, boolean active)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
ContactId c;
|
ContactId c;
|
||||||
Transaction txn = db.startTransaction();
|
Transaction txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
c = db.addContact(txn, remote, local, active);
|
c = db.addContact(txn, remote, local, active);
|
||||||
|
keyManager.addContact(txn, c, master, timestamp, alice);
|
||||||
Contact contact = db.getContact(txn, c);
|
Contact contact = db.getContact(txn, c);
|
||||||
for (AddContactHook hook : addHooks)
|
for (AddContactHook hook : addHooks)
|
||||||
hook.addingContact(txn, contact);
|
hook.addingContact(txn, contact);
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ import org.briarproject.api.identity.LocalAuthor;
|
|||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.api.sync.GroupFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.KeyManager;
|
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
|
|
||||||
@@ -41,12 +39,11 @@ class AliceConnector extends Connector {
|
|||||||
BdfWriterFactory bdfWriterFactory,
|
BdfWriterFactory bdfWriterFactory,
|
||||||
StreamReaderFactory streamReaderFactory,
|
StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory,
|
StreamWriterFactory streamWriterFactory,
|
||||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
AuthorFactory authorFactory, ConnectionManager connectionManager,
|
||||||
KeyManager keyManager, ConnectionManager connectionManager,
|
|
||||||
ContactManager contactManager, Clock clock, ConnectorGroup group,
|
ContactManager contactManager, Clock clock, ConnectorGroup group,
|
||||||
DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
|
DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
|
||||||
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
|
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
|
||||||
streamWriterFactory, authorFactory, groupFactory, keyManager,
|
streamWriterFactory, authorFactory,
|
||||||
connectionManager, contactManager, clock, group, plugin,
|
connectionManager, contactManager, clock, group, plugin,
|
||||||
localAuthor, random);
|
localAuthor, random);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ import org.briarproject.api.identity.LocalAuthor;
|
|||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.api.sync.GroupFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.KeyManager;
|
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
|
|
||||||
@@ -41,12 +39,11 @@ class BobConnector extends Connector {
|
|||||||
BdfWriterFactory bdfWriterFactory,
|
BdfWriterFactory bdfWriterFactory,
|
||||||
StreamReaderFactory streamReaderFactory,
|
StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory,
|
StreamWriterFactory streamWriterFactory,
|
||||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
AuthorFactory authorFactory, ConnectionManager connectionManager,
|
||||||
KeyManager keyManager, ConnectionManager connectionManager,
|
|
||||||
ContactManager contactManager, Clock clock, ConnectorGroup group,
|
ContactManager contactManager, Clock clock, ConnectorGroup group,
|
||||||
DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
|
DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
|
||||||
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
|
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
|
||||||
streamWriterFactory, authorFactory, groupFactory, keyManager,
|
streamWriterFactory, authorFactory,
|
||||||
connectionManager, contactManager, clock, group, plugin,
|
connectionManager, contactManager, clock, group, plugin,
|
||||||
localAuthor, random);
|
localAuthor, random);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import org.briarproject.api.identity.LocalAuthor;
|
|||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.api.sync.GroupFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.KeyManager;
|
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
|
|
||||||
@@ -52,8 +50,6 @@ abstract class Connector extends Thread {
|
|||||||
protected final StreamReaderFactory streamReaderFactory;
|
protected final StreamReaderFactory streamReaderFactory;
|
||||||
protected final StreamWriterFactory streamWriterFactory;
|
protected final StreamWriterFactory streamWriterFactory;
|
||||||
protected final AuthorFactory authorFactory;
|
protected final AuthorFactory authorFactory;
|
||||||
protected final GroupFactory groupFactory;
|
|
||||||
protected final KeyManager keyManager;
|
|
||||||
protected final ConnectionManager connectionManager;
|
protected final ConnectionManager connectionManager;
|
||||||
protected final ContactManager contactManager;
|
protected final ContactManager contactManager;
|
||||||
protected final Clock clock;
|
protected final Clock clock;
|
||||||
@@ -74,8 +70,7 @@ abstract class Connector extends Thread {
|
|||||||
BdfWriterFactory bdfWriterFactory,
|
BdfWriterFactory bdfWriterFactory,
|
||||||
StreamReaderFactory streamReaderFactory,
|
StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory,
|
StreamWriterFactory streamWriterFactory,
|
||||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
AuthorFactory authorFactory, ConnectionManager connectionManager,
|
||||||
KeyManager keyManager, ConnectionManager connectionManager,
|
|
||||||
ContactManager contactManager, Clock clock, ConnectorGroup group,
|
ContactManager contactManager, Clock clock, ConnectorGroup group,
|
||||||
DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
|
DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
|
||||||
super("Connector");
|
super("Connector");
|
||||||
@@ -85,8 +80,6 @@ abstract class Connector extends Thread {
|
|||||||
this.streamReaderFactory = streamReaderFactory;
|
this.streamReaderFactory = streamReaderFactory;
|
||||||
this.streamWriterFactory = streamWriterFactory;
|
this.streamWriterFactory = streamWriterFactory;
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
this.groupFactory = groupFactory;
|
|
||||||
this.keyManager = keyManager;
|
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
@@ -219,9 +212,7 @@ abstract class Connector extends Thread {
|
|||||||
long timestamp, boolean alice) throws DbException {
|
long timestamp, boolean alice) throws DbException {
|
||||||
// Add the contact to the database
|
// Add the contact to the database
|
||||||
contactId = contactManager.addContact(remoteAuthor,
|
contactId = contactManager.addContact(remoteAuthor,
|
||||||
localAuthor.getId(), true);
|
localAuthor.getId(), master, timestamp, alice, true);
|
||||||
// Derive transport keys
|
|
||||||
keyManager.addContact(contactId, master, timestamp, alice);
|
|
||||||
return contactId;
|
return contactId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ import org.briarproject.api.invitation.InvitationTask;
|
|||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
import org.briarproject.api.plugins.PluginManager;
|
import org.briarproject.api.plugins.PluginManager;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||||
import org.briarproject.api.sync.GroupFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.KeyManager;
|
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
|
|
||||||
@@ -48,8 +46,6 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
private final StreamReaderFactory streamReaderFactory;
|
private final StreamReaderFactory streamReaderFactory;
|
||||||
private final StreamWriterFactory streamWriterFactory;
|
private final StreamWriterFactory streamWriterFactory;
|
||||||
private final AuthorFactory authorFactory;
|
private final AuthorFactory authorFactory;
|
||||||
private final GroupFactory groupFactory;
|
|
||||||
private final KeyManager keyManager;
|
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
@@ -74,8 +70,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
BdfWriterFactory bdfWriterFactory,
|
BdfWriterFactory bdfWriterFactory,
|
||||||
StreamReaderFactory streamReaderFactory,
|
StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory,
|
StreamWriterFactory streamWriterFactory,
|
||||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
AuthorFactory authorFactory, ConnectionManager connectionManager,
|
||||||
KeyManager keyManager, ConnectionManager connectionManager,
|
|
||||||
IdentityManager identityManager, ContactManager contactManager,
|
IdentityManager identityManager, ContactManager contactManager,
|
||||||
Clock clock, PluginManager pluginManager, AuthorId localAuthorId,
|
Clock clock, PluginManager pluginManager, AuthorId localAuthorId,
|
||||||
int localInvitationCode, int remoteInvitationCode) {
|
int localInvitationCode, int remoteInvitationCode) {
|
||||||
@@ -86,8 +81,6 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
this.streamReaderFactory = streamReaderFactory;
|
this.streamReaderFactory = streamReaderFactory;
|
||||||
this.streamWriterFactory = streamWriterFactory;
|
this.streamWriterFactory = streamWriterFactory;
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
this.groupFactory = groupFactory;
|
|
||||||
this.keyManager = keyManager;
|
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.identityManager = identityManager;
|
this.identityManager = identityManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -181,8 +174,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
remoteInvitationCode);
|
remoteInvitationCode);
|
||||||
return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory,
|
return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory,
|
||||||
streamReaderFactory, streamWriterFactory, authorFactory,
|
streamReaderFactory, streamWriterFactory, authorFactory,
|
||||||
groupFactory, keyManager, connectionManager, contactManager,
|
connectionManager, contactManager, clock, this, plugin,
|
||||||
clock, this, plugin, localAuthor, random);
|
localAuthor, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Connector createBobConnector(DuplexPlugin plugin,
|
private Connector createBobConnector(DuplexPlugin plugin,
|
||||||
@@ -191,8 +184,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
localInvitationCode);
|
localInvitationCode);
|
||||||
return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory,
|
return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory,
|
||||||
streamReaderFactory, streamWriterFactory, authorFactory,
|
streamReaderFactory, streamWriterFactory, authorFactory,
|
||||||
groupFactory, keyManager, connectionManager, contactManager,
|
connectionManager, contactManager, clock, this, plugin,
|
||||||
clock, this, plugin, localAuthor, random);
|
localAuthor, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void localConfirmationSucceeded() {
|
public void localConfirmationSucceeded() {
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ import org.briarproject.api.invitation.InvitationTask;
|
|||||||
import org.briarproject.api.invitation.InvitationTaskFactory;
|
import org.briarproject.api.invitation.InvitationTaskFactory;
|
||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
import org.briarproject.api.plugins.PluginManager;
|
import org.briarproject.api.plugins.PluginManager;
|
||||||
import org.briarproject.api.sync.GroupFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.KeyManager;
|
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
|
|
||||||
@@ -27,8 +25,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
|||||||
private final StreamReaderFactory streamReaderFactory;
|
private final StreamReaderFactory streamReaderFactory;
|
||||||
private final StreamWriterFactory streamWriterFactory;
|
private final StreamWriterFactory streamWriterFactory;
|
||||||
private final AuthorFactory authorFactory;
|
private final AuthorFactory authorFactory;
|
||||||
private final GroupFactory groupFactory;
|
|
||||||
private final KeyManager keyManager;
|
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
@@ -40,8 +36,7 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
|||||||
BdfReaderFactory bdfReaderFactory, BdfWriterFactory bdfWriterFactory,
|
BdfReaderFactory bdfReaderFactory, BdfWriterFactory bdfWriterFactory,
|
||||||
StreamReaderFactory streamReaderFactory,
|
StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory,
|
StreamWriterFactory streamWriterFactory,
|
||||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
AuthorFactory authorFactory, ConnectionManager connectionManager,
|
||||||
KeyManager keyManager, ConnectionManager connectionManager,
|
|
||||||
IdentityManager identityManager, ContactManager contactManager,
|
IdentityManager identityManager, ContactManager contactManager,
|
||||||
Clock clock, PluginManager pluginManager) {
|
Clock clock, PluginManager pluginManager) {
|
||||||
this.crypto = crypto;
|
this.crypto = crypto;
|
||||||
@@ -50,8 +45,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
|||||||
this.streamReaderFactory = streamReaderFactory;
|
this.streamReaderFactory = streamReaderFactory;
|
||||||
this.streamWriterFactory = streamWriterFactory;
|
this.streamWriterFactory = streamWriterFactory;
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
this.groupFactory = groupFactory;
|
|
||||||
this.keyManager = keyManager;
|
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.identityManager = identityManager;
|
this.identityManager = identityManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -63,8 +56,7 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
|||||||
int remoteCode) {
|
int remoteCode) {
|
||||||
return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory,
|
return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory,
|
||||||
streamReaderFactory, streamWriterFactory, authorFactory,
|
streamReaderFactory, streamWriterFactory, authorFactory,
|
||||||
groupFactory, keyManager, connectionManager, identityManager,
|
connectionManager, identityManager, contactManager, clock,
|
||||||
contactManager, clock, pluginManager, localAuthorId, localCode,
|
pluginManager, localAuthorId, localCode, remoteCode);
|
||||||
remoteCode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,10 +88,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addContact(ContactId c, SecretKey master, long timestamp,
|
public void addContact(Transaction txn, ContactId c, SecretKey master,
|
||||||
boolean alice) {
|
long timestamp, boolean alice) throws DbException {
|
||||||
for (TransportKeyManager m : managers.values())
|
for (TransportKeyManager m : managers.values())
|
||||||
m.addContact(c, master, timestamp, alice);
|
m.addContact(txn, c, master, timestamp, alice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamContext getStreamContext(ContactId c, TransportId t) {
|
public StreamContext getStreamContext(ContactId c, TransportId t) {
|
||||||
|
|||||||
@@ -149,8 +149,8 @@ class TransportKeyManager {
|
|||||||
timer.schedule(task, delay);
|
timer.schedule(task, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addContact(ContactId c, SecretKey master, long timestamp,
|
void addContact(Transaction txn, ContactId c, SecretKey master,
|
||||||
boolean alice) {
|
long timestamp, boolean alice) throws DbException {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
// Work out what rotation period the timestamp belongs to
|
// Work out what rotation period the timestamp belongs to
|
||||||
@@ -164,15 +164,7 @@ class TransportKeyManager {
|
|||||||
// Initialise mutable state for the contact
|
// Initialise mutable state for the contact
|
||||||
addKeys(c, new MutableTransportKeys(k));
|
addKeys(c, new MutableTransportKeys(k));
|
||||||
// Write the keys back to the DB
|
// Write the keys back to the DB
|
||||||
Transaction txn = db.startTransaction();
|
db.addTransportKeys(txn, c, k);
|
||||||
try {
|
|
||||||
db.addTransportKeys(txn, c, k);
|
|
||||||
txn.setComplete();
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.forum.ForumModule;
|
import org.briarproject.forum.ForumModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.messaging.MessagingModule;
|
import org.briarproject.messaging.MessagingModule;
|
||||||
|
import org.briarproject.transport.TransportModule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -57,7 +58,8 @@ public class ConstantsTest extends BriarTestCase {
|
|||||||
new TestLifecycleModule(), new TestSystemModule(),
|
new TestLifecycleModule(), new TestSystemModule(),
|
||||||
new ContactModule(), new CryptoModule(), new DatabaseModule(),
|
new ContactModule(), new CryptoModule(), new DatabaseModule(),
|
||||||
new DataModule(), new EventModule(), new ForumModule(),
|
new DataModule(), new EventModule(), new ForumModule(),
|
||||||
new IdentityModule(), new MessagingModule(), new SyncModule());
|
new IdentityModule(), new MessagingModule(), new SyncModule(),
|
||||||
|
new TransportModule());
|
||||||
crypto = i.getInstance(CryptoComponent.class);
|
crypto = i.getInstance(CryptoComponent.class);
|
||||||
authorFactory = i.getInstance(AuthorFactory.class);
|
authorFactory = i.getInstance(AuthorFactory.class);
|
||||||
privateMessageFactory = i.getInstance(PrivateMessageFactory.class);
|
privateMessageFactory = i.getInstance(PrivateMessageFactory.class);
|
||||||
|
|||||||
@@ -135,9 +135,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
Author bobAuthor = new Author(bobId, "Bob",
|
Author bobAuthor = new Author(bobId, "Bob",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
||||||
true);
|
master, timestamp, true, true);
|
||||||
// Derive and store the transport keys
|
|
||||||
keyManager.addContact(contactId, master, timestamp, true);
|
|
||||||
|
|
||||||
// Send Bob a message
|
// Send Bob a message
|
||||||
GroupId groupId = messagingManager.getConversationId(contactId);
|
GroupId groupId = messagingManager.getConversationId(contactId);
|
||||||
@@ -206,9 +204,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
Author aliceAuthor = new Author(aliceId, "Alice",
|
Author aliceAuthor = new Author(aliceId, "Alice",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
||||||
true);
|
master, timestamp, false, true);
|
||||||
// Derive and store the transport keys
|
|
||||||
keyManager.addContact(contactId, master, timestamp, false);
|
|
||||||
|
|
||||||
// Set up an event listener
|
// Set up an event listener
|
||||||
MessageListener listener = new MessageListener();
|
MessageListener listener = new MessageListener();
|
||||||
|
|||||||
@@ -133,17 +133,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
will(new EncodeTagAction());
|
will(new EncodeTagAction());
|
||||||
}
|
}
|
||||||
// Save the keys
|
// Save the keys
|
||||||
oneOf(db).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addTransportKeys(txn, contactId, rotated);
|
oneOf(db).addTransportKeys(txn, contactId, rotated);
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
|
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
|
||||||
crypto, timer, clock, transportId, maxLatency);
|
crypto, timer, clock, transportId, maxLatency);
|
||||||
// The timestamp is 1 ms before the start of rotation period 1000
|
// The timestamp is 1 ms before the start of rotation period 1000
|
||||||
long timestamp = rotationPeriodLength * 1000 - 1;
|
long timestamp = rotationPeriodLength * 1000 - 1;
|
||||||
transportKeyManager.addContact(contactId, masterKey, timestamp, alice);
|
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
|
||||||
|
alice);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
@@ -194,17 +192,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
||||||
will(returnValue(transportKeys));
|
will(returnValue(transportKeys));
|
||||||
// Save the keys
|
// Save the keys
|
||||||
oneOf(db).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
|
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
|
||||||
crypto, timer, clock, transportId, maxLatency);
|
crypto, timer, clock, transportId, maxLatency);
|
||||||
// The timestamp is at the start of rotation period 1000
|
// The timestamp is at the start of rotation period 1000
|
||||||
long timestamp = rotationPeriodLength * 1000;
|
long timestamp = rotationPeriodLength * 1000;
|
||||||
transportKeyManager.addContact(contactId, masterKey, timestamp, alice);
|
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
|
||||||
|
alice);
|
||||||
assertNull(transportKeyManager.getStreamContext(contactId));
|
assertNull(transportKeyManager.getStreamContext(contactId));
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
@@ -240,10 +236,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
||||||
will(returnValue(transportKeys));
|
will(returnValue(transportKeys));
|
||||||
// Save the keys
|
// Save the keys
|
||||||
oneOf(db).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Increment the stream counter
|
// Increment the stream counter
|
||||||
oneOf(db).startTransaction();
|
oneOf(db).startTransaction();
|
||||||
will(returnValue(txn1));
|
will(returnValue(txn1));
|
||||||
@@ -256,7 +249,8 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
crypto, timer, clock, transportId, maxLatency);
|
crypto, timer, clock, transportId, maxLatency);
|
||||||
// The timestamp is at the start of rotation period 1000
|
// The timestamp is at the start of rotation period 1000
|
||||||
long timestamp = rotationPeriodLength * 1000;
|
long timestamp = rotationPeriodLength * 1000;
|
||||||
transportKeyManager.addContact(contactId, masterKey, timestamp, alice);
|
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
|
||||||
|
alice);
|
||||||
// The first request should return a stream context
|
// The first request should return a stream context
|
||||||
StreamContext ctx = transportKeyManager.getStreamContext(contactId);
|
StreamContext ctx = transportKeyManager.getStreamContext(contactId);
|
||||||
assertNotNull(ctx);
|
assertNotNull(ctx);
|
||||||
@@ -299,17 +293,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
||||||
will(returnValue(transportKeys));
|
will(returnValue(transportKeys));
|
||||||
// Save the keys
|
// Save the keys
|
||||||
oneOf(db).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
|
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
|
||||||
crypto, timer, clock, transportId, maxLatency);
|
crypto, timer, clock, transportId, maxLatency);
|
||||||
// The timestamp is at the start of rotation period 1000
|
// The timestamp is at the start of rotation period 1000
|
||||||
long timestamp = rotationPeriodLength * 1000;
|
long timestamp = rotationPeriodLength * 1000;
|
||||||
transportKeyManager.addContact(contactId, masterKey, timestamp, alice);
|
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
|
||||||
|
alice);
|
||||||
assertNull(transportKeyManager.getStreamContext(new byte[TAG_LENGTH]));
|
assertNull(transportKeyManager.getStreamContext(new byte[TAG_LENGTH]));
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
@@ -345,10 +337,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
oneOf(crypto).rotateTransportKeys(transportKeys, 1000);
|
||||||
will(returnValue(transportKeys));
|
will(returnValue(transportKeys));
|
||||||
// Save the keys
|
// Save the keys
|
||||||
oneOf(db).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Encode a new tag after sliding the window
|
// Encode a new tag after sliding the window
|
||||||
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
||||||
with(tagKey), with((long) REORDERING_WINDOW_SIZE));
|
with(tagKey), with((long) REORDERING_WINDOW_SIZE));
|
||||||
@@ -365,7 +354,8 @@ public class TransportKeyManagerTest extends BriarTestCase {
|
|||||||
crypto, timer, clock, transportId, maxLatency);
|
crypto, timer, clock, transportId, maxLatency);
|
||||||
// The timestamp is at the start of rotation period 1000
|
// The timestamp is at the start of rotation period 1000
|
||||||
long timestamp = rotationPeriodLength * 1000;
|
long timestamp = rotationPeriodLength * 1000;
|
||||||
transportKeyManager.addContact(contactId, masterKey, timestamp, alice);
|
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
|
||||||
|
alice);
|
||||||
// Use the first tag (previous rotation period, stream number 0)
|
// Use the first tag (previous rotation period, stream number 0)
|
||||||
assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size());
|
assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size());
|
||||||
byte[] tag = tags.get(0);
|
byte[] tag = tags.get(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user