mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 23:29:52 +01:00
Let plugins know if we're Alice or Bob.
This commit is contained in:
@@ -57,5 +57,5 @@ public interface DuplexPlugin extends Plugin {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
||||||
ConnectionHandler incoming);
|
boolean alice, ConnectionHandler incoming);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
||||||
ConnectionHandler incoming) {
|
boolean alice, ConnectionHandler incoming) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ abstract class TcpPlugin implements DuplexPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
||||||
ConnectionHandler incoming) {
|
boolean alice, ConnectionHandler incoming) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -614,7 +614,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
||||||
ConnectionHandler incoming) {
|
boolean alice, ConnectionHandler incoming) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
private final Executor worker;
|
private final Executor worker;
|
||||||
// The following fields are only accessed on the worker
|
// The following fields are only accessed on the worker
|
||||||
private final Map<TransportId, PluginState> pluginStates = new HashMap<>();
|
private final Map<TransportId, PluginState> pluginStates = new HashMap<>();
|
||||||
private final Map<PendingContactId, SecretKey> rendezvousKeys =
|
private final Map<PendingContactId, CryptoState> cryptoStates =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
@Nullable
|
@Nullable
|
||||||
private KeyPair handshakeKeyPair = null;
|
private KeyPair handshakeKeyPair = null;
|
||||||
@@ -153,12 +153,15 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
.deriveStaticMasterKey(p.getPublicKey(), handshakeKeyPair);
|
.deriveStaticMasterKey(p.getPublicKey(), handshakeKeyPair);
|
||||||
SecretKey rendezvousKey = rendezvousCrypto
|
SecretKey rendezvousKey = rendezvousCrypto
|
||||||
.deriveRendezvousKey(staticMasterKey);
|
.deriveRendezvousKey(staticMasterKey);
|
||||||
requireNull(rendezvousKeys.put(p.getId(), rendezvousKey));
|
boolean alice = transportCrypto
|
||||||
for (PluginState state : pluginStates.values()) {
|
.isAlice(p.getPublicKey(), handshakeKeyPair);
|
||||||
|
CryptoState cs = new CryptoState(rendezvousKey, alice);
|
||||||
|
requireNull(cryptoStates.put(p.getId(), cs));
|
||||||
|
for (PluginState ps : pluginStates.values()) {
|
||||||
RendezvousEndpoint endpoint =
|
RendezvousEndpoint endpoint =
|
||||||
createEndpoint(state.plugin, p.getId(), rendezvousKey);
|
createEndpoint(ps.plugin, p.getId(), cs);
|
||||||
if (endpoint != null)
|
if (endpoint != null)
|
||||||
requireNull(state.endpoints.put(p.getId(), endpoint));
|
requireNull(ps.endpoints.put(p.getId(), endpoint));
|
||||||
}
|
}
|
||||||
} catch (DbException | GeneralSecurityException e) {
|
} catch (DbException | GeneralSecurityException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
@@ -179,9 +182,9 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
// Worker
|
// Worker
|
||||||
private boolean removePendingContact(PendingContactId p) {
|
private boolean removePendingContact(PendingContactId p) {
|
||||||
// We can come here twice if a pending contact fails and is then removed
|
// We can come here twice if a pending contact fails and is then removed
|
||||||
if (rendezvousKeys.remove(p) == null) return false;
|
if (cryptoStates.remove(p) == null) return false;
|
||||||
for (PluginState state : pluginStates.values()) {
|
for (PluginState ps : pluginStates.values()) {
|
||||||
RendezvousEndpoint endpoint = state.endpoints.remove(p);
|
RendezvousEndpoint endpoint = ps.endpoints.remove(p);
|
||||||
if (endpoint != null) tryToClose(endpoint, LOG, INFO);
|
if (endpoint != null) tryToClose(endpoint, LOG, INFO);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -189,33 +192,33 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private RendezvousEndpoint createEndpoint(DuplexPlugin plugin,
|
private RendezvousEndpoint createEndpoint(DuplexPlugin plugin,
|
||||||
PendingContactId p, SecretKey rendezvousKey) {
|
PendingContactId p, CryptoState cs) {
|
||||||
TransportId t = plugin.getId();
|
TransportId t = plugin.getId();
|
||||||
KeyMaterialSource k =
|
KeyMaterialSource k =
|
||||||
rendezvousCrypto.createKeyMaterialSource(rendezvousKey, t);
|
rendezvousCrypto.createKeyMaterialSource(cs.rendezvousKey, t);
|
||||||
Handler h = new Handler(p, t, true);
|
Handler h = new Handler(p, t, true);
|
||||||
return plugin.createRendezvousEndpoint(k, h);
|
return plugin.createRendezvousEndpoint(k, cs.alice, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduler
|
@Scheduler
|
||||||
private void poll() {
|
private void poll() {
|
||||||
worker.execute(() -> {
|
worker.execute(() -> {
|
||||||
for (PluginState state : pluginStates.values()) poll(state);
|
for (PluginState ps : pluginStates.values()) poll(ps);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Worker
|
// Worker
|
||||||
private void poll(PluginState state) {
|
private void poll(PluginState ps) {
|
||||||
List<Pair<TransportProperties, ConnectionHandler>> properties =
|
List<Pair<TransportProperties, ConnectionHandler>> properties =
|
||||||
new ArrayList<>();
|
new ArrayList<>();
|
||||||
for (Entry<PendingContactId, RendezvousEndpoint> e :
|
for (Entry<PendingContactId, RendezvousEndpoint> e :
|
||||||
state.endpoints.entrySet()) {
|
ps.endpoints.entrySet()) {
|
||||||
TransportProperties props =
|
TransportProperties props =
|
||||||
e.getValue().getRemoteTransportProperties();
|
e.getValue().getRemoteTransportProperties();
|
||||||
Handler h = new Handler(e.getKey(), state.plugin.getId(), false);
|
Handler h = new Handler(e.getKey(), ps.plugin.getId(), false);
|
||||||
properties.add(new Pair<>(props, h));
|
properties.add(new Pair<>(props, h));
|
||||||
}
|
}
|
||||||
state.plugin.poll(properties);
|
ps.plugin.poll(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -249,13 +252,13 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
|
|
||||||
// Worker
|
// Worker
|
||||||
private void poll(PendingContactId p) {
|
private void poll(PendingContactId p) {
|
||||||
for (PluginState state : pluginStates.values()) {
|
for (PluginState ps : pluginStates.values()) {
|
||||||
RendezvousEndpoint endpoint = state.endpoints.get(p);
|
RendezvousEndpoint endpoint = ps.endpoints.get(p);
|
||||||
if (endpoint != null) {
|
if (endpoint != null) {
|
||||||
TransportProperties props =
|
TransportProperties props =
|
||||||
endpoint.getRemoteTransportProperties();
|
endpoint.getRemoteTransportProperties();
|
||||||
Handler h = new Handler(p, state.plugin.getId(), false);
|
Handler h = new Handler(p, ps.plugin.getId(), false);
|
||||||
state.plugin.poll(singletonList(new Pair<>(props, h)));
|
ps.plugin.poll(singletonList(new Pair<>(props, h)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -279,7 +282,7 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
private void addTransport(DuplexPlugin plugin) {
|
private void addTransport(DuplexPlugin plugin) {
|
||||||
TransportId t = plugin.getId();
|
TransportId t = plugin.getId();
|
||||||
Map<PendingContactId, RendezvousEndpoint> endpoints = new HashMap<>();
|
Map<PendingContactId, RendezvousEndpoint> endpoints = new HashMap<>();
|
||||||
for (Entry<PendingContactId, SecretKey> e : rendezvousKeys.entrySet()) {
|
for (Entry<PendingContactId, CryptoState> e : cryptoStates.entrySet()) {
|
||||||
RendezvousEndpoint endpoint =
|
RendezvousEndpoint endpoint =
|
||||||
createEndpoint(plugin, e.getKey(), e.getValue());
|
createEndpoint(plugin, e.getKey(), e.getValue());
|
||||||
if (endpoint != null) endpoints.put(e.getKey(), endpoint);
|
if (endpoint != null) endpoints.put(e.getKey(), endpoint);
|
||||||
@@ -294,9 +297,9 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
|
|
||||||
// Worker
|
// Worker
|
||||||
private void removeTransport(TransportId t) {
|
private void removeTransport(TransportId t) {
|
||||||
PluginState state = pluginStates.remove(t);
|
PluginState ps = pluginStates.remove(t);
|
||||||
if (state != null) {
|
if (ps != null) {
|
||||||
for (RendezvousEndpoint endpoint : state.endpoints.values()) {
|
for (RendezvousEndpoint endpoint : ps.endpoints.values()) {
|
||||||
tryToClose(endpoint, LOG, INFO);
|
tryToClose(endpoint, LOG, INFO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,6 +317,17 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class CryptoState {
|
||||||
|
|
||||||
|
private final SecretKey rendezvousKey;
|
||||||
|
private final boolean alice;
|
||||||
|
|
||||||
|
private CryptoState(SecretKey rendezvousKey, boolean alice) {
|
||||||
|
this.rendezvousKey = rendezvousKey;
|
||||||
|
this.alice = alice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class Handler implements ConnectionHandler {
|
private class Handler implements ConnectionHandler {
|
||||||
|
|
||||||
private final PendingContactId pendingContactId;
|
private final PendingContactId pendingContactId;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.jmock.Expectations;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@@ -79,6 +80,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
private final TransportId transportId = getTransportId();
|
private final TransportId transportId = getTransportId();
|
||||||
private final TransportProperties transportProperties =
|
private final TransportProperties transportProperties =
|
||||||
getTransportProperties(3);
|
getTransportProperties(3);
|
||||||
|
private final boolean alice = new Random().nextBoolean();
|
||||||
|
|
||||||
private RendezvousPollerImpl rendezvousPoller;
|
private RendezvousPollerImpl rendezvousPoller;
|
||||||
|
|
||||||
@@ -122,6 +124,9 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(staticMasterKey));
|
will(returnValue(staticMasterKey));
|
||||||
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
||||||
will(returnValue(rendezvousKey));
|
will(returnValue(rendezvousKey));
|
||||||
|
oneOf(transportCrypto).isAlice(pendingContact.getPublicKey(),
|
||||||
|
handshakeKeyPair);
|
||||||
|
will(returnValue(alice));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
rendezvousPoller.startService();
|
rendezvousPoller.startService();
|
||||||
@@ -182,11 +187,14 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(staticMasterKey));
|
will(returnValue(staticMasterKey));
|
||||||
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
||||||
will(returnValue(rendezvousKey));
|
will(returnValue(rendezvousKey));
|
||||||
|
oneOf(transportCrypto).isAlice(pendingContact.getPublicKey(),
|
||||||
|
handshakeKeyPair);
|
||||||
|
will(returnValue(alice));
|
||||||
oneOf(rendezvousCrypto).createKeyMaterialSource(rendezvousKey,
|
oneOf(rendezvousCrypto).createKeyMaterialSource(rendezvousKey,
|
||||||
transportId);
|
transportId);
|
||||||
will(returnValue(keyMaterialSource));
|
will(returnValue(keyMaterialSource));
|
||||||
oneOf(plugin).createRendezvousEndpoint(with(keyMaterialSource),
|
oneOf(plugin).createRendezvousEndpoint(with(keyMaterialSource),
|
||||||
with(any(ConnectionHandler.class)));
|
with(alice), with(any(ConnectionHandler.class)));
|
||||||
will(returnValue(rendezvousEndpoint));
|
will(returnValue(rendezvousEndpoint));
|
||||||
// Poll newly added pending contact
|
// Poll newly added pending contact
|
||||||
oneOf(rendezvousEndpoint).getRemoteTransportProperties();
|
oneOf(rendezvousEndpoint).getRemoteTransportProperties();
|
||||||
@@ -250,11 +258,14 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(staticMasterKey));
|
will(returnValue(staticMasterKey));
|
||||||
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
||||||
will(returnValue(rendezvousKey));
|
will(returnValue(rendezvousKey));
|
||||||
|
oneOf(transportCrypto).isAlice(pendingContact.getPublicKey(),
|
||||||
|
handshakeKeyPair);
|
||||||
|
will(returnValue(alice));
|
||||||
oneOf(rendezvousCrypto).createKeyMaterialSource(rendezvousKey,
|
oneOf(rendezvousCrypto).createKeyMaterialSource(rendezvousKey,
|
||||||
transportId);
|
transportId);
|
||||||
will(returnValue(keyMaterialSource));
|
will(returnValue(keyMaterialSource));
|
||||||
oneOf(plugin).createRendezvousEndpoint(with(keyMaterialSource),
|
oneOf(plugin).createRendezvousEndpoint(with(keyMaterialSource),
|
||||||
with(any(ConnectionHandler.class)));
|
with(alice), with(any(ConnectionHandler.class)));
|
||||||
will(returnValue(rendezvousEndpoint));
|
will(returnValue(rendezvousEndpoint));
|
||||||
// Poll newly added pending contact
|
// Poll newly added pending contact
|
||||||
oneOf(rendezvousEndpoint).getRemoteTransportProperties();
|
oneOf(rendezvousEndpoint).getRemoteTransportProperties();
|
||||||
@@ -305,6 +316,9 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(staticMasterKey));
|
will(returnValue(staticMasterKey));
|
||||||
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
oneOf(rendezvousCrypto).deriveRendezvousKey(staticMasterKey);
|
||||||
will(returnValue(rendezvousKey));
|
will(returnValue(rendezvousKey));
|
||||||
|
oneOf(transportCrypto).isAlice(pendingContact.getPublicKey(),
|
||||||
|
handshakeKeyPair);
|
||||||
|
will(returnValue(alice));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
rendezvousPoller.eventOccurred(
|
rendezvousPoller.eventOccurred(
|
||||||
@@ -323,7 +337,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
transportId);
|
transportId);
|
||||||
will(returnValue(keyMaterialSource));
|
will(returnValue(keyMaterialSource));
|
||||||
oneOf(plugin).createRendezvousEndpoint(with(keyMaterialSource),
|
oneOf(plugin).createRendezvousEndpoint(with(keyMaterialSource),
|
||||||
with(any(ConnectionHandler.class)));
|
with(alice), with(any(ConnectionHandler.class)));
|
||||||
will(returnValue(rendezvousEndpoint));
|
will(returnValue(rendezvousEndpoint));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
public RendezvousEndpoint createRendezvousEndpoint(KeyMaterialSource k,
|
||||||
ConnectionHandler incoming) {
|
boolean alice, ConnectionHandler incoming) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user