Optionally include handshake public key for new contact.

This commit is contained in:
akwizgran
2019-05-30 16:36:25 +01:00
parent 83dc52572d
commit 4a2936c685
9 changed files with 60 additions and 256 deletions

View File

@@ -61,14 +61,7 @@ public interface DatabaseComponent extends TransactionManager {
* and returns an ID for the contact. * and returns an ID for the contact.
*/ */
ContactId addContact(Transaction txn, Author remote, AuthorId local, ContactId addContact(Transaction txn, Author remote, AuthorId local,
boolean verified) throws DbException; @Nullable PublicKey handshake, boolean verified) throws DbException;
/**
* Stores a contact associated with the given local and remote pseudonyms,
* replacing the given pending contact, and returns an ID for the contact.
*/
ContactId addContact(Transaction txn, PendingContactId p, Author remote,
AuthorId local, boolean verified) throws DbException;
/** /**
* Stores a group. * Stores a group.

View File

@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.PendingContactState; import org.briarproject.bramble.api.contact.PendingContactState;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -76,7 +77,7 @@ class ContactManagerImpl implements ContactManager {
public ContactId addContact(Transaction txn, Author remote, AuthorId local, public ContactId addContact(Transaction txn, Author remote, AuthorId local,
SecretKey rootKey, long timestamp, boolean alice, boolean verified, SecretKey rootKey, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException { boolean active) throws DbException {
ContactId c = db.addContact(txn, remote, local, verified); ContactId c = db.addContact(txn, remote, local, null, verified);
keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp, keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp,
alice, active); alice, active);
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
@@ -89,7 +90,9 @@ class ContactManagerImpl implements ContactManager {
Author remote, AuthorId local, SecretKey rootKey, long timestamp, Author remote, AuthorId local, SecretKey rootKey, long timestamp,
boolean alice, boolean verified, boolean active) boolean alice, boolean verified, boolean active)
throws DbException { throws DbException {
ContactId c = db.addContact(txn, p, remote, local, verified); PublicKey handshake = db.getPendingContact(txn, p).getPublicKey();
db.removePendingContact(txn, p);
ContactId c = db.addContact(txn, remote, local, handshake, verified);
keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp, keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp,
alice, active); alice, active);
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
@@ -100,7 +103,7 @@ class ContactManagerImpl implements ContactManager {
@Override @Override
public ContactId addContact(Transaction txn, Author remote, AuthorId local, public ContactId addContact(Transaction txn, Author remote, AuthorId local,
boolean verified) throws DbException { boolean verified) throws DbException {
ContactId c = db.addContact(txn, remote, local, verified); ContactId c = db.addContact(txn, remote, local, null, verified);
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
for (ContactHook hook : hooks) hook.addingContact(txn, contact); for (ContactHook hook : hooks) hook.addingContact(txn, contact);
return c; return c;

View File

@@ -88,8 +88,8 @@ interface Database<T> {
* 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(T txn, Author remote, AuthorId local, boolean verified) ContactId addContact(T txn, Author remote, AuthorId local,
throws DbException; @Nullable PublicKey handshake, boolean verified) throws DbException;
/** /**
* Stores a group. * Stores a group.
@@ -695,14 +695,6 @@ interface Database<T> {
void setTransportKeysActive(T txn, TransportId t, KeySetId k) void setTransportKeysActive(T txn, TransportId t, KeySetId k)
throws DbException; throws DbException;
/**
* Transfers ownership of any transport keys from the given pending contact
* to the given contact and copies the pending contact's handshake public
* key to the contact.
*/
void transferKeys(T txn, PendingContactId p, ContactId c)
throws DbException;
/** /**
* Updates the transmission count, expiry time and estimated time of arrival * Updates the transmission count, expiry time and estimated time of arrival
* of the given message with respect to the given contact, using the latency * of the given message with respect to the given contact, using the latency

View File

@@ -85,6 +85,7 @@ import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
@@ -99,7 +100,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
class DatabaseComponentImpl<T> implements DatabaseComponent { class DatabaseComponentImpl<T> implements DatabaseComponent {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(DatabaseComponentImpl.class.getName()); getLogger(DatabaseComponentImpl.class.getName());
private final Database<T> db; private final Database<T> db;
private final Class<T> txnClass; private final Class<T> txnClass;
@@ -234,39 +235,18 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Override @Override
public ContactId addContact(Transaction transaction, Author remote, public ContactId addContact(Transaction transaction, Author remote,
AuthorId local, boolean verified) throws DbException { AuthorId local, @Nullable PublicKey handshake, boolean verified)
if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction);
if (!db.containsIdentity(txn, local))
throw new NoSuchIdentityException();
if (db.containsIdentity(txn, remote.getId()))
throw new ContactExistsException(local, remote);
if (db.containsContact(txn, remote.getId(), local))
throw new ContactExistsException(local, remote);
ContactId c = db.addContact(txn, remote, local, verified);
transaction.attach(new ContactAddedEvent(c, verified));
return c;
}
@Override
public ContactId addContact(Transaction transaction, PendingContactId p,
Author remote, AuthorId local, boolean verified)
throws DbException { throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsPendingContact(txn, p))
throw new NoSuchPendingContactException();
if (!db.containsIdentity(txn, local)) if (!db.containsIdentity(txn, local))
throw new NoSuchIdentityException(); throw new NoSuchIdentityException();
if (db.containsIdentity(txn, remote.getId())) if (db.containsIdentity(txn, remote.getId()))
throw new ContactExistsException(local, remote); throw new ContactExistsException(local, remote);
if (db.containsContact(txn, remote.getId(), local)) if (db.containsContact(txn, remote.getId(), local))
throw new ContactExistsException(local, remote); throw new ContactExistsException(local, remote);
ContactId c = db.addContact(txn, remote, local, verified); ContactId c = db.addContact(txn, remote, local, handshake, verified);
db.transferKeys(txn, p, c);
db.removePendingContact(txn, p);
transaction.attach(new ContactAddedEvent(c, verified)); transaction.attach(new ContactAddedEvent(c, verified));
transaction.attach(new PendingContactRemovedEvent(p));
return c; return c;
} }

View File

@@ -629,22 +629,25 @@ abstract class JdbcDatabase implements Database<Connection> {
@Override @Override
public ContactId addContact(Connection txn, Author remote, AuthorId local, public ContactId addContact(Connection txn, Author remote, AuthorId local,
boolean verified) throws DbException { @Nullable PublicKey handshake, boolean verified)
throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
// Create a contact row // Create a contact row
String sql = "INSERT INTO contacts" String sql = "INSERT INTO contacts"
+ " (authorId, formatVersion, name, publicKey," + " (authorId, formatVersion, name, publicKey,"
+ " localAuthorId, verified)" + " localAuthorId, handshakePublicKey, verified)"
+ " VALUES (?, ?, ?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, remote.getId().getBytes()); ps.setBytes(1, remote.getId().getBytes());
ps.setInt(2, remote.getFormatVersion()); ps.setInt(2, remote.getFormatVersion());
ps.setString(3, remote.getName()); ps.setString(3, remote.getName());
ps.setBytes(4, remote.getPublicKey().getEncoded()); ps.setBytes(4, remote.getPublicKey().getEncoded());
ps.setBytes(5, local.getBytes()); ps.setBytes(5, local.getBytes());
ps.setBoolean(6, verified); if (handshake == null) ps.setNull(6, BINARY);
else ps.setBytes(6, handshake.getEncoded());
ps.setBoolean(7, verified);
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException(); if (affected != 1) throw new DbStateException();
ps.close(); ps.close();
@@ -3139,48 +3142,6 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
@Override
public void transferKeys(Connection txn, PendingContactId p, ContactId c)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
// Transfer the handshake public key
String sql = "SELECT publicKey from pendingContacts"
+ " WHERE pendingContactId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, p.getBytes());
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
byte[] publicKey = rs.getBytes(1);
if (rs.next()) throw new DbStateException();
rs.close();
ps.close();
sql = "UPDATE contacts SET handshakePublicKey = ?"
+ " WHERE contactId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, publicKey);
ps.setInt(2, c.getInt());
int affected = ps.executeUpdate();
if (affected < 0 || affected > 1) throw new DbStateException();
ps.close();
// Transfer the transport keys
sql = "UPDATE outgoingKeys"
+ " SET contactId = ?, pendingContactId = NULL"
+ " WHERE pendingContactId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setBytes(2, p.getBytes());
affected = ps.executeUpdate();
if (affected < 0) throw new DbStateException();
ps.close();
} catch (SQLException e) {
tryToClose(rs, LOG, WARNING);
tryToClose(ps, LOG, WARNING);
throw new DbException(e);
}
}
@Override @Override
public void updateExpiryTimeAndEta(Connection txn, ContactId c, MessageId m, public void updateExpiryTimeAndEta(Connection txn, ContactId c, MessageId m,
int maxLatency) throws DbException { int maxLatency) throws DbException {

View File

@@ -71,7 +71,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(false), withDbCallable(txn)); oneOf(db).transactionWithResult(with(false), withDbCallable(txn));
oneOf(db).addContact(txn, remote, local, verified); oneOf(db).addContact(txn, remote, local, null, verified);
will(returnValue(contactId)); will(returnValue(contactId));
oneOf(keyManager).addContactWithRotationKeys(txn, contactId, oneOf(keyManager).addContactWithRotationKeys(txn, contactId,
rootKey, timestamp, alice, active); rootKey, timestamp, alice, active);

View File

@@ -176,7 +176,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
oneOf(database).containsContact(txn, author.getId(), oneOf(database).containsContact(txn, author.getId(),
localAuthor.getId()); localAuthor.getId());
will(returnValue(false)); will(returnValue(false));
oneOf(database).addContact(txn, author, localAuthor.getId(), true); oneOf(database).addContact(txn, author, localAuthor.getId(),
null, true);
will(returnValue(contactId)); will(returnValue(contactId));
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class))); oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
// getContacts() // getContacts()
@@ -224,7 +225,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
db.transaction(false, transaction -> { db.transaction(false, transaction -> {
db.addIdentity(transaction, identity); db.addIdentity(transaction, identity);
assertEquals(contactId, db.addContact(transaction, author, assertEquals(contactId, db.addContact(transaction, author,
localAuthor.getId(), true)); localAuthor.getId(), null, true));
assertEquals(singletonList(contact), assertEquals(singletonList(contact),
db.getContacts(transaction)); db.getContacts(transaction));
db.addGroup(transaction, group); // First time - listeners called db.addGroup(transaction, group); // First time - listeners called
@@ -445,7 +446,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.addContact(transaction, author, localAuthor.getId(), db.addContact(transaction, author, localAuthor.getId(),
true)); null, true));
fail(); fail();
} catch (NoSuchIdentityException expected) { } catch (NoSuchIdentityException expected) {
// Expected // Expected
@@ -763,25 +764,16 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Check whether the pending contact is in the DB (which it's not) // Check whether the pending contact is in the DB (which it's not)
exactly(4).of(database).startTransaction(); exactly(3).of(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
exactly(4).of(database).containsPendingContact(txn, exactly(3).of(database).containsPendingContact(txn,
pendingContactId); pendingContactId);
will(returnValue(false)); will(returnValue(false));
exactly(4).of(database).abortTransaction(txn); exactly(3).of(database).abortTransaction(txn);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, eventBus, DatabaseComponent db = createDatabaseComponent(database, eventBus,
eventExecutor, shutdownManager); eventExecutor, shutdownManager);
try {
db.transaction(false, transaction ->
db.addContact(transaction, pendingContactId, author,
localAuthor.getId(), true));
fail();
} catch (NoSuchPendingContactException expected) {
// Expected
}
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.addTransportKeys(transaction, pendingContactId, db.addTransportKeys(transaction, pendingContactId,
@@ -1473,7 +1465,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.addContact(transaction, author, localAuthor.getId(), db.addContact(transaction, author, localAuthor.getId(),
true)); null, true));
fail(); fail();
} catch (ContactExistsException expected) { } catch (ContactExistsException expected) {
assertEquals(localAuthor.getId(), expected.getLocalAuthorId()); assertEquals(localAuthor.getId(), expected.getLocalAuthorId());
@@ -1503,70 +1495,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.addContact(transaction, author, localAuthor.getId(), db.addContact(transaction, author, localAuthor.getId(),
true)); null, true));
fail();
} catch (ContactExistsException expected) {
assertEquals(localAuthor.getId(), expected.getLocalAuthorId());
assertEquals(author, expected.getRemoteAuthor());
}
}
@Test
public void testCannotAddLocalIdentityAsContactFromPendingContact()
throws Exception {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsPendingContact(txn, pendingContactId);
will(returnValue(true));
oneOf(database).containsIdentity(txn, localAuthor.getId());
will(returnValue(true));
// Contact is a local identity
oneOf(database).containsIdentity(txn, author.getId());
will(returnValue(true));
oneOf(database).abortTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
eventExecutor, shutdownManager);
try {
db.transaction(false, transaction ->
db.addContact(transaction, pendingContactId, author,
localAuthor.getId(), true));
fail();
} catch (ContactExistsException expected) {
assertEquals(localAuthor.getId(), expected.getLocalAuthorId());
assertEquals(author, expected.getRemoteAuthor());
}
}
@Test
public void testCannotAddDuplicateContactFromPendingContact()
throws Exception {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsPendingContact(txn, pendingContactId);
will(returnValue(true));
oneOf(database).containsIdentity(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).containsIdentity(txn, author.getId());
will(returnValue(false));
// Contact already exists for this local identity
oneOf(database).containsContact(txn, author.getId(),
localAuthor.getId());
will(returnValue(true));
oneOf(database).abortTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
eventExecutor, shutdownManager);
try {
db.transaction(false, transaction ->
db.addContact(transaction, pendingContactId, author,
localAuthor.getId(), true));
fail(); fail();
} catch (ContactExistsException expected) { } catch (ContactExistsException expected) {
assertEquals(localAuthor.getId(), expected.getLocalAuthorId()); assertEquals(localAuthor.getId(), expected.getLocalAuthorId());

View File

@@ -548,7 +548,7 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
for (int i = 0; i < CONTACTS; i++) { for (int i = 0; i < CONTACTS; i++) {
ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(), ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(),
random.nextBoolean()); null, random.nextBoolean());
contacts.add(db.getContact(txn, c)); contacts.add(db.getContact(txn, c));
contactGroups.put(c, new ArrayList<>()); contactGroups.put(c, new ArrayList<>());
for (int j = 0; j < GROUPS_PER_CONTACT; j++) { for (int j = 0; j < GROUPS_PER_CONTACT; j++) {

View File

@@ -147,7 +147,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertFalse(db.containsContact(txn, contactId)); assertFalse(db.containsContact(txn, contactId));
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
assertTrue(db.containsContact(txn, contactId)); assertTrue(db.containsContact(txn, contactId));
assertFalse(db.containsGroup(txn, groupId)); assertFalse(db.containsGroup(txn, groupId));
db.addGroup(txn, group); db.addGroup(txn, group);
@@ -210,7 +210,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -241,7 +241,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared but unvalidated message // Add a contact, a shared group and a shared but unvalidated message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, UNKNOWN, true, null); db.addMessage(txn, message, UNKNOWN, true, null);
@@ -286,7 +286,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, an invisible group and a shared message // Add a contact, an invisible group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -337,7 +337,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and an unshared message // Add a contact, a shared group and an unshared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, false, null); db.addMessage(txn, message, DELIVERED, false, null);
@@ -368,7 +368,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -395,7 +395,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact and a visible group // Add a contact and a visible group
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, false); db.addGroupVisibility(txn, contactId, groupId, false);
@@ -436,7 +436,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -568,7 +568,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact and a shared group // Add a contact and a shared group
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
@@ -588,7 +588,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact // Add a contact
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
// The group is not in the database // The group is not in the database
assertFalse(db.containsVisibleMessage(txn, contactId, messageId)); assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
@@ -606,7 +606,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, an invisible group and a message // Add a contact, an invisible group and a message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -625,7 +625,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact and a group // Add a contact and a group
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
// The group should not be visible to the contact // The group should not be visible to the contact
@@ -677,7 +677,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, the transport and the transport keys // Add the contact, the transport and the transport keys
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1)); assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1));
@@ -786,7 +786,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, the transport and the handshake keys // Add the contact, the transport and the handshake keys
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1)); assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1));
@@ -920,7 +920,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, transport and transport keys // Add the contact, transport and transport keys
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
@@ -964,7 +964,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, transport and handshake keys // Add the contact, transport and handshake keys
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
@@ -1011,7 +1011,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, transport and transport keys // Add the contact, transport and transport keys
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
@@ -1058,7 +1058,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, transport and handshake keys // Add the contact, transport and handshake keys
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
@@ -1104,7 +1104,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact associated with the local author // Add a contact associated with the local author
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
// Ensure contact is returned from database by author ID // Ensure contact is returned from database by author ID
Collection<Contact> contacts = Collection<Contact> contacts =
@@ -1135,7 +1135,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact associated with the local author // Add a contact associated with the local author
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
contacts = db.getContacts(txn, localAuthor.getId()); contacts = db.getContacts(txn, localAuthor.getId());
assertEquals(singletonList(contactId), contacts); assertEquals(singletonList(contactId), contacts);
@@ -1157,7 +1157,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact - initially there should be no offered messages // Add a contact - initially there should be no offered messages
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
assertEquals(0, db.countOfferedMessages(txn, contactId)); assertEquals(0, db.countOfferedMessages(txn, contactId));
// Add some offered messages and count them // Add some offered messages and count them
@@ -1741,7 +1741,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -1853,9 +1853,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the same contact for each local author // Add the same contact for each local author
ContactId contactId = ContactId contactId =
db.addContact(txn, author, localAuthor.getId(), true); db.addContact(txn, author, localAuthor.getId(), null, true);
ContactId contactId1 = ContactId contactId1 =
db.addContact(txn, author, localAuthor1.getId(), true); db.addContact(txn, author, localAuthor1.getId(), null, true);
// The contacts should be distinct // The contacts should be distinct
assertNotEquals(contactId, contactId1); assertNotEquals(contactId, contactId1);
@@ -1875,7 +1875,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -1929,7 +1929,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact // Add a contact
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
// The contact should have no alias // The contact should have no alias
Contact contact = db.getContact(txn, contactId); Contact contact = db.getContact(txn, contactId);
@@ -1986,7 +1986,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a group and a message // Add a contact, a group and a message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, message, UNKNOWN, false, null); db.addMessage(txn, message, UNKNOWN, false, null);
@@ -2070,7 +2070,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -2115,7 +2115,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addIdentity(txn, identity); db.addIdentity(txn, identity);
assertEquals(contactId, assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true)); db.addContact(txn, author, localAuthor.getId(), null, true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -2229,60 +2229,6 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertEquals(expected.getTimestamp(), actual.getTimestamp()); assertEquals(expected.getTimestamp(), actual.getTimestamp());
} }
@Test
public void testTransferKeys() throws Exception {
boolean alice = random.nextBoolean();
TransportKeys transportKeys =
createHandshakeKeys(1000, getSecretKey(), alice);
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add the pending contact, the transport and the handshake keys
db.addPendingContact(txn, pendingContact);
db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, pendingContact.getId(),
transportKeys));
Collection<TransportKeySet> allKeys =
db.getTransportKeys(txn, transportId);
assertEquals(1, allKeys.size());
TransportKeySet ks = allKeys.iterator().next();
assertEquals(keySetId, ks.getKeySetId());
assertNull(ks.getContactId());
assertEquals(pendingContact.getId(), ks.getPendingContactId());
// Add a contact
db.addIdentity(txn, identity);
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
// The contact shouldn't have a handshake public key
Contact contact = db.getContact(txn, contactId);
assertNull(contact.getHandshakePublicKey());
// Transfer the keys to the contact
db.transferKeys(txn, pendingContact.getId(), contactId);
// The handshake public key should have been copied to the contact
contact = db.getContact(txn, contactId);
PublicKey handshakePublicKey = contact.getHandshakePublicKey();
assertNotNull(handshakePublicKey);
assertArrayEquals(pendingContact.getPublicKey().getEncoded(),
handshakePublicKey.getEncoded());
// The transport keys should have been transferred to the contact
allKeys = db.getTransportKeys(txn, transportId);
assertEquals(1, allKeys.size());
ks = allKeys.iterator().next();
assertEquals(keySetId, ks.getKeySetId());
assertEquals(contactId, ks.getContactId());
assertNull(ks.getPendingContactId());
db.commitTransaction(txn);
db.close();
}
@Test @Test
public void testSetHandshakeKeyPair() throws Exception { public void testSetHandshakeKeyPair() throws Exception {
Identity withoutKeys = new Identity(localAuthor, null, null, Identity withoutKeys = new Identity(localAuthor, null, null,