Derive handshake root key when converting pending contact.

This commit is contained in:
akwizgran
2019-05-30 17:21:46 +01:00
parent 4a2936c685
commit 430b530ca5
11 changed files with 125 additions and 122 deletions

View File

@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.security.GeneralSecurityException;
import java.util.Collection;
import javax.annotation.Nullable;
@@ -44,10 +45,13 @@ public interface ContactManager {
* for each transport, and returns an ID for the contact.
*
* @param alice True if the local party is Alice
* @throws GeneralSecurityException If the pending contact's handshake
* public key is invalid
*/
ContactId addContact(Transaction txn, PendingContactId p, Author remote,
AuthorId local, SecretKey rootKey, long timestamp, boolean alice,
boolean verified, boolean active) throws DbException;
boolean verified, boolean active)
throws DbException, GeneralSecurityException;
/**
* Stores a contact associated with the given local and remote pseudonyms
@@ -83,9 +87,11 @@ public interface ContactManager {
* @throws UnsupportedVersionException If the link uses a format version
* that is not supported
* @throws FormatException If the link is invalid
* @throws GeneralSecurityException If the pending contact's handshake
* public key is invalid
*/
PendingContact addPendingContact(String link, String alias)
throws DbException, FormatException;
throws DbException, FormatException, GeneralSecurityException;
/**
* Returns the pending contact with the given ID.

View File

@@ -1,9 +1,9 @@
package org.briarproject.bramble.api.transport;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId;
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.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
@@ -21,9 +21,9 @@ import javax.annotation.Nullable;
public interface KeyManager {
/**
* Informs the key manager that a new contact has been added. Derives and
* stores a set of rotation mode transport keys for communicating with the
* contact over each transport and returns the key set IDs.
* Derives and stores a set of rotation mode transport keys for
* communicating with the given contact over each transport and returns the
* key set IDs.
* <p/>
* {@link StreamContext StreamContexts} for the contact can be created
* after this method has returned.
@@ -31,7 +31,7 @@ public interface KeyManager {
* @param alice True if the local party is Alice
* @param active Whether the derived keys can be used for outgoing streams
*/
Map<TransportId, KeySetId> addContactWithRotationKeys(Transaction txn,
Map<TransportId, KeySetId> addRotationKeys(Transaction txn,
ContactId c, SecretKey rootKey, long timestamp, boolean alice,
boolean active) throws DbException;
@@ -42,11 +42,10 @@ public interface KeyManager {
* <p/>
* {@link StreamContext StreamContexts} for the contact can be created
* after this method has returned.
*
* @param alice True if the local party is Alice
*/
Map<TransportId, KeySetId> addContactWithHandshakeKeys(Transaction txn,
ContactId c, SecretKey rootKey, boolean alice) throws DbException;
Map<TransportId, KeySetId> addContact(Transaction txn, ContactId c,
PublicKey theirPublicKey, KeyPair ourKeyPair)
throws DbException, GeneralSecurityException;
/**
* Informs the key manager that a new pending contact has been added.
@@ -58,7 +57,7 @@ public interface KeyManager {
* created after this method has returned.
*/
Map<TransportId, KeySetId> addPendingContact(Transaction txn,
PendingContact p, KeyPair ourKeyPair)
PendingContactId p, PublicKey theirPublicKey, KeyPair ourKeyPair)
throws DbException, GeneralSecurityException;
/**

View File

@@ -78,8 +78,7 @@ class ContactManagerImpl implements ContactManager {
SecretKey rootKey, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException {
ContactId c = db.addContact(txn, remote, local, null, verified);
keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp,
alice, active);
keyManager.addRotationKeys(txn, c, rootKey, timestamp, alice, active);
Contact contact = db.getContact(txn, c);
for (ContactHook hook : hooks) hook.addingContact(txn, contact);
return c;
@@ -89,12 +88,14 @@ class ContactManagerImpl implements ContactManager {
public ContactId addContact(Transaction txn, PendingContactId p,
Author remote, AuthorId local, SecretKey rootKey, long timestamp,
boolean alice, boolean verified, boolean active)
throws DbException {
PublicKey handshake = db.getPendingContact(txn, p).getPublicKey();
throws DbException, GeneralSecurityException {
PublicKey theirPublicKey = db.getPendingContact(txn, p).getPublicKey();
db.removePendingContact(txn, p);
ContactId c = db.addContact(txn, remote, local, handshake, verified);
keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp,
alice, active);
ContactId c =
db.addContact(txn, remote, local, theirPublicKey, verified);
KeyPair ourKeyPair = identityManager.getHandshakeKeys(txn);
keyManager.addContact(txn, c, theirPublicKey, ourKeyPair);
keyManager.addRotationKeys(txn, c, rootKey, timestamp, alice, active);
Contact contact = db.getContact(txn, c);
for (ContactHook hook : hooks) hook.addingContact(txn, contact);
return c;
@@ -126,18 +127,19 @@ class ContactManagerImpl implements ContactManager {
@Override
public PendingContact addPendingContact(String link, String alias)
throws DbException, FormatException {
throws DbException, FormatException, GeneralSecurityException {
PendingContact p =
pendingContactFactory.createPendingContact(link, alias);
db.transaction(false, txn -> {
Transaction txn = db.startTransaction(false);
try {
db.addPendingContact(txn, p);
KeyPair ourKeyPair = identityManager.getHandshakeKeys(txn);
try {
keyManager.addPendingContact(txn, p, ourKeyPair);
} catch (GeneralSecurityException e) {
throw new AssertionError();
}
});
keyManager.addPendingContact(txn, p.getId(), p.getPublicKey(),
ourKeyPair);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return p;
}

View File

@@ -1,11 +1,11 @@
package org.briarproject.bramble.transport;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
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.TransportCrypto;
import org.briarproject.bramble.api.db.DatabaseComponent;
@@ -101,46 +101,51 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
}
@Override
public Map<TransportId, KeySetId> addContactWithRotationKeys(
public Map<TransportId, KeySetId> addRotationKeys(
Transaction txn, ContactId c, SecretKey rootKey, long timestamp,
boolean alice, boolean active) throws DbException {
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.addContactWithRotationKeys(txn, c, rootKey, timestamp,
ids.put(t, m.addRotationKeys(txn, c, rootKey, timestamp,
alice, active));
}
return ids;
}
@Override
public Map<TransportId, KeySetId> addContactWithHandshakeKeys(
Transaction txn, ContactId c, SecretKey rootKey, boolean alice)
throws DbException {
public Map<TransportId, KeySetId> addContact(Transaction txn, ContactId c,
PublicKey theirPublicKey, KeyPair ourKeyPair)
throws DbException, GeneralSecurityException {
SecretKey staticMasterKey = transportCrypto
.deriveStaticMasterKey(theirPublicKey, ourKeyPair);
SecretKey rootKey =
transportCrypto.deriveHandshakeRootKey(staticMasterKey, true);
boolean alice = transportCrypto.isAlice(theirPublicKey, ourKeyPair);
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.addContactWithHandshakeKeys(txn, c, rootKey, alice));
ids.put(t, m.addHandshakeKeys(txn, c, rootKey, alice));
}
return ids;
}
@Override
public Map<TransportId, KeySetId> addPendingContact(Transaction txn,
PendingContact p, KeyPair ourKeyPair)
PendingContactId p, PublicKey theirPublicKey, KeyPair ourKeyPair)
throws DbException, GeneralSecurityException {
SecretKey staticMasterKey = transportCrypto
.deriveStaticMasterKey(p.getPublicKey(), ourKeyPair);
.deriveStaticMasterKey(theirPublicKey, ourKeyPair);
SecretKey rootKey =
transportCrypto.deriveHandshakeRootKey(staticMasterKey, true);
boolean alice = transportCrypto.isAlice(p.getPublicKey(), ourKeyPair);
boolean alice = transportCrypto.isAlice(theirPublicKey, ourKeyPair);
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.addPendingContact(txn, p.getId(), rootKey, alice));
ids.put(t, m.addHandshakeKeys(txn, p, rootKey, alice));
}
return ids;
}

View File

@@ -16,14 +16,14 @@ interface TransportKeyManager {
void start(Transaction txn) throws DbException;
KeySetId addContactWithRotationKeys(Transaction txn, ContactId c,
KeySetId addRotationKeys(Transaction txn, ContactId c,
SecretKey rootKey, long timestamp, boolean alice, boolean active)
throws DbException;
KeySetId addContactWithHandshakeKeys(Transaction txn, ContactId c,
KeySetId addHandshakeKeys(Transaction txn, ContactId c,
SecretKey rootKey, boolean alice) throws DbException;
KeySetId addPendingContact(Transaction txn, PendingContactId p,
KeySetId addHandshakeKeys(Transaction txn, PendingContactId p,
SecretKey rootKey, boolean alice) throws DbException;
void activateKeys(Transaction txn, KeySetId k) throws DbException;

View File

@@ -115,11 +115,14 @@ class TransportKeyManagerImpl implements TransportKeyManager {
TransportKeys k = ks.getKeys();
TransportKeys k1 = transportCrypto.updateTransportKeys(k,
timePeriod);
TransportKeySet ks1 = new TransportKeySet(ks.getKeySetId(),
ks.getContactId(), null, k1);
if (k1.getTimePeriod() > k.getTimePeriod())
if (k1.getTimePeriod() > k.getTimePeriod()) {
TransportKeySet ks1 = new TransportKeySet(ks.getKeySetId(),
ks.getContactId(), ks.getPendingContactId(), k1);
updateResult.updated.add(ks1);
updateResult.current.add(ks1);
updateResult.current.add(ks1);
} else {
updateResult.current.add(ks);
}
}
return updateResult;
}
@@ -207,7 +210,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
}
@Override
public KeySetId addContactWithRotationKeys(Transaction txn, ContactId c,
public KeySetId addRotationKeys(Transaction txn, ContactId c,
SecretKey rootKey, long timestamp, boolean alice, boolean active)
throws DbException {
lock.lock();
@@ -222,7 +225,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
k = transportCrypto.updateTransportKeys(k, timePeriod);
// Write the keys back to the DB
KeySetId keySetId = db.addTransportKeys(txn, c, k);
// Initialise mutable state for the contact
// Initialise mutable state for the keys
addKeys(keySetId, c, null, new MutableTransportKeys(k));
return keySetId;
} finally {
@@ -231,7 +234,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
}
@Override
public KeySetId addContactWithHandshakeKeys(Transaction txn, ContactId c,
public KeySetId addHandshakeKeys(Transaction txn, ContactId c,
SecretKey rootKey, boolean alice) throws DbException {
lock.lock();
try {
@@ -242,7 +245,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
rootKey, timePeriod, alice);
// Write the keys back to the DB
KeySetId keySetId = db.addTransportKeys(txn, c, k);
// Initialise mutable state for the contact
// Initialise mutable state for the keys
addKeys(keySetId, c, null, new MutableTransportKeys(k));
return keySetId;
} finally {
@@ -251,7 +254,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
}
@Override
public KeySetId addPendingContact(Transaction txn, PendingContactId p,
public KeySetId addHandshakeKeys(Transaction txn, PendingContactId p,
SecretKey rootKey, boolean alice) throws DbException {
lock.lock();
try {
@@ -262,7 +265,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
rootKey, timePeriod, alice);
// Write the keys back to the DB
KeySetId keySetId = db.addTransportKeys(txn, p, k);
// Initialise mutable state for the pending contact
// Initialise mutable state for the keys
addKeys(keySetId, null, p, new MutableTransportKeys(k));
return keySetId;
} finally {

View File

@@ -73,8 +73,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
oneOf(db).transactionWithResult(with(false), withDbCallable(txn));
oneOf(db).addContact(txn, remote, local, null, verified);
will(returnValue(contactId));
oneOf(keyManager).addContactWithRotationKeys(txn, contactId,
rootKey, timestamp, alice, active);
oneOf(keyManager).addRotationKeys(txn, contactId, rootKey,
timestamp, alice, active);
oneOf(db).getContact(txn, contactId);
will(returnValue(contact));
}});

View File

@@ -1,10 +1,10 @@
package org.briarproject.bramble.transport;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
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.TransportCrypto;
import org.briarproject.bramble.api.db.DatabaseComponent;
@@ -31,8 +31,8 @@ import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENG
import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getContactId;
import static org.briarproject.bramble.test.TestUtils.getPendingContact;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTransportId;
import static org.junit.Assert.assertEquals;
@@ -52,8 +52,8 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
private final DeterministicExecutor executor = new DeterministicExecutor();
private final Transaction txn = new Transaction(null, false);
private final ContactId contactId = getContactId();
private final PendingContact pendingContact = getPendingContact();
private final PendingContactId pendingContactId = pendingContact.getId();
private final PendingContactId pendingContactId =
new PendingContactId(getRandomId());
private final KeySetId keySetId = new KeySetId(345);
private final TransportId transportId = getTransportId();
private final TransportId unknownTransportId = getTransportId();
@@ -64,6 +64,11 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
new StreamContext(null, pendingContactId, transportId,
getSecretKey(), getSecretKey(), 1, true);
private final byte[] tag = getRandomBytes(TAG_LENGTH);
private final PublicKey theirPublicKey = getAgreementPublicKey();
private final KeyPair ourKeyPair =
new KeyPair(getAgreementPublicKey(), getAgreementPrivateKey());
private final SecretKey staticMasterKey = getSecretKey();
private final SecretKey rootKey = getSecretKey();
private final Random random = new Random();
private final KeyManagerImpl keyManager = new KeyManagerImpl(db, executor,
@@ -105,57 +110,59 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
boolean active = random.nextBoolean();
context.checking(new Expectations() {{
oneOf(transportKeyManager).addContactWithRotationKeys(txn,
oneOf(transportKeyManager).addRotationKeys(txn,
contactId, secretKey, timestamp, alice, active);
will(returnValue(keySetId));
}});
Map<TransportId, KeySetId> ids = keyManager.addContactWithRotationKeys(
Map<TransportId, KeySetId> ids = keyManager.addRotationKeys(
txn, contactId, secretKey, timestamp, alice, active);
assertEquals(singletonMap(transportId, keySetId), ids);
}
@Test
public void testAddContactWithHandshakeModeKeys() throws Exception {
SecretKey secretKey = getSecretKey();
public void testAddContactWithHandshakePublicKey() throws Exception {
boolean alice = random.nextBoolean();
context.checking(new Expectations() {{
oneOf(transportKeyManager).addContactWithHandshakeKeys(
txn, contactId, secretKey, alice);
oneOf(transportCrypto)
.deriveStaticMasterKey(theirPublicKey, ourKeyPair);
will(returnValue(staticMasterKey));
oneOf(transportCrypto)
.deriveHandshakeRootKey(staticMasterKey, false);
will(returnValue(rootKey));
oneOf(transportCrypto).isAlice(theirPublicKey, ourKeyPair);
will(returnValue(alice));
oneOf(transportKeyManager).addHandshakeKeys(txn, contactId,
rootKey, alice);
will(returnValue(keySetId));
}});
Map<TransportId, KeySetId> ids = keyManager.addContactWithHandshakeKeys(
txn, contactId, secretKey, alice);
Map<TransportId, KeySetId> ids = keyManager.addContact(txn, contactId,
theirPublicKey, ourKeyPair);
assertEquals(singletonMap(transportId, keySetId), ids);
}
@Test
public void testAddPendingContact() throws Exception {
KeyPair ourKeyPair =
new KeyPair(getAgreementPublicKey(), getAgreementPrivateKey());
SecretKey staticMasterKey = getSecretKey();
SecretKey rootKey = getSecretKey();
boolean alice = random.nextBoolean();
context.checking(new Expectations() {{
oneOf(transportCrypto).deriveStaticMasterKey(
pendingContact.getPublicKey(), ourKeyPair);
oneOf(transportCrypto)
.deriveStaticMasterKey(theirPublicKey, ourKeyPair);
will(returnValue(staticMasterKey));
oneOf(transportCrypto)
.deriveHandshakeRootKey(staticMasterKey, true);
will(returnValue(rootKey));
oneOf(transportCrypto).isAlice(pendingContact.getPublicKey(),
ourKeyPair);
oneOf(transportCrypto).isAlice(theirPublicKey, ourKeyPair);
will(returnValue(alice));
oneOf(transportKeyManager).addPendingContact(txn, pendingContactId,
oneOf(transportKeyManager).addHandshakeKeys(txn, pendingContactId,
rootKey, alice);
will(returnValue(keySetId));
}});
Map<TransportId, KeySetId> ids = keyManager.addPendingContact(txn,
pendingContact, ourKeyPair);
pendingContactId, theirPublicKey, ourKeyPair);
assertEquals(singletonMap(transportId, keySetId), ids);
}

View File

@@ -21,6 +21,7 @@ import org.hamcrest.Description;
import org.jmock.Expectations;
import org.jmock.api.Action;
import org.jmock.api.Invocation;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
@@ -72,6 +73,14 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
private final SecretKey rootKey = getSecretKey();
private final Random random = new Random();
private TransportKeyManager transportKeyManager;
@Before
public void setUp() {
transportKeyManager = new TransportKeyManagerImpl(db, transportCrypto,
dbExecutor, scheduler, clock, transportId, maxLatency);
}
@Test
public void testKeysAreUpdatedAtStartup() throws Exception {
boolean active = random.nextBoolean();
@@ -112,16 +121,13 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
with(timePeriodLength - 1), with(MILLISECONDS));
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
transportKeyManager.start(txn);
assertEquals(active,
transportKeyManager.canSendOutgoingStreams(contactId));
}
@Test
public void testRotationKeysAreDerivedAndUpdatedWhenAddingContact()
public void testRotationKeysForContactAreDerivedAndUpdatedWhenAdded()
throws Exception {
boolean alice = random.nextBoolean();
boolean active = random.nextBoolean();
@@ -156,14 +162,14 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
maxLatency);
// The timestamp is 1 ms before the start of time period 1000
long timestamp = timePeriodLength * 1000 - 1;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
txn, contactId, rootKey, timestamp, alice, active));
assertEquals(keySetId, transportKeyManager.addRotationKeys(txn,
contactId, rootKey, timestamp, alice, active));
assertEquals(active,
transportKeyManager.canSendOutgoingStreams(contactId));
}
@Test
public void testHandshakeKeysAreDerivedWhenAddingContact()
public void testHandshakeKeysForContactAreDerivedWhenAdded()
throws Exception {
boolean alice = random.nextBoolean();
TransportKeys transportKeys = createHandshakeKeys(1000, 0, alice);
@@ -189,16 +195,13 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
will(returnValue(keySetId));
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
assertEquals(keySetId, transportKeyManager.addContactWithHandshakeKeys(
txn, contactId, rootKey, alice));
assertEquals(keySetId, transportKeyManager.addHandshakeKeys(txn,
contactId, rootKey, alice));
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
}
@Test
public void testHandshakeKeysAreDerivedWhenAddingPendingContact()
public void testHandshakeKeysForPendingContactAreDerivedWhenAdded()
throws Exception {
boolean alice = random.nextBoolean();
TransportKeys transportKeys = createHandshakeKeys(1000, 0, alice);
@@ -224,10 +227,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
will(returnValue(keySetId));
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
assertEquals(keySetId, transportKeyManager.addPendingContact(txn,
assertEquals(keySetId, transportKeyManager.addHandshakeKeys(txn,
pendingContactId, rootKey, alice));
assertTrue(transportKeyManager.canSendOutgoingStreams(
pendingContactId));
@@ -269,12 +269,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
expectAddContactKeysNotUpdated(alice, true, transportKeys, txn);
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
// The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
assertEquals(keySetId, transportKeyManager.addRotationKeys(
txn, contactId, rootKey, timestamp, alice, true));
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
assertNull(transportKeyManager.getStreamContext(txn, contactId));
@@ -295,12 +292,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(db).incrementStreamCounter(txn, transportId, keySetId);
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
// The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
assertEquals(keySetId, transportKeyManager.addRotationKeys(
txn, contactId, rootKey, timestamp, alice, true));
// The first request should return a stream context
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
@@ -327,12 +321,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
expectAddContactKeysNotUpdated(alice, active, transportKeys, txn);
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
// The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
assertEquals(keySetId, transportKeyManager.addRotationKeys(
txn, contactId, rootKey, timestamp, alice, active));
assertEquals(active,
transportKeyManager.canSendOutgoingStreams(contactId));
@@ -380,12 +371,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
1, new byte[REORDERING_WINDOW_SIZE / 8]);
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
// The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
assertEquals(keySetId, transportKeyManager.addRotationKeys(
txn, contactId, rootKey, timestamp, alice, true));
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
// Use the first tag (previous time period, stream number 0)
@@ -461,9 +449,6 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
with(timePeriodLength), with(MILLISECONDS));
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
transportKeyManager.start(txn);
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
}
@@ -483,12 +468,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(db).incrementStreamCounter(txn, transportId, keySetId);
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
// The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
assertEquals(keySetId, transportKeyManager.addRotationKeys(
txn, contactId, rootKey, timestamp, alice, false));
// The keys are inactive so no stream context should be returned
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
@@ -549,12 +531,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(db).incrementStreamCounter(txn, transportId, keySetId);
}});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency);
// The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContactWithRotationKeys(
assertEquals(keySetId, transportKeyManager.addRotationKeys(
txn, contactId, rootKey, timestamp, alice, false));
// The keys are inactive so no stream context should be returned
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));

View File

@@ -16,6 +16,7 @@ import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.LiveResult;
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
import java.security.GeneralSecurityException;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
@@ -102,14 +103,15 @@ public class AddContactViewModel extends AndroidViewModel {
} catch (UnsupportedVersionException e) {
logException(LOG, WARNING, e);
addContactResult.postValue(new LiveResult<>(e));
} catch (DbException | FormatException e) {
} catch (DbException | FormatException
| GeneralSecurityException e) {
logException(LOG, WARNING, e);
addContactResult.postValue(new LiveResult<>(e));
}
});
}
public LiveData<LiveResult<Boolean>> getAddContactResult() {
LiveData<LiveResult<Boolean>> getAddContactResult() {
return addContactResult;
}

View File

@@ -444,7 +444,7 @@ class IntroduceeProtocolEngine
// add the keys to the new contact
//noinspection ConstantConditions
keys = keyManager.addContactWithRotationKeys(txn, c.getId(),
keys = keyManager.addRotationKeys(txn, c.getId(),
new SecretKey(s.getMasterKey()), timestamp,
s.getLocal().alice, false);