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

@@ -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 {