Add a method for binding transport keys to a contact.

This commit is contained in:
akwizgran
2018-03-27 17:01:39 +01:00
parent 5bd2092a03
commit 17fe358fd9
11 changed files with 139 additions and 32 deletions

View File

@@ -131,6 +131,12 @@ interface Database<T> {
KeySetId addTransportKeys(T txn, @Nullable ContactId c, TransportKeys k)
throws DbException;
/**
* Binds the given keys for the given transport to the given contact.
*/
void bindTransportKeys(T txn, ContactId c, TransportId t, KeySetId k)
throws DbException;
/**
* Returns true if the database contains the given contact for the given
* local pseudonym.

View File

@@ -245,6 +245,18 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.addTransportKeys(txn, c, k);
}
@Override
public void bindTransportKeys(Transaction transaction, ContactId c,
TransportId t, KeySetId k) throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction);
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
if (!db.containsTransport(txn, t))
throw new NoSuchTransportException();
db.bindTransportKeys(txn, c, t, k);
}
@Override
public boolean containsContact(Transaction transaction, AuthorId remote,
AuthorId local) throws DbException {

View File

@@ -950,6 +950,33 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
@Override
public void bindTransportKeys(Connection txn, ContactId c, TransportId t,
KeySetId k) throws DbException {
PreparedStatement ps = null;
try {
String sql = "UPDATE outgoingKeys SET contactId = ?"
+ " WHERE keySetId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, k.getInt());
int affected = ps.executeUpdate();
if (affected < 0) throw new DbStateException();
ps.close();
sql = "UPDATE incomingKeys SET contactId = ?"
+ " WHERE keySetId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, k.getInt());
affected = ps.executeUpdate();
if (affected < 0) throw new DbStateException();
ps.close();
} catch (SQLException e) {
tryToClose(ps);
throw new DbException(e);
}
}
@Override
public boolean containsContact(Connection txn, AuthorId remote,
AuthorId local) throws DbException {
@@ -2882,6 +2909,7 @@ abstract class JdbcDatabase implements Database<Connection> {
try {
// Delete any existing outgoing keys - this will also remove any
// incoming keys with the same key set ID
// TODO: Add an index to speed this up?
String sql = "DELETE FROM outgoingKeys WHERE keySetId = ?";
ps = txn.prepareStatement(sql);
for (KeySet ks : keys) {

View File

@@ -22,8 +22,6 @@ import org.briarproject.bramble.api.transport.KeyManager;
import org.briarproject.bramble.api.transport.KeySetId;
import org.briarproject.bramble.api.transport.StreamContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -108,15 +106,32 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
}
@Override
public Collection<KeySetId> addUnboundKeys(Transaction txn,
public Map<TransportId, KeySetId> addUnboundKeys(Transaction txn,
SecretKey master, long timestamp, boolean alice)
throws DbException {
Collection<KeySetId> ids = new ArrayList<>();
for (TransportKeyManager m : managers.values())
ids.add(m.addUnboundKeys(txn, master, timestamp, alice));
Map<TransportId, KeySetId> ids = new HashMap<>();
for (Entry<TransportId, TransportKeyManager> e : managers.entrySet()) {
TransportId t = e.getKey();
TransportKeyManager m = e.getValue();
ids.put(t, m.addUnboundKeys(txn, master, timestamp, alice));
}
return ids;
}
@Override
public void bindKeys(Transaction txn, ContactId c,
Map<TransportId, KeySetId> keys) throws DbException {
for (Entry<TransportId, KeySetId> e : keys.entrySet()) {
TransportId t = e.getKey();
TransportKeyManager m = managers.get(t);
if (m == null) {
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
} else {
m.bindKeys(txn, c, e.getValue());
}
}
}
@Override
public StreamContext getStreamContext(ContactId c, TransportId t)
throws DbException {

View File

@@ -21,6 +21,8 @@ interface TransportKeyManager {
KeySetId addUnboundKeys(Transaction txn, SecretKey master, long timestamp,
boolean alice) throws DbException;
void bindKeys(Transaction txn, ContactId c, KeySetId k) throws DbException;
void removeContact(ContactId c);
@Nullable

View File

@@ -22,7 +22,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -57,7 +56,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
private final ReentrantLock lock = new ReentrantLock();
// The following are locking: lock
private final Collection<MutableKeySet> keys = new ArrayList<>();
private final Map<KeySetId, MutableKeySet> keys = new HashMap<>();
private final Map<Bytes, TagContext> inContexts = new HashMap<>();
private final Map<ContactId, MutableKeySet> outContexts = new HashMap<>();
@@ -123,7 +122,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
private void addKeys(KeySetId keySetId, @Nullable ContactId contactId,
MutableTransportKeys m) {
MutableKeySet ks = new MutableKeySet(keySetId, contactId, m);
keys.add(ks);
keys.put(keySetId, ks);
if (contactId != null) {
encodeTags(keySetId, contactId, m.getPreviousIncomingKeys());
encodeTags(keySetId, contactId, m.getCurrentIncomingKeys());
@@ -204,22 +203,34 @@ class TransportKeyManagerImpl implements TransportKeyManager {
}
}
@Override
public void bindKeys(Transaction txn, ContactId c, KeySetId k)
throws DbException {
lock.lock();
try {
MutableKeySet ks = keys.get(k);
if (ks == null) throw new IllegalArgumentException();
if (ks.getContactId() != null) throw new IllegalArgumentException();
MutableTransportKeys m = ks.getTransportKeys();
addKeys(k, c, m);
db.bindTransportKeys(txn, c, m.getTransportId(), k);
} finally {
lock.unlock();
}
}
@Override
public void removeContact(ContactId c) {
lock.lock();
try {
// Remove mutable state for the contact
Iterator<Entry<Bytes, TagContext>> inContextsIter =
inContexts.entrySet().iterator();
while (inContextsIter.hasNext()) {
ContactId c1 = inContextsIter.next().getValue().contactId;
if (c1.equals(c)) inContextsIter.remove();
}
Iterator<TagContext> it = inContexts.values().iterator();
while (it.hasNext()) if (it.next().contactId.equals(c)) it.remove();
outContexts.remove(c);
Iterator<MutableKeySet> keysIter = keys.iterator();
while (keysIter.hasNext()) {
ContactId c1 = keysIter.next().getContactId();
if (c1 != null && c1.equals(c)) keysIter.remove();
Iterator<MutableKeySet> it1 = keys.values().iterator();
while (it1.hasNext()) {
ContactId c1 = it1.next().getContactId();
if (c1 != null && c1.equals(c)) it1.remove();
}
} finally {
lock.unlock();
@@ -300,7 +311,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
try {
// Rotate the keys to the current rotation period
Collection<KeySet> snapshot = new ArrayList<>(keys.size());
for (MutableKeySet ks : keys) {
for (MutableKeySet ks : keys.values()) {
snapshot.add(new KeySet(ks.getKeySetId(), ks.getContactId(),
ks.getTransportKeys().snapshot()));
}