From eed8d25120946f78c53cfb20665656c1b08d3f96 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 3 Jun 2019 17:44:38 +0100 Subject: [PATCH] Decouple HandshakeManager from ContactExchangeManager. --- .../bramble/api/contact/HandshakeManager.java | 32 +++++++++++++++---- .../bramble/contact/HandshakeManagerImpl.java | 16 +++------- .../ContactExchangeIntegrationTest.java | 29 +++++++++++++---- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/HandshakeManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/HandshakeManager.java index 6a9eb6eda..d77287de1 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/HandshakeManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/HandshakeManager.java @@ -1,8 +1,8 @@ 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.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.transport.StreamWriter; import java.io.IOException; @@ -12,16 +12,34 @@ import java.io.InputStream; public interface HandshakeManager { /** - * Handshakes and exchanges pseudonyms with the given pending contact, - * converts the pending contact to a contact and returns the contact. + * Handshakes with the given pending contact. Returns an ephemeral master + * 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 * handshake mode * @param out An outgoing stream for the handshake, which must be secured * in handshake mode - * @param conn The connection to use for the handshake and contact exchange */ - Contact handshakeAndAddContact(PendingContactId p, - InputStream in, StreamWriter out, DuplexTransportConnection conn) - throws DbException, IOException; + HandshakeResult handshake(PendingContactId p, + InputStream in, StreamWriter out) 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; + } + } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/HandshakeManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/HandshakeManagerImpl.java index bb4cb5dbb..3e6abcc4f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/contact/HandshakeManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/HandshakeManagerImpl.java @@ -3,8 +3,6 @@ package org.briarproject.bramble.contact; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.Pair; 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.HandshakeManager; 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.identity.IdentityManager; 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.RecordReader; import org.briarproject.bramble.api.record.RecordReaderFactory; @@ -58,7 +55,6 @@ class HandshakeManagerImpl implements HandshakeManager { private final HandshakeCrypto handshakeCrypto; private final RecordReaderFactory recordReaderFactory; private final RecordWriterFactory recordWriterFactory; - private final ContactExchangeManager contactExchangeManager; @Inject HandshakeManagerImpl(DatabaseComponent db, @@ -66,21 +62,18 @@ class HandshakeManagerImpl implements HandshakeManager { ContactManager contactManager, HandshakeCrypto handshakeCrypto, RecordReaderFactory recordReaderFactory, - RecordWriterFactory recordWriterFactory, - ContactExchangeManager contactExchangeManager) { + RecordWriterFactory recordWriterFactory) { this.db = db; this.identityManager = identityManager; this.contactManager = contactManager; this.handshakeCrypto = handshakeCrypto; this.recordReaderFactory = recordReaderFactory; this.recordWriterFactory = recordWriterFactory; - this.contactExchangeManager = contactExchangeManager; } @Override - public Contact handshakeAndAddContact(PendingContactId p, - InputStream in, StreamWriter out, DuplexTransportConnection conn) - throws DbException, IOException { + public HandshakeResult handshake(PendingContactId p, InputStream in, + StreamWriter out) throws DbException, IOException { Pair keys = db.transactionWithResult(true, txn -> { PendingContact pendingContact = contactManager.getPendingContact(txn, p); @@ -125,8 +118,7 @@ class HandshakeManagerImpl implements HandshakeManager { recordReader.readRecord(r -> false, IGNORE); if (!handshakeCrypto.verifyOwnership(masterKey, !alice, theirProof)) throw new FormatException(); - return contactExchangeManager.exchangeContacts(p, conn, masterKey, - alice, false); + return new HandshakeResult(masterKey, alice); } private void sendPublicKey(RecordWriter w, PublicKey k) throws IOException { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTest.java b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTest.java index a674c52a4..8b461c669 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTest.java @@ -3,6 +3,7 @@ package org.briarproject.bramble.contact; import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.contact.Contact; 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.PendingContactState; import org.briarproject.bramble.api.crypto.PublicKey; @@ -25,6 +26,7 @@ import java.io.PipedOutputStream; import java.util.Collection; import java.util.Random; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; import static java.util.concurrent.TimeUnit.MILLISECONDS; 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.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; public class ContactExchangeIntegrationTest extends BrambleTestCase { @@ -169,19 +172,25 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase { PipedInputStream bobHandshakeIn = new PipedInputStream(); OutputStream aliceHandshakeOut = new PipedOutputStream(bobHandshakeIn); OutputStream bobHandshakeOut = new PipedOutputStream(aliceHandshakeIn); + AtomicReference aliceResult = new AtomicReference<>(); + AtomicReference bobResult = new AtomicReference<>(); TestDuplexTransportConnection[] pair = createPair(); TestDuplexTransportConnection aliceConnection = pair[0]; TestDuplexTransportConnection bobConnection = pair[1]; CountDownLatch aliceFinished = new CountDownLatch(1); CountDownLatch bobFinished = new CountDownLatch(1); + boolean verified = random.nextBoolean(); alice.getIoExecutor().execute(() -> { try { - alice.getHandshakeManager().handshakeAndAddContact( + HandshakeResult result = alice.getHandshakeManager().handshake( bobFromAlice.getId(), aliceHandshakeIn, - new TestStreamWriter(aliceHandshakeOut), - aliceConnection); + new TestStreamWriter(aliceHandshakeOut)); + aliceResult.set(result); + alice.getContactExchangeManager().exchangeContacts( + bobFromAlice.getId(), aliceConnection, + result.getMasterKey(), result.isAlice(), verified); aliceFinished.countDown(); } catch (Exception e) { fail(); @@ -189,10 +198,13 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase { }); bob.getIoExecutor().execute(() -> { try { - bob.getHandshakeManager().handshakeAndAddContact( + HandshakeResult result = bob.getHandshakeManager().handshake( aliceFromBob.getId(), bobHandshakeIn, - new TestStreamWriter(bobHandshakeOut), - bobConnection); + new TestStreamWriter(bobHandshakeOut)); + bobResult.set(result); + bob.getContactExchangeManager().exchangeContacts( + aliceFromBob.getId(), bobConnection, + result.getMasterKey(), result.isAlice(), verified); bobFinished.countDown(); } catch (Exception e) { fail(); @@ -200,7 +212,10 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase { }); aliceFinished.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(); }