Fix master secret/master key/root key terminology.

In the key agreement, contact exchange and introduction protocols we
refer to the master key. In the transport protocol we refer to the root
key. When adding a contact in person, the key agreement protocol's
master key is used as the transport root key. When a contact is
introduced, the introduction protocol's master key is used as the
transport root key.
This commit is contained in:
akwizgran
2019-04-10 14:30:01 +01:00
parent d4b929fc6c
commit d5ac2c9ead
20 changed files with 103 additions and 105 deletions

View File

@@ -18,30 +18,30 @@ public interface ContactExchangeTask {
byte PROTOCOL_VERSION = 1; byte PROTOCOL_VERSION = 1;
/** /**
* Label for deriving Alice's header key from the master secret. * Label for deriving Alice's header key from the master key.
*/ */
String ALICE_KEY_LABEL = String ALICE_KEY_LABEL =
"org.briarproject.bramble.contact/ALICE_HEADER_KEY"; "org.briarproject.bramble.contact/ALICE_HEADER_KEY";
/** /**
* Label for deriving Bob's header key from the master secret. * Label for deriving Bob's header key from the master key.
*/ */
String BOB_KEY_LABEL = "org.briarproject.bramble.contact/BOB_HEADER_KEY"; String BOB_KEY_LABEL = "org.briarproject.bramble.contact/BOB_HEADER_KEY";
/** /**
* Label for deriving Alice's key binding nonce from the master secret. * Label for deriving Alice's key binding nonce from the master key.
*/ */
String ALICE_NONCE_LABEL = "org.briarproject.bramble.contact/ALICE_NONCE"; String ALICE_NONCE_LABEL = "org.briarproject.bramble.contact/ALICE_NONCE";
/** /**
* Label for deriving Bob's key binding nonce from the master secret. * Label for deriving Bob's key binding nonce from the master key.
*/ */
String BOB_NONCE_LABEL = "org.briarproject.bramble.contact/BOB_NONCE"; String BOB_NONCE_LABEL = "org.briarproject.bramble.contact/BOB_NONCE";
/** /**
* Exchanges contact information with a remote peer. * Exchanges contact information with a remote peer.
*/ */
void startExchange(LocalAuthor localAuthor, SecretKey masterSecret, void startExchange(LocalAuthor localAuthor, SecretKey masterKey,
DuplexTransportConnection conn, TransportId transportId, DuplexTransportConnection conn, TransportId transportId,
boolean alice); boolean alice);
} }

View File

@@ -13,8 +13,6 @@ import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.FAILED;
@NotNullByDefault @NotNullByDefault
public interface ContactManager { public interface ContactManager {
@@ -33,7 +31,7 @@ public interface ContactManager {
* @param alice true if the local party is Alice * @param alice true if the local party is Alice
*/ */
ContactId addContact(Transaction txn, Author remote, AuthorId local, ContactId addContact(Transaction txn, Author remote, AuthorId local,
SecretKey master, long timestamp, boolean alice, boolean verified, SecretKey rootKey, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException; boolean active) throws DbException;
/** /**
@@ -50,7 +48,7 @@ public interface ContactManager {
* *
* @param alice true if the local party is Alice * @param alice true if the local party is Alice
*/ */
ContactId addContact(Author remote, AuthorId local, SecretKey master, ContactId addContact(Author remote, AuthorId local, SecretKey rootKey,
long timestamp, boolean alice, boolean verified, boolean active) long timestamp, boolean alice, boolean verified, boolean active)
throws DbException; throws DbException;

View File

@@ -12,12 +12,12 @@ public interface TransportCrypto {
/** /**
* Derives initial transport keys for the given transport in the given * Derives initial transport keys for the given transport in the given
* time period from the given master secret. * time period from the given root key.
* *
* @param alice whether the keys are for use by Alice or Bob. * @param alice whether the keys are for use by Alice or Bob.
* @param active whether the keys are usable for outgoing streams. * @param active whether the keys are usable for outgoing streams.
*/ */
TransportKeys deriveTransportKeys(TransportId t, SecretKey master, TransportKeys deriveTransportKeys(TransportId t, SecretKey rootKey,
long timePeriod, boolean alice, boolean active); long timePeriod, boolean alice, boolean active);
/** /**

View File

@@ -40,8 +40,8 @@ public interface KeyAgreementConstants {
"org.briarproject.bramble.keyagreement/SHARED_SECRET"; "org.briarproject.bramble.keyagreement/SHARED_SECRET";
/** /**
* Label for deriving the master secret. * Label for deriving the master key.
*/ */
String MASTER_SECRET_LABEL = String MASTER_KEY_LABEL =
"org.briarproject.bramble.keyagreement/MASTER_SECRET"; "org.briarproject.bramble.keyagreement/MASTER_SECRET";
} }

View File

@@ -28,7 +28,7 @@ public interface KeyManager {
* @param active whether the derived keys can be used for outgoing streams * @param active whether the derived keys can be used for outgoing streams
*/ */
Map<TransportId, KeySetId> addContact(Transaction txn, ContactId c, Map<TransportId, KeySetId> addContact(Transaction txn, ContactId c,
SecretKey master, long timestamp, boolean alice, boolean active) SecretKey rootKey, long timestamp, boolean alice, boolean active)
throws DbException; throws DbException;
/** /**

View File

@@ -82,23 +82,23 @@ public interface TransportConstants {
int REORDERING_WINDOW_SIZE = 32; int REORDERING_WINDOW_SIZE = 32;
/** /**
* Label for deriving Alice's initial tag key from the master secret. * Label for deriving Alice's initial tag key from the root key.
*/ */
String ALICE_TAG_LABEL = "org.briarproject.bramble.transport/ALICE_TAG_KEY"; String ALICE_TAG_LABEL = "org.briarproject.bramble.transport/ALICE_TAG_KEY";
/** /**
* Label for deriving Bob's initial tag key from the master secret. * Label for deriving Bob's initial tag key from the root key.
*/ */
String BOB_TAG_LABEL = "org.briarproject.bramble.transport/BOB_TAG_KEY"; String BOB_TAG_LABEL = "org.briarproject.bramble.transport/BOB_TAG_KEY";
/** /**
* Label for deriving Alice's initial header key from the master secret. * Label for deriving Alice's initial header key from the root key.
*/ */
String ALICE_HEADER_LABEL = String ALICE_HEADER_LABEL =
"org.briarproject.bramble.transport/ALICE_HEADER_KEY"; "org.briarproject.bramble.transport/ALICE_HEADER_KEY";
/** /**
* Label for deriving Bob's initial header key from the master secret. * Label for deriving Bob's initial header key from the root key.
*/ */
String BOB_HEADER_LABEL = String BOB_HEADER_LABEL =
"org.briarproject.bramble.transport/BOB_HEADER_KEY"; "org.briarproject.bramble.transport/BOB_HEADER_KEY";

View File

@@ -77,7 +77,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
private volatile LocalAuthor localAuthor; private volatile LocalAuthor localAuthor;
private volatile DuplexTransportConnection conn; private volatile DuplexTransportConnection conn;
private volatile TransportId transportId; private volatile TransportId transportId;
private volatile SecretKey masterSecret; private volatile SecretKey masterKey;
private volatile boolean alice; private volatile boolean alice;
@Inject @Inject
@@ -104,13 +104,13 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
} }
@Override @Override
public void startExchange(LocalAuthor localAuthor, SecretKey masterSecret, public void startExchange(LocalAuthor localAuthor, SecretKey masterKey,
DuplexTransportConnection conn, TransportId transportId, DuplexTransportConnection conn, TransportId transportId,
boolean alice) { boolean alice) {
this.localAuthor = localAuthor; this.localAuthor = localAuthor;
this.conn = conn; this.conn = conn;
this.transportId = transportId; this.transportId = transportId;
this.masterSecret = masterSecret; this.masterKey = masterKey;
this.alice = alice; this.alice = alice;
start(); start();
} }
@@ -142,9 +142,9 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
} }
// Derive the header keys for the transport streams // Derive the header keys for the transport streams
SecretKey aliceHeaderKey = crypto.deriveKey(ALICE_KEY_LABEL, SecretKey aliceHeaderKey = crypto.deriveKey(ALICE_KEY_LABEL, masterKey,
masterSecret, new byte[] {PROTOCOL_VERSION}); new byte[] {PROTOCOL_VERSION});
SecretKey bobHeaderKey = crypto.deriveKey(BOB_KEY_LABEL, masterSecret, SecretKey bobHeaderKey = crypto.deriveKey(BOB_KEY_LABEL, masterKey,
new byte[] {PROTOCOL_VERSION}); new byte[] {PROTOCOL_VERSION});
// Create the readers // Create the readers
@@ -163,9 +163,9 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
.createRecordWriter(streamWriter.getOutputStream()); .createRecordWriter(streamWriter.getOutputStream());
// Derive the nonces to be signed // Derive the nonces to be signed
byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret, byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterKey,
new byte[] {PROTOCOL_VERSION}); new byte[] {PROTOCOL_VERSION});
byte[] bobNonce = crypto.mac(BOB_NONCE_LABEL, masterSecret, byte[] bobNonce = crypto.mac(BOB_NONCE_LABEL, masterKey,
new byte[] {PROTOCOL_VERSION}); new byte[] {PROTOCOL_VERSION});
byte[] localNonce = alice ? aliceNonce : bobNonce; byte[] localNonce = alice ? aliceNonce : bobNonce;
byte[] remoteNonce = alice ? bobNonce : aliceNonce; byte[] remoteNonce = alice ? bobNonce : aliceNonce;
@@ -293,7 +293,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
throws DbException { throws DbException {
return db.transactionWithResult(false, txn -> { return db.transactionWithResult(false, txn -> {
ContactId contactId = contactManager.addContact(txn, remoteAuthor, ContactId contactId = contactManager.addContact(txn, remoteAuthor,
localAuthor.getId(), masterSecret, timestamp, alice, localAuthor.getId(), masterKey, timestamp, alice,
true, true); true, true);
transportPropertyManager.addRemoteProperties(txn, contactId, transportPropertyManager.addRemoteProperties(txn, contactId,
remoteProperties); remoteProperties);

View File

@@ -69,10 +69,10 @@ class ContactManagerImpl implements ContactManager {
@Override @Override
public ContactId addContact(Transaction txn, Author remote, AuthorId local, public ContactId addContact(Transaction txn, Author remote, AuthorId local,
SecretKey master, 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, active); ContactId c = db.addContact(txn, remote, local, verified, active);
keyManager.addContact(txn, c, master, timestamp, alice, active); keyManager.addContact(txn, c, rootKey, timestamp, alice, active);
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;
@@ -88,11 +88,11 @@ class ContactManagerImpl implements ContactManager {
} }
@Override @Override
public ContactId addContact(Author remote, AuthorId local, SecretKey master, public ContactId addContact(Author remote, AuthorId local,
long timestamp, boolean alice, boolean verified, boolean active) SecretKey rootKey, long timestamp, boolean alice, boolean verified,
throws DbException { boolean active) throws DbException {
return db.transactionWithResult(false, txn -> return db.transactionWithResult(false, txn ->
addContact(txn, remote, local, master, timestamp, alice, addContact(txn, remote, local, rootKey, timestamp, alice,
verified, active)); verified, active));
} }

View File

@@ -43,12 +43,12 @@ class TransportCryptoImpl implements TransportCrypto {
@Override @Override
public TransportKeys deriveTransportKeys(TransportId t, public TransportKeys deriveTransportKeys(TransportId t,
SecretKey master, long timePeriod, boolean alice, boolean active) { SecretKey rootKey, long timePeriod, boolean alice, boolean active) {
// Keys for the previous period are derived from the master secret // Keys for the previous period are derived from the root key
SecretKey inTagPrev = deriveTagKey(master, t, !alice); SecretKey inTagPrev = deriveTagKey(rootKey, t, !alice);
SecretKey inHeaderPrev = deriveHeaderKey(master, t, !alice); SecretKey inHeaderPrev = deriveHeaderKey(rootKey, t, !alice);
SecretKey outTagPrev = deriveTagKey(master, t, alice); SecretKey outTagPrev = deriveTagKey(rootKey, t, alice);
SecretKey outHeaderPrev = deriveHeaderKey(master, t, alice); SecretKey outHeaderPrev = deriveHeaderKey(rootKey, t, alice);
// Derive the keys for the current and next periods // Derive the keys for the current and next periods
SecretKey inTagCurr = rotateKey(inTagPrev, timePeriod); SecretKey inTagCurr = rotateKey(inTagPrev, timePeriod);
SecretKey inHeaderCurr = rotateKey(inHeaderPrev, timePeriod); SecretKey inHeaderCurr = rotateKey(inHeaderPrev, timePeriod);
@@ -70,8 +70,7 @@ class TransportCryptoImpl implements TransportCrypto {
} }
@Override @Override
public TransportKeys rotateTransportKeys(TransportKeys k, public TransportKeys rotateTransportKeys(TransportKeys k, long timePeriod) {
long timePeriod) {
if (k.getTimePeriod() >= timePeriod) return k; if (k.getTimePeriod() >= timePeriod) return k;
IncomingKeys inPrev = k.getPreviousIncomingKeys(); IncomingKeys inPrev = k.getPreviousIncomingKeys();
IncomingKeys inCurr = k.getCurrentIncomingKeys(); IncomingKeys inCurr = k.getCurrentIncomingKeys();
@@ -101,18 +100,18 @@ class TransportCryptoImpl implements TransportCrypto {
return crypto.deriveKey(ROTATE_LABEL, k, period); return crypto.deriveKey(ROTATE_LABEL, k, period);
} }
private SecretKey deriveTagKey(SecretKey master, TransportId t, private SecretKey deriveTagKey(SecretKey rootKey, TransportId t,
boolean alice) { boolean alice) {
String label = alice ? ALICE_TAG_LABEL : BOB_TAG_LABEL; String label = alice ? ALICE_TAG_LABEL : BOB_TAG_LABEL;
byte[] id = toUtf8(t.getString()); byte[] id = toUtf8(t.getString());
return crypto.deriveKey(label, master, id); return crypto.deriveKey(label, rootKey, id);
} }
private SecretKey deriveHeaderKey(SecretKey master, TransportId t, private SecretKey deriveHeaderKey(SecretKey rootKey, TransportId t,
boolean alice) { boolean alice) {
String label = alice ? ALICE_HEADER_LABEL : BOB_HEADER_LABEL; String label = alice ? ALICE_HEADER_LABEL : BOB_HEADER_LABEL;
byte[] id = toUtf8(t.getString()); byte[] id = toUtf8(t.getString());
return crypto.deriveKey(label, master, id); return crypto.deriveKey(label, rootKey, id);
} }
@Override @Override
@@ -146,23 +145,23 @@ class TransportCryptoImpl implements TransportCrypto {
return new OutgoingKeys(tag, header, timePeriod, true); return new OutgoingKeys(tag, header, timePeriod, true);
} }
private SecretKey deriveStaticTagKey(TransportId t, SecretKey root, private SecretKey deriveStaticTagKey(TransportId t, SecretKey rootKey,
boolean alice, long timePeriod) { boolean alice, long timePeriod) {
String label = alice ? ALICE_STATIC_TAG_LABEL : BOB_STATIC_TAG_LABEL; String label = alice ? ALICE_STATIC_TAG_LABEL : BOB_STATIC_TAG_LABEL;
byte[] id = toUtf8(t.getString()); byte[] id = toUtf8(t.getString());
byte[] period = new byte[INT_64_BYTES]; byte[] period = new byte[INT_64_BYTES];
writeUint64(timePeriod, period, 0); writeUint64(timePeriod, period, 0);
return crypto.deriveKey(label, root, id, period); return crypto.deriveKey(label, rootKey, id, period);
} }
private SecretKey deriveStaticHeaderKey(TransportId t, SecretKey root, private SecretKey deriveStaticHeaderKey(TransportId t, SecretKey rootKey,
boolean alice, long timePeriod) { boolean alice, long timePeriod) {
String label = String label =
alice ? ALICE_STATIC_HEADER_LABEL : BOB_STATIC_HEADER_LABEL; alice ? ALICE_STATIC_HEADER_LABEL : BOB_STATIC_HEADER_LABEL;
byte[] id = toUtf8(t.getString()); byte[] id = toUtf8(t.getString());
byte[] period = new byte[INT_64_BYTES]; byte[] period = new byte[INT_64_BYTES];
writeUint64(timePeriod, period, 0); writeUint64(timePeriod, period, 0);
return crypto.deriveKey(label, root, id, period); return crypto.deriveKey(label, rootKey, id, period);
} }
@Override @Override

View File

@@ -14,7 +14,7 @@ import java.io.IOException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Arrays; import java.util.Arrays;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.MASTER_SECRET_LABEL; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.MASTER_KEY_LABEL;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL;
@@ -90,7 +90,7 @@ class KeyAgreementProtocol {
/** /**
* Perform the BQP protocol. * Perform the BQP protocol.
* *
* @return the negotiated master secret. * @return the negotiated master key.
* @throws AbortException when the protocol may have been tampered with. * @throws AbortException when the protocol may have been tampered with.
* @throws IOException for all other other connection errors. * @throws IOException for all other other connection errors.
*/ */
@@ -115,7 +115,7 @@ class KeyAgreementProtocol {
receiveConfirm(s, theirPublicKey); receiveConfirm(s, theirPublicKey);
sendConfirm(s, theirPublicKey); sendConfirm(s, theirPublicKey);
} }
return crypto.deriveKey(MASTER_SECRET_LABEL, s); return crypto.deriveKey(MASTER_KEY_LABEL, s);
} catch (AbortException e) { } catch (AbortException e) {
sendAbort(e.getCause() != null); sendAbort(e.getCause() != null);
throw e; throw e;

View File

@@ -114,9 +114,9 @@ class KeyAgreementTaskImpl extends Thread implements KeyAgreementTask,
keyAgreementCrypto, payloadEncoder, transport, remotePayload, keyAgreementCrypto, payloadEncoder, transport, remotePayload,
localPayload, localKeyPair, alice); localPayload, localKeyPair, alice);
try { try {
SecretKey master = protocol.perform(); SecretKey masterKey = protocol.perform();
KeyAgreementResult result = KeyAgreementResult result =
new KeyAgreementResult(master, transport.getConnection(), new KeyAgreementResult(masterKey, transport.getConnection(),
transport.getTransportId(), alice); transport.getTransportId(), alice);
LOG.info("Finished BQP protocol"); LOG.info("Finished BQP protocol");
// Broadcast result to caller // Broadcast result to caller

View File

@@ -96,13 +96,13 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
@Override @Override
public Map<TransportId, KeySetId> addContact(Transaction txn, ContactId c, public Map<TransportId, KeySetId> addContact(Transaction txn, ContactId c,
SecretKey master, long timestamp, boolean alice, boolean active) SecretKey rootKey, long timestamp, boolean alice, boolean active)
throws DbException { throws DbException {
Map<TransportId, KeySetId> ids = new HashMap<>(); Map<TransportId, KeySetId> ids = new HashMap<>();
for (Entry<TransportId, TransportKeyManager> e : managers.entrySet()) { for (Entry<TransportId, TransportKeyManager> e : managers.entrySet()) {
TransportId t = e.getKey(); TransportId t = e.getKey();
TransportKeyManager m = e.getValue(); TransportKeyManager m = e.getValue();
ids.put(t, m.addContact(txn, c, master, timestamp, alice, active)); ids.put(t, m.addContact(txn, c, rootKey, timestamp, alice, active));
} }
return ids; return ids;
} }

View File

@@ -15,7 +15,7 @@ interface TransportKeyManager {
void start(Transaction txn) throws DbException; void start(Transaction txn) throws DbException;
KeySetId addContact(Transaction txn, ContactId c, SecretKey master, KeySetId addContact(Transaction txn, ContactId c, SecretKey rootKey,
long timestamp, boolean alice, boolean active) throws DbException; long timestamp, boolean alice, boolean active) throws DbException;
void activateKeys(Transaction txn, KeySetId k) throws DbException; void activateKeys(Transaction txn, KeySetId k) throws DbException;

View File

@@ -170,7 +170,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
} }
@Override @Override
public KeySetId addContact(Transaction txn, ContactId c, SecretKey master, public KeySetId addContact(Transaction txn, ContactId c, SecretKey rootKey,
long timestamp, boolean alice, boolean active) throws DbException { long timestamp, boolean alice, boolean active) throws DbException {
lock.lock(); lock.lock();
try { try {
@@ -178,7 +178,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
long timePeriod = timestamp / timePeriodLength; long timePeriod = timestamp / timePeriodLength;
// Derive the transport keys // Derive the transport keys
TransportKeys k = transportCrypto.deriveTransportKeys(transportId, TransportKeys k = transportCrypto.deriveTransportKeys(transportId,
master, timePeriod, alice, active); rootKey, timePeriod, alice, active);
// Rotate the keys to the current time period if necessary // Rotate the keys to the current time period if necessary
timePeriod = clock.currentTimeMillis() / timePeriodLength; timePeriod = clock.currentTimeMillis() / timePeriodLength;
k = transportCrypto.rotateTransportKeys(k, timePeriod); k = transportCrypto.rotateTransportKeys(k, timePeriod);

View File

@@ -64,7 +64,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testAddContact() throws Exception { public void testAddContact() throws Exception {
SecretKey master = getSecretKey(); SecretKey rootKey = getSecretKey();
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
boolean alice = new Random().nextBoolean(); boolean alice = new Random().nextBoolean();
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
@@ -73,14 +73,14 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
oneOf(db).transactionWithResult(with(false), withDbCallable(txn)); oneOf(db).transactionWithResult(with(false), withDbCallable(txn));
oneOf(db).addContact(txn, remote, local, verified, active); oneOf(db).addContact(txn, remote, local, verified, active);
will(returnValue(contactId)); will(returnValue(contactId));
oneOf(keyManager).addContact(txn, contactId, master, timestamp, oneOf(keyManager).addContact(txn, contactId, rootKey, timestamp,
alice, active); alice, active);
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
}}); }});
assertEquals(contactId, contactManager.addContact(remote, local, assertEquals(contactId, contactManager.addContact(remote, local,
master, timestamp, alice, verified, active)); rootKey, timestamp, alice, verified, active));
} }
@Test @Test

View File

@@ -30,12 +30,12 @@ public class KeyDerivationTest extends BrambleTestCase {
private final TransportCrypto transportCrypto = private final TransportCrypto transportCrypto =
new TransportCryptoImpl(crypto); new TransportCryptoImpl(crypto);
private final TransportId transportId = getTransportId(); private final TransportId transportId = getTransportId();
private final SecretKey master = getSecretKey(); private final SecretKey rootKey = getSecretKey();
@Test @Test
public void testKeysAreDistinct() { public void testKeysAreDistinct() {
TransportKeys k = transportCrypto.deriveTransportKeys(transportId, TransportKeys k = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); rootKey, 123, true, true);
assertAllDifferent(k); assertAllDifferent(k);
} }
@@ -43,9 +43,9 @@ public class KeyDerivationTest extends BrambleTestCase {
public void testCurrentKeysMatchCurrentKeysOfContact() { public void testCurrentKeysMatchCurrentKeysOfContact() {
// Start in time period 123 // Start in time period 123
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId, TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); rootKey, 123, true, true);
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId, TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
master, 123, false, true); rootKey, 123, false, true);
// Alice's incoming keys should equal Bob's outgoing keys // Alice's incoming keys should equal Bob's outgoing keys
assertArrayEquals(kA.getCurrentIncomingKeys().getTagKey().getBytes(), assertArrayEquals(kA.getCurrentIncomingKeys().getTagKey().getBytes(),
kB.getCurrentOutgoingKeys().getTagKey().getBytes()); kB.getCurrentOutgoingKeys().getTagKey().getBytes());
@@ -75,9 +75,9 @@ public class KeyDerivationTest extends BrambleTestCase {
public void testPreviousKeysMatchPreviousKeysOfContact() { public void testPreviousKeysMatchPreviousKeysOfContact() {
// Start in time period 123 // Start in time period 123
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId, TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); rootKey, 123, true, true);
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId, TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
master, 123, false, true); rootKey, 123, false, true);
// Compare Alice's previous keys in period 456 with Bob's current keys // Compare Alice's previous keys in period 456 with Bob's current keys
// in period 455 // in period 455
kA = transportCrypto.rotateTransportKeys(kA, 456); kA = transportCrypto.rotateTransportKeys(kA, 456);
@@ -102,9 +102,9 @@ public class KeyDerivationTest extends BrambleTestCase {
public void testNextKeysMatchNextKeysOfContact() { public void testNextKeysMatchNextKeysOfContact() {
// Start in time period 123 // Start in time period 123
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId, TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); rootKey, 123, true, true);
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId, TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
master, 123, false, true); rootKey, 123, false, true);
// Compare Alice's current keys in period 456 with Bob's next keys in // Compare Alice's current keys in period 456 with Bob's next keys in
// period 455 // period 455
kA = transportCrypto.rotateTransportKeys(kA, 456); kA = transportCrypto.rotateTransportKeys(kA, 456);
@@ -125,13 +125,13 @@ public class KeyDerivationTest extends BrambleTestCase {
} }
@Test @Test
public void testMasterKeyAffectsOutput() { public void testRootKeyAffectsOutput() {
SecretKey master1 = getSecretKey(); SecretKey rootKey1 = getSecretKey();
assertFalse(Arrays.equals(master.getBytes(), master1.getBytes())); assertFalse(Arrays.equals(rootKey.getBytes(), rootKey1.getBytes()));
TransportKeys k = transportCrypto.deriveTransportKeys(transportId, TransportKeys k = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); rootKey, 123, true, true);
TransportKeys k1 = transportCrypto.deriveTransportKeys(transportId, TransportKeys k1 = transportCrypto.deriveTransportKeys(transportId,
master1, 123, true, true); rootKey1, 123, true, true);
assertAllDifferent(k, k1); assertAllDifferent(k, k1);
} }
@@ -140,9 +140,9 @@ public class KeyDerivationTest extends BrambleTestCase {
TransportId transportId1 = getTransportId(); TransportId transportId1 = getTransportId();
assertNotEquals(transportId.getString(), transportId1.getString()); assertNotEquals(transportId.getString(), transportId1.getString());
TransportKeys k = transportCrypto.deriveTransportKeys(transportId, TransportKeys k = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); rootKey, 123, true, true);
TransportKeys k1 = transportCrypto.deriveTransportKeys(transportId1, TransportKeys k1 = transportCrypto.deriveTransportKeys(transportId1,
master, 123, true, true); rootKey, 123, true, true);
assertAllDifferent(k, k1); assertAllDifferent(k, k1);
} }

View File

@@ -17,7 +17,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.MASTER_SECRET_LABEL; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.MASTER_KEY_LABEL;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
@@ -74,7 +74,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
Payload ourPayload = new Payload(aliceCommit, null); Payload ourPayload = new Payload(aliceCommit, null);
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
SecretKey sharedSecret = getSecretKey(); SecretKey sharedSecret = getSecretKey();
SecretKey masterSecret = getSecretKey(); SecretKey masterKey = getSecretKey();
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks, KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
crypto, keyAgreementCrypto, payloadEncoder, transport, crypto, keyAgreementCrypto, payloadEncoder, transport,
@@ -134,13 +134,13 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
true, false); true, false);
will(returnValue(bobConfirm)); will(returnValue(bobConfirm));
// Alice computes master secret // Alice derives master key
oneOf(crypto).deriveKey(MASTER_SECRET_LABEL, sharedSecret); oneOf(crypto).deriveKey(MASTER_KEY_LABEL, sharedSecret);
will(returnValue(masterSecret)); will(returnValue(masterKey));
}}); }});
// execute // execute
assertThat(masterSecret, is(equalTo(protocol.perform()))); assertThat(masterKey, is(equalTo(protocol.perform())));
} }
@Test @Test
@@ -150,7 +150,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
Payload ourPayload = new Payload(bobCommit, null); Payload ourPayload = new Payload(bobCommit, null);
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
SecretKey sharedSecret = getSecretKey(); SecretKey sharedSecret = getSecretKey();
SecretKey masterSecret = getSecretKey(); SecretKey masterKey = getSecretKey();
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks, KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
crypto, keyAgreementCrypto, payloadEncoder, transport, crypto, keyAgreementCrypto, payloadEncoder, transport,
@@ -209,13 +209,13 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(bobConfirm)); will(returnValue(bobConfirm));
oneOf(transport).sendConfirm(bobConfirm); oneOf(transport).sendConfirm(bobConfirm);
// Bob computes master secret // Bob derives master key
oneOf(crypto).deriveKey(MASTER_SECRET_LABEL, sharedSecret); oneOf(crypto).deriveKey(MASTER_KEY_LABEL, sharedSecret);
will(returnValue(masterSecret)); will(returnValue(masterKey));
}}); }});
// execute // execute
assertThat(masterSecret, is(equalTo(protocol.perform()))); assertThat(masterKey, is(equalTo(protocol.perform())));
} }
@Test(expected = AbortException.class) @Test(expected = AbortException.class)
@@ -373,8 +373,8 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
// Alice aborts // Alice aborts
oneOf(transport).sendAbort(false); oneOf(transport).sendAbort(false);
// Alice never computes master secret // Alice never derives master key
never(crypto).deriveKey(MASTER_SECRET_LABEL, sharedSecret); never(crypto).deriveKey(MASTER_KEY_LABEL, sharedSecret);
}}); }});
// execute // execute

View File

@@ -64,7 +64,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
private final KeySetId keySetId1 = new KeySetId(456); private final KeySetId keySetId1 = new KeySetId(456);
private final SecretKey tagKey = TestUtils.getSecretKey(); private final SecretKey tagKey = TestUtils.getSecretKey();
private final SecretKey headerKey = TestUtils.getSecretKey(); private final SecretKey headerKey = TestUtils.getSecretKey();
private final SecretKey masterKey = TestUtils.getSecretKey(); private final SecretKey rootKey = TestUtils.getSecretKey();
private final Random random = new Random(); private final Random random = new Random();
@Test @Test
@@ -120,7 +120,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, rootKey,
999, alice, true); 999, alice, true);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (1 ms after start of time period 1000) // Get the current time (1 ms after start of time period 1000)
@@ -147,7 +147,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is 1 ms before the start of time period 1000 // The timestamp is 1 ms before the start of time period 1000
long timestamp = timePeriodLength * 1000 - 1; long timestamp = timePeriodLength * 1000 - 1;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); rootKey, timestamp, alice, true));
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId)); assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
} }
@@ -180,7 +180,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is at the start of time period 1000 // The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); rootKey, timestamp, alice, true));
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId)); assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
assertNull(transportKeyManager.getStreamContext(txn, contactId)); assertNull(transportKeyManager.getStreamContext(txn, contactId));
} }
@@ -206,7 +206,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is at the start of time period 1000 // The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); rootKey, timestamp, alice, true));
// The first request should return a stream context // The first request should return a stream context
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId)); assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
StreamContext ctx = transportKeyManager.getStreamContext(txn, StreamContext ctx = transportKeyManager.getStreamContext(txn,
@@ -238,7 +238,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is at the start of time period 1000 // The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, active)); rootKey, timestamp, alice, active));
assertEquals(active, assertEquals(active,
transportKeyManager.canSendOutgoingStreams(contactId)); transportKeyManager.canSendOutgoingStreams(contactId));
// The tag should not be recognised // The tag should not be recognised
@@ -256,7 +256,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
List<byte[]> tags = new ArrayList<>(); List<byte[]> tags = new ArrayList<>();
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, rootKey,
1000, alice, true); 1000, alice, true);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (the start of time period 1000) // Get the current time (the start of time period 1000)
@@ -291,7 +291,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is at the start of time period 1000 // The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); rootKey, timestamp, alice, true));
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId)); assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
// Use the first tag (previous time period, stream number 0) // Use the first tag (previous time period, stream number 0)
assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size()); assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size());
@@ -394,7 +394,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is at the start of time period 1000 // The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, false)); rootKey, timestamp, alice, false));
// The keys are inactive so no stream context should be returned // The keys are inactive so no stream context should be returned
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId)); assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
assertNull(transportKeyManager.getStreamContext(txn, contactId)); assertNull(transportKeyManager.getStreamContext(txn, contactId));
@@ -421,7 +421,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
List<byte[]> tags = new ArrayList<>(); List<byte[]> tags = new ArrayList<>();
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, rootKey,
1000, alice, false); 1000, alice, false);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (the start of time period 1000) // Get the current time (the start of time period 1000)
@@ -460,7 +460,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// The timestamp is at the start of time period 1000 // The timestamp is at the start of time period 1000
long timestamp = timePeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, false)); rootKey, timestamp, alice, false));
// The keys are inactive so no stream context should be returned // The keys are inactive so no stream context should be returned
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId)); assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
assertNull(transportKeyManager.getStreamContext(txn, contactId)); assertNull(transportKeyManager.getStreamContext(txn, contactId));
@@ -488,7 +488,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
private void expectAddContactNoRotation(boolean alice, boolean active, private void expectAddContactNoRotation(boolean alice, boolean active,
TransportKeys transportKeys, Transaction txn) throws Exception { TransportKeys transportKeys, Transaction txn) throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, rootKey,
1000, alice, active); 1000, alice, active);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (the start of time period 1000) // Get the current time (the start of time period 1000)

View File

@@ -41,7 +41,8 @@ interface IntroductionCrypto {
/** /**
* Derives a MAC key from the session's master key for Alice or Bob. * Derives a MAC key from the session's master key for Alice or Bob.
* *
* @param masterKey The key returned by {@link #deriveMasterKey(IntroduceeSession)} * @param masterKey The key returned by
* {@link #deriveMasterKey(IntroduceeSession)}
* @param alice true for Alice's MAC key, false for Bob's * @param alice true for Alice's MAC key, false for Bob's
* @return The MAC key * @return The MAC key
*/ */

View File

@@ -56,7 +56,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final File testDir = getTestDirectory(); private final File testDir = getTestDirectory();
private final File aliceDir = new File(testDir, "alice"); private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob"); private final File bobDir = new File(testDir, "bob");
private final SecretKey master = getSecretKey(); private final SecretKey rootKey = getSecretKey();
private final long timestamp = System.currentTimeMillis(); private final long timestamp = System.currentTimeMillis();
private SimplexMessagingIntegrationTestComponent alice, bob; private SimplexMessagingIntegrationTestComponent alice, bob;
@@ -110,7 +110,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
// Add the other user as a contact // Add the other user as a contact
ContactManager contactManager = device.getContactManager(); ContactManager contactManager = device.getContactManager();
return contactManager.addContact(remote, local.getId(), master, return contactManager.addContact(remote, local.getId(), rootKey,
timestamp, alice, true, true); timestamp, alice, true, true);
} }