mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 06:09:55 +01:00
Decouple HandshakeManager from ContactExchangeManager.
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user