Decouple HandshakeManager from ContactExchangeManager.

This commit is contained in:
akwizgran
2019-06-03 17:44:38 +01:00
parent 89cbdc824c
commit eed8d25120
3 changed files with 51 additions and 26 deletions

View File

@@ -1,8 +1,8 @@
package org.briarproject.bramble.api.contact; package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.transport.StreamWriter; import org.briarproject.bramble.api.transport.StreamWriter;
import java.io.IOException; import java.io.IOException;
@@ -12,16 +12,34 @@ import java.io.InputStream;
public interface HandshakeManager { public interface HandshakeManager {
/** /**
* Handshakes and exchanges pseudonyms with the given pending contact, * Handshakes with the given pending contact. Returns an ephemeral master
* converts the pending contact to a contact and returns the contact. * key authenticated with both parties' handshake key pairs and a flag
* indicating whether the local peer is Alice or Bob.
* *
* @param in An incoming stream for the handshake, which must be secured in * @param in An incoming stream for the handshake, which must be secured in
* handshake mode * handshake mode
* @param out An outgoing stream for the handshake, which must be secured * @param out An outgoing stream for the handshake, which must be secured
* in handshake mode * in handshake mode
* @param conn The connection to use for the handshake and contact exchange
*/ */
Contact handshakeAndAddContact(PendingContactId p, HandshakeResult handshake(PendingContactId p,
InputStream in, StreamWriter out, DuplexTransportConnection conn) InputStream in, StreamWriter out) throws DbException, IOException;
throws DbException, IOException;
class HandshakeResult {
private final SecretKey masterKey;
private final boolean alice;
public HandshakeResult(SecretKey masterKey, boolean alice) {
this.masterKey = masterKey;
this.alice = alice;
}
public SecretKey getMasterKey() {
return masterKey;
}
public boolean isAlice() {
return alice;
}
}
} }

View File

@@ -3,8 +3,6 @@ package org.briarproject.bramble.contact;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.Predicate; import org.briarproject.bramble.api.Predicate;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactExchangeManager;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.HandshakeManager; import org.briarproject.bramble.api.contact.HandshakeManager;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
@@ -18,7 +16,6 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.TransactionManager; import org.briarproject.bramble.api.db.TransactionManager;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.record.Record; import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordReader; import org.briarproject.bramble.api.record.RecordReader;
import org.briarproject.bramble.api.record.RecordReaderFactory; import org.briarproject.bramble.api.record.RecordReaderFactory;
@@ -58,7 +55,6 @@ class HandshakeManagerImpl implements HandshakeManager {
private final HandshakeCrypto handshakeCrypto; private final HandshakeCrypto handshakeCrypto;
private final RecordReaderFactory recordReaderFactory; private final RecordReaderFactory recordReaderFactory;
private final RecordWriterFactory recordWriterFactory; private final RecordWriterFactory recordWriterFactory;
private final ContactExchangeManager contactExchangeManager;
@Inject @Inject
HandshakeManagerImpl(DatabaseComponent db, HandshakeManagerImpl(DatabaseComponent db,
@@ -66,21 +62,18 @@ class HandshakeManagerImpl implements HandshakeManager {
ContactManager contactManager, ContactManager contactManager,
HandshakeCrypto handshakeCrypto, HandshakeCrypto handshakeCrypto,
RecordReaderFactory recordReaderFactory, RecordReaderFactory recordReaderFactory,
RecordWriterFactory recordWriterFactory, RecordWriterFactory recordWriterFactory) {
ContactExchangeManager contactExchangeManager) {
this.db = db; this.db = db;
this.identityManager = identityManager; this.identityManager = identityManager;
this.contactManager = contactManager; this.contactManager = contactManager;
this.handshakeCrypto = handshakeCrypto; this.handshakeCrypto = handshakeCrypto;
this.recordReaderFactory = recordReaderFactory; this.recordReaderFactory = recordReaderFactory;
this.recordWriterFactory = recordWriterFactory; this.recordWriterFactory = recordWriterFactory;
this.contactExchangeManager = contactExchangeManager;
} }
@Override @Override
public Contact handshakeAndAddContact(PendingContactId p, public HandshakeResult handshake(PendingContactId p, InputStream in,
InputStream in, StreamWriter out, DuplexTransportConnection conn) StreamWriter out) throws DbException, IOException {
throws DbException, IOException {
Pair<PublicKey, KeyPair> keys = db.transactionWithResult(true, txn -> { Pair<PublicKey, KeyPair> keys = db.transactionWithResult(true, txn -> {
PendingContact pendingContact = PendingContact pendingContact =
contactManager.getPendingContact(txn, p); contactManager.getPendingContact(txn, p);
@@ -125,8 +118,7 @@ class HandshakeManagerImpl implements HandshakeManager {
recordReader.readRecord(r -> false, IGNORE); recordReader.readRecord(r -> false, IGNORE);
if (!handshakeCrypto.verifyOwnership(masterKey, !alice, theirProof)) if (!handshakeCrypto.verifyOwnership(masterKey, !alice, theirProof))
throw new FormatException(); throw new FormatException();
return contactExchangeManager.exchangeContacts(p, conn, masterKey, return new HandshakeResult(masterKey, alice);
alice, false);
} }
private void sendPublicKey(RecordWriter w, PublicKey k) throws IOException { private void sendPublicKey(RecordWriter w, PublicKey k) throws IOException {

View File

@@ -3,6 +3,7 @@ package org.briarproject.bramble.contact;
import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.HandshakeManager.HandshakeResult;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactState; import org.briarproject.bramble.api.contact.PendingContactState;
import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.crypto.PublicKey;
@@ -25,6 +26,7 @@ import java.io.PipedOutputStream;
import java.util.Collection; import java.util.Collection;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNotNull;
@@ -37,6 +39,7 @@ import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class ContactExchangeIntegrationTest extends BrambleTestCase { public class ContactExchangeIntegrationTest extends BrambleTestCase {
@@ -169,19 +172,25 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
PipedInputStream bobHandshakeIn = new PipedInputStream(); PipedInputStream bobHandshakeIn = new PipedInputStream();
OutputStream aliceHandshakeOut = new PipedOutputStream(bobHandshakeIn); OutputStream aliceHandshakeOut = new PipedOutputStream(bobHandshakeIn);
OutputStream bobHandshakeOut = new PipedOutputStream(aliceHandshakeIn); OutputStream bobHandshakeOut = new PipedOutputStream(aliceHandshakeIn);
AtomicReference<HandshakeResult> aliceResult = new AtomicReference<>();
AtomicReference<HandshakeResult> bobResult = new AtomicReference<>();
TestDuplexTransportConnection[] pair = createPair(); TestDuplexTransportConnection[] pair = createPair();
TestDuplexTransportConnection aliceConnection = pair[0]; TestDuplexTransportConnection aliceConnection = pair[0];
TestDuplexTransportConnection bobConnection = pair[1]; TestDuplexTransportConnection bobConnection = pair[1];
CountDownLatch aliceFinished = new CountDownLatch(1); CountDownLatch aliceFinished = new CountDownLatch(1);
CountDownLatch bobFinished = new CountDownLatch(1); CountDownLatch bobFinished = new CountDownLatch(1);
boolean verified = random.nextBoolean();
alice.getIoExecutor().execute(() -> { alice.getIoExecutor().execute(() -> {
try { try {
alice.getHandshakeManager().handshakeAndAddContact( HandshakeResult result = alice.getHandshakeManager().handshake(
bobFromAlice.getId(), aliceHandshakeIn, bobFromAlice.getId(), aliceHandshakeIn,
new TestStreamWriter(aliceHandshakeOut), new TestStreamWriter(aliceHandshakeOut));
aliceConnection); aliceResult.set(result);
alice.getContactExchangeManager().exchangeContacts(
bobFromAlice.getId(), aliceConnection,
result.getMasterKey(), result.isAlice(), verified);
aliceFinished.countDown(); aliceFinished.countDown();
} catch (Exception e) { } catch (Exception e) {
fail(); fail();
@@ -189,10 +198,13 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
}); });
bob.getIoExecutor().execute(() -> { bob.getIoExecutor().execute(() -> {
try { try {
bob.getHandshakeManager().handshakeAndAddContact( HandshakeResult result = bob.getHandshakeManager().handshake(
aliceFromBob.getId(), bobHandshakeIn, aliceFromBob.getId(), bobHandshakeIn,
new TestStreamWriter(bobHandshakeOut), new TestStreamWriter(bobHandshakeOut));
bobConnection); bobResult.set(result);
bob.getContactExchangeManager().exchangeContacts(
aliceFromBob.getId(), bobConnection,
result.getMasterKey(), result.isAlice(), verified);
bobFinished.countDown(); bobFinished.countDown();
} catch (Exception e) { } catch (Exception e) {
fail(); fail();
@@ -200,7 +212,10 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
}); });
aliceFinished.await(TIMEOUT, MILLISECONDS); aliceFinished.await(TIMEOUT, MILLISECONDS);
bobFinished.await(TIMEOUT, MILLISECONDS); bobFinished.await(TIMEOUT, MILLISECONDS);
assertContacts(false, true); assertArrayEquals(aliceResult.get().getMasterKey().getBytes(),
bobResult.get().getMasterKey().getBytes());
assertNotEquals(aliceResult.get().isAlice(), bobResult.get().isAlice());
assertContacts(verified, true);
assertNoPendingContacts(); assertNoPendingContacts();
} }