From 151a3605876748dbb8417772eb2d20cb0b18c259 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Thu, 11 Aug 2011 15:41:52 +0100
Subject: [PATCH] Store shared secrets in the database (the crypto component
 will be responsible for wrapping/unwrapping them).

---
 .../sf/briar/api/db/DatabaseComponent.java    |  9 ++-
 components/net/sf/briar/db/Database.java      | 13 +++-
 components/net/sf/briar/db/JdbcDatabase.java  | 32 +++++++--
 .../db/ReadWriteLockDatabaseComponent.java    | 24 ++++++-
 .../db/SynchronizedDatabaseComponent.java     | 21 +++++-
 .../sf/briar/db/DatabaseComponentTest.java    | 24 +++++--
 test/net/sf/briar/db/H2DatabaseTest.java      | 72 ++++++++++---------
 7 files changed, 138 insertions(+), 57 deletions(-)

diff --git a/api/net/sf/briar/api/db/DatabaseComponent.java b/api/net/sf/briar/api/db/DatabaseComponent.java
index 03188adeb6..c4433c846e 100644
--- a/api/net/sf/briar/api/db/DatabaseComponent.java
+++ b/api/net/sf/briar/api/db/DatabaseComponent.java
@@ -58,10 +58,10 @@ public interface DatabaseComponent {
 
 	/**
 	 * Adds a new contact to the database with the given transport properties
-	 * and returns an ID for the contact.
+	 * and shared secret, returns an ID for the contact.
 	 */
-	ContactId addContact(Map<String, Map<String, String>> transports)
-	throws DbException;
+	ContactId addContact(Map<String, Map<String, String>> transports,
+			byte[] secret) throws DbException;
 
 	/** Adds a locally generated message to the database. */
 	void addLocallyGeneratedMessage(Message m) throws DbException;
@@ -117,6 +117,9 @@ public interface DatabaseComponent {
 	/** Returns the user's rating for the given author. */
 	Rating getRating(AuthorId a) throws DbException;
 
+	/** Returns the secret shared with the given contact. */
+	byte[] getSharedSecret(ContactId c) throws DbException;
+
 	/** Returns the set of groups to which the user subscribes. */
 	Collection<Group> getSubscriptions() throws DbException;
 
diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java
index 4f73cb9eb7..7e8a204262 100644
--- a/components/net/sf/briar/db/Database.java
+++ b/components/net/sf/briar/db/Database.java
@@ -79,12 +79,12 @@ interface Database<T> {
 
 	/**
 	 * Adds a new contact to the database with the given transport properties
-	 * and returns an ID for the contact.
+	 * and secret, and returns an ID for the contact.
 	 * <p>
 	 * Locking: contacts write, transports write.
 	 */
-	ContactId addContact(T txn, Map<String, Map<String, String>> transports)
-	throws DbException;
+	ContactId addContact(T txn, Map<String, Map<String, String>> transports,
+			byte[] secret) throws DbException;
 
 	/**
 	 * Returns false if the given message is already in the database. Otherwise
@@ -273,6 +273,13 @@ interface Database<T> {
 	Collection<MessageId> getSendableMessages(T txn, ContactId c, int size)
 	throws DbException;
 
+	/**
+	 * Returns the secret shared with the given contact.
+	 * <p>
+	 * Locking: contacts read.
+	 */
+	byte[] getSharedSecret(T txn, ContactId c) throws DbException;
+
 	/**
 	 * Returns the groups to which the user subscribes.
 	 * <p>
diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java
index f2b314d68d..d0bf3a5d75 100644
--- a/components/net/sf/briar/db/JdbcDatabase.java
+++ b/components/net/sf/briar/db/JdbcDatabase.java
@@ -79,6 +79,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 		+ " (contactId INT NOT NULL,"
 		+ " subscriptionsTimestamp BIGINT NOT NULL,"
 		+ " transportsTimestamp BIGINT NOT NULL,"
+		+ " secret BINARY NOT NULL,"
 		+ " PRIMARY KEY (contactId))";
 
 	private static final String CREATE_VISIBILITIES =
@@ -432,7 +433,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 	}
 
 	public ContactId addContact(Connection txn,
-			Map<String, Map<String, String>> transports)
+			Map<String, Map<String, String>> transports, byte[] secret)
 	throws DbException {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
@@ -449,13 +450,14 @@ abstract class JdbcDatabase implements Database<Connection> {
 			rs.close();
 			ps.close();
 			// Create a new contact row
-			sql = "INSERT INTO contacts"
-				+ " (contactId, subscriptionsTimestamp, transportsTimestamp)"
-				+ " VALUES (?, ?, ?)";
+			sql = "INSERT INTO contacts (contactId, subscriptionsTimestamp,"
+				+ " transportsTimestamp, secret)"
+				+ " VALUES (?, ?, ?, ?)";
 			ps = txn.prepareStatement(sql);
 			ps.setInt(1, c.getInt());
 			ps.setLong(2, 0L);
 			ps.setLong(3, 0L);
+			ps.setBytes(4, secret);
 			int affected = ps.executeUpdate();
 			if(affected != 1) throw new DbStateException();
 			ps.close();
@@ -1048,6 +1050,28 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
+	public byte[] getSharedSecret(Connection txn, ContactId c)
+	throws DbException {
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		try {
+			String sql = "SELECT secret FROM contacts WHERE contactId = ?";
+			ps = txn.prepareStatement(sql);
+			ps.setInt(1, c.getInt());
+			rs = ps.executeQuery();
+			if(!rs.next()) throw new DbStateException();
+			byte[] secret = rs.getBytes(1);
+			if(rs.next()) throw new DbStateException();
+			rs.close();
+			ps.close();
+			return secret;
+		} catch(SQLException e) {
+			tryToClose(rs);
+			tryToClose(ps);
+			throw new DbException(e);
+		}
+	}
+
 	public int getSendability(Connection txn, MessageId m) throws DbException {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
diff --git a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java
index 6a80b926c0..5c984a207e 100644
--- a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java
+++ b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java
@@ -103,8 +103,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 		db.close();
 	}
 
-	public ContactId addContact(Map<String, Map<String, String>> transports)
-	throws DbException {
+	public ContactId addContact(Map<String, Map<String, String>> transports,
+			byte[] secret) throws DbException {
 		if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact");
 		contactLock.writeLock().lock();
 		try {
@@ -112,7 +112,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 			try {
 				Txn txn = db.startTransaction();
 				try {
-					ContactId c = db.addContact(txn, transports);
+					ContactId c = db.addContact(txn, transports, secret);
 					db.commitTransaction(txn);
 					if(LOG.isLoggable(Level.FINE))
 						LOG.fine("Added contact " + c);
@@ -550,6 +550,24 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 		}
 	}
 
+	public byte[] getSharedSecret(ContactId c) throws DbException {
+		contactLock.readLock().lock();
+		try {
+			if(!containsContact(c)) throw new NoSuchContactException();
+			Txn txn = db.startTransaction();
+			try {
+				byte[] secret = db.getSharedSecret(txn, c);
+				db.commitTransaction(txn);
+				return secret;
+			} catch(DbException e) {
+				db.abortTransaction(txn);
+				throw e;
+			}
+		} finally {
+			contactLock.readLock().unlock();
+		}
+	}
+
 	public Collection<Group> getSubscriptions() throws DbException {
 		subscriptionLock.readLock().lock();
 		try {
diff --git a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java
index 0bfc7db141..c5ca968e59 100644
--- a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java
+++ b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java
@@ -86,14 +86,14 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 		db.close();
 	}
 
-	public ContactId addContact(Map<String, Map<String, String>> transports)
-	throws DbException {
+	public ContactId addContact(Map<String, Map<String, String>> transports,
+			byte[] secret) throws DbException {
 		if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact");
 		synchronized(contactLock) {
 			synchronized(transportLock) {
 				Txn txn = db.startTransaction();
 				try {
-					ContactId c = db.addContact(txn, transports);
+					ContactId c = db.addContact(txn, transports, secret);
 					db.commitTransaction(txn);
 					if(LOG.isLoggable(Level.FINE))
 						LOG.fine("Added contact " + c);
@@ -422,6 +422,21 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 		}
 	}
 
+	public byte[] getSharedSecret(ContactId c) throws DbException {
+		synchronized(contactLock) {
+			if(!containsContact(c)) throw new NoSuchContactException();
+			Txn txn = db.startTransaction();
+			try {
+				byte[] secret = db.getSharedSecret(txn, c);
+				db.commitTransaction(txn);
+				return secret;
+			} catch(DbException e) {
+				db.abortTransaction(txn);
+				throw e;
+			}
+		}
+	}
+
 	public Collection<Group> getSubscriptions() throws DbException {
 		synchronized(subscriptionLock) {
 			Txn txn = db.startTransaction();
diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java
index 4a8bd4ee46..b7c1d33a20 100644
--- a/test/net/sf/briar/db/DatabaseComponentTest.java
+++ b/test/net/sf/briar/db/DatabaseComponentTest.java
@@ -54,6 +54,7 @@ public abstract class DatabaseComponentTest extends TestCase {
 	private final Message message;
 	private final Group group;
 	private final Map<String, Map<String, String>> transports;
+	private final byte[] secret;
 
 	public DatabaseComponentTest() {
 		super();
@@ -71,6 +72,7 @@ public abstract class DatabaseComponentTest extends TestCase {
 		group = new TestGroup(groupId, "The really exciting group", null);
 		transports = Collections.singletonMap("foo",
 				Collections.singletonMap("bar", "baz"));
+		secret = new byte[123];
 	}
 
 	protected abstract <T> DatabaseComponent createDatabaseComponent(
@@ -97,7 +99,7 @@ public abstract class DatabaseComponentTest extends TestCase {
 			oneOf(database).getRating(txn, authorId);
 			will(returnValue(Rating.UNRATED));
 			// addContact(transports)
-			oneOf(database).addContact(txn, transports);
+			oneOf(database).addContact(txn, transports, secret);
 			will(returnValue(contactId));
 			// getContacts()
 			oneOf(database).getContacts(txn);
@@ -107,6 +109,11 @@ public abstract class DatabaseComponentTest extends TestCase {
 			will(returnValue(true));
 			oneOf(database).getConnectionWindow(txn, contactId, 123);
 			will(returnValue(connectionWindow));
+			// getSharedSecret(contactId)
+			oneOf(database).containsContact(txn, contactId);
+			will(returnValue(true));
+			oneOf(database).getSharedSecret(txn, contactId);
+			will(returnValue(secret));
 			// getTransports(contactId)
 			oneOf(database).containsContact(txn, contactId);
 			will(returnValue(true));
@@ -153,9 +160,10 @@ public abstract class DatabaseComponentTest extends TestCase {
 		db.open(false);
 		db.addListener(listener);
 		assertEquals(Rating.UNRATED, db.getRating(authorId));
-		assertEquals(contactId, db.addContact(transports));
+		assertEquals(contactId, db.addContact(transports, secret));
 		assertEquals(Collections.singletonList(contactId), db.getContacts());
 		assertEquals(connectionWindow, db.getConnectionWindow(contactId, 123));
+		assertEquals(secret, db.getSharedSecret(contactId));
 		assertEquals(transports, db.getTransports(contactId));
 		db.subscribe(group);
 		db.subscribe(group); // Again - check listeners aren't called
@@ -486,12 +494,11 @@ public abstract class DatabaseComponentTest extends TestCase {
 		final TransportUpdate transportsUpdate = context.mock(TransportUpdate.class);
 		context.checking(new Expectations() {{
 			// Check whether the contact is still in the DB (which it's not)
-			// once for each method
-			exactly(16).of(database).startTransaction();
+			exactly(17).of(database).startTransaction();
 			will(returnValue(txn));
-			exactly(16).of(database).containsContact(txn, contactId);
+			exactly(17).of(database).containsContact(txn, contactId);
 			will(returnValue(false));
-			exactly(16).of(database).commitTransaction(txn);
+			exactly(17).of(database).commitTransaction(txn);
 		}});
 		DatabaseComponent db = createDatabaseComponent(database, cleaner);
 
@@ -536,6 +543,11 @@ public abstract class DatabaseComponentTest extends TestCase {
 			fail();
 		} catch(NoSuchContactException expected) {}
 
+		try {
+			db.getSharedSecret(contactId);
+			fail();
+		} catch(NoSuchContactException expected) {}
+
 		try {
 			db.getTransports(contactId);
 			fail();
diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java
index 87497ed4ca..a0f525eb6a 100644
--- a/test/net/sf/briar/db/H2DatabaseTest.java
+++ b/test/net/sf/briar/db/H2DatabaseTest.java
@@ -66,6 +66,7 @@ public class H2DatabaseTest extends TestCase {
 	private final Group group;
 	private final Map<String, Map<String, String>> transports;
 	private final Map<Group, Long> subscriptions;
+	private final byte[] secret;
 
 	public H2DatabaseTest() throws Exception {
 		super();
@@ -89,6 +90,7 @@ public class H2DatabaseTest extends TestCase {
 		transports = Collections.singletonMap("foo",
 				Collections.singletonMap("bar", "baz"));
 		subscriptions = Collections.singletonMap(group, 0L);
+		secret = new byte[123];
 	}
 
 	@Before
@@ -102,7 +104,7 @@ public class H2DatabaseTest extends TestCase {
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 		assertFalse(db.containsContact(txn, contactId));
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		assertTrue(db.containsContact(txn, contactId));
 		assertFalse(db.containsSubscription(txn, groupId));
 		db.addSubscription(txn, group);
@@ -150,20 +152,20 @@ public class H2DatabaseTest extends TestCase {
 
 		// Create three contacts
 		assertFalse(db.containsContact(txn, contactId));
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		assertTrue(db.containsContact(txn, contactId));
 		assertFalse(db.containsContact(txn, contactId1));
-		assertEquals(contactId1, db.addContact(txn, transports));
+		assertEquals(contactId1, db.addContact(txn, transports, secret));
 		assertTrue(db.containsContact(txn, contactId1));
 		assertFalse(db.containsContact(txn, contactId2));
-		assertEquals(contactId2, db.addContact(txn, transports));
+		assertEquals(contactId2, db.addContact(txn, transports, secret));
 		assertTrue(db.containsContact(txn, contactId2));
 		// Delete one of the contacts
 		db.removeContact(txn, contactId1);
 		assertFalse(db.containsContact(txn, contactId1));
 		// Add another contact - a new ID should be created
 		assertFalse(db.containsContact(txn, contactId3));
-		assertEquals(contactId3, db.addContact(txn, transports));
+		assertEquals(contactId3, db.addContact(txn, transports, secret));
 		assertTrue(db.containsContact(txn, contactId3));
 
 		db.commitTransaction(txn);
@@ -210,7 +212,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -248,7 +250,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -290,7 +292,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.addMessage(txn, message);
@@ -329,7 +331,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.addMessage(txn, message);
@@ -364,7 +366,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -395,7 +397,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
 		db.addMessage(txn, message);
@@ -428,7 +430,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact and some batches to ack
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addBatchToAck(txn, contactId, batchId);
 		db.addBatchToAck(txn, contactId, batchId1);
 		db.commitTransaction(txn);
@@ -456,7 +458,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact and receive the same batch twice
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addBatchToAck(txn, contactId, batchId);
 		db.addBatchToAck(txn, contactId, batchId);
 		db.commitTransaction(txn);
@@ -483,7 +485,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -520,7 +522,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -563,7 +565,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		// Add some outstanding batches, a few ms apart
 		for(int i = 0; i < ids.length; i++) {
 			db.addOutstandingBatch(txn, contactId, ids[i],
@@ -602,7 +604,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		// Add some outstanding batches, a few ms apart
 		for(int i = 0; i < ids.length; i++) {
 			db.addOutstandingBatch(txn, contactId, ids[i],
@@ -830,7 +832,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact with some transport properties
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		assertEquals(transports, db.getTransports(txn, contactId));
 		// Replace the transport properties
 		Map<String, Map<String, String>> transports1 =
@@ -888,7 +890,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact with some transport properties
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		assertEquals(transports, db.getTransports(txn, contactId));
 		// Replace the transport properties using a timestamp of 2
 		Map<String, Map<String, String>> transports1 =
@@ -919,7 +921,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		// Add some subscriptions
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
 		assertEquals(Collections.singletonList(group),
@@ -944,7 +946,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		// Add some subscriptions
 		db.setSubscriptions(txn, contactId, subscriptions, 2);
 		assertEquals(Collections.singletonList(group),
@@ -967,7 +969,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact and subscribe to a group
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
 
@@ -985,7 +987,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
 		db.addMessage(txn, message);
@@ -1008,7 +1010,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
 		db.addMessage(txn, message);
@@ -1030,7 +1032,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		// The message is older than the contact's subscription
@@ -1055,7 +1057,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -1080,7 +1082,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact and subscribe to a group
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -1099,7 +1101,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact with a subscription
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
 
 		// There's no local subscription for the group
@@ -1116,7 +1118,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.addMessage(txn, message);
 		db.setStatus(txn, contactId, messageId, Status.NEW);
@@ -1135,7 +1137,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.addMessage(txn, message);
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -1155,7 +1157,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -1176,7 +1178,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact, subscribe to a group and store a message
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 		db.setVisibility(txn, groupId, Collections.singleton(contactId));
 		db.setSubscriptions(txn, contactId, subscriptions, 1);
@@ -1196,7 +1198,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact and subscribe to a group
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 		db.addSubscription(txn, group);
 
 		// The group should not be visible to the contact
@@ -1222,7 +1224,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 
 		// Get the connection window for a new transport
 		ConnectionWindow w = db.getConnectionWindow(txn, contactId, 123);
@@ -1242,7 +1244,7 @@ public class H2DatabaseTest extends TestCase {
 		Connection txn = db.startTransaction();
 
 		// Add a contact
-		assertEquals(contactId, db.addContact(txn, transports));
+		assertEquals(contactId, db.addContact(txn, transports, secret));
 
 		// Get the connection window for a new transport
 		ConnectionWindow w = db.getConnectionWindow(txn, contactId, 123);
-- 
GitLab