From 967f0686371cadad09702a1144305dd0579c0df4 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 14 May 2019 17:07:07 +0100 Subject: [PATCH] Add initial API for rendezvous plugins. --- .../keyagreement/KeyAgreementListener.java | 2 +- .../bramble/api/plugin/PluginManager.java | 5 +++ .../api/plugin/duplex/DuplexPlugin.java | 13 +++++++ .../api/rendezvous/KeyMaterialSource.java | 15 ++++++++ .../api/rendezvous/RendezvousConstants.java | 10 ++++++ .../api/rendezvous/RendezvousCrypto.java | 12 +++++++ .../api/rendezvous/RendezvousHandler.java | 24 +++++++++++++ .../bramble/BrambleCoreModule.java | 2 ++ .../bramble/plugin/PluginManagerImpl.java | 8 +++++ .../plugin/bluetooth/BluetoothPlugin.java | 12 +++++++ .../bramble/plugin/tcp/TcpPlugin.java | 12 +++++++ .../bramble/plugin/tor/TorPlugin.java | 12 +++++++ .../rendezvous/KeyMaterialSourceImpl.java | 33 ++++++++++++++++++ .../rendezvous/RendezvousCryptoImpl.java | 34 +++++++++++++++++++ .../bramble/rendezvous/RendezvousModule.java | 16 +++++++++ .../bramble/plugin/modem/ModemPlugin.java | 12 +++++++ 16 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/KeyMaterialSource.java create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousConstants.java create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousCrypto.java create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousHandler.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/rendezvous/KeyMaterialSourceImpl.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousCryptoImpl.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousModule.java diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementListener.java b/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementListener.java index 8c520b47e..9ace16f09 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementListener.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementListener.java @@ -5,7 +5,7 @@ import org.briarproject.bramble.api.data.BdfList; import java.io.IOException; /** - * An class for managing a particular key agreement listener. + * Accepts key agreement connections over a given transport. */ public abstract class KeyAgreementListener { diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginManager.java index 32c3a8012..9c34b434d 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginManager.java @@ -36,4 +36,9 @@ public interface PluginManager { * Returns any duplex plugins that support key agreement. */ Collection getKeyAgreementPlugins(); + + /** + * Returns any duplex plugins that support rendezvous. + */ + Collection getRendezvousPlugins(); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java index 5633d77ee..4ce802ced 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java @@ -5,6 +5,8 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.briarproject.bramble.api.rendezvous.RendezvousHandler; import javax.annotation.Nullable; @@ -40,4 +42,15 @@ public interface DuplexPlugin extends Plugin { @Nullable DuplexTransportConnection createKeyAgreementConnection( byte[] remoteCommitment, BdfList descriptor); + + /** + * Returns true if the plugin supports rendezvous connections. + */ + boolean supportsRendezvous(); + + /** + * Creates and returns a handler that uses the given key material to + * rendezvous with a pending contact. + */ + RendezvousHandler createRendezvousHandler(KeyMaterialSource k); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/KeyMaterialSource.java b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/KeyMaterialSource.java new file mode 100644 index 000000000..87d1960da --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/KeyMaterialSource.java @@ -0,0 +1,15 @@ +package org.briarproject.bramble.api.rendezvous; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +/** + * A source of key material for use in making rendezvous connections. + */ +@NotNullByDefault +public interface KeyMaterialSource { + + /** + * Returns the requested amount of key material. + */ + byte[] getKeyMaterial(int length); +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousConstants.java new file mode 100644 index 000000000..00ac61fe1 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousConstants.java @@ -0,0 +1,10 @@ +package org.briarproject.bramble.api.rendezvous; + +public interface RendezvousConstants { + + /** + * Label for deriving key material from the master key. + */ + String KEY_MATERIAL_LABEL = + "org.briarproject.bramble.rendezvous/KEY_MATERIAL"; +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousCrypto.java b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousCrypto.java new file mode 100644 index 000000000..e6cacef09 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousCrypto.java @@ -0,0 +1,12 @@ +package org.briarproject.bramble.api.rendezvous; + +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; + +@NotNullByDefault +public interface RendezvousCrypto { + + KeyMaterialSource createKeyMaterialSource(SecretKey masterKey, + TransportId t); +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousHandler.java b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousHandler.java new file mode 100644 index 000000000..a48e2d619 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousHandler.java @@ -0,0 +1,24 @@ +package org.briarproject.bramble.api.rendezvous; + +import org.briarproject.bramble.api.properties.TransportProperties; + +import java.io.IOException; + +/** + * An interface for making and accepting rendezvous connections with a pending + * contact over a given transport. + */ +public interface RendezvousHandler { + + /** + * Returns a set of transport properties for connecting to the pending + * contact. + */ + TransportProperties getRemoteTransportProperties(); + + /** + * Closes the handler and releases any resources held by it, such as + * network sockets. + */ + void close() throws IOException; +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java index 44535a50a..ebf43a69d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java @@ -15,6 +15,7 @@ import org.briarproject.bramble.plugin.PluginModule; import org.briarproject.bramble.properties.PropertiesModule; import org.briarproject.bramble.record.RecordModule; import org.briarproject.bramble.reliability.ReliabilityModule; +import org.briarproject.bramble.rendezvous.RendezvousModule; import org.briarproject.bramble.reporting.ReportingModule; import org.briarproject.bramble.settings.SettingsModule; import org.briarproject.bramble.socks.SocksModule; @@ -42,6 +43,7 @@ import dagger.Module; PropertiesModule.class, RecordModule.class, ReliabilityModule.class, + RendezvousModule.class, ReportingModule.class, SettingsModule.class, SocksModule.class, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java index 682b7fde2..cbaac0943 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java @@ -169,6 +169,14 @@ class PluginManagerImpl implements PluginManager, Service { return supported; } + @Override + public Collection getRendezvousPlugins() { + List supported = new ArrayList<>(); + for (DuplexPlugin d : duplexPlugins) + if (d.supportsRendezvous()) supported.add(d); + return supported; + } + private class PluginStarter implements Runnable { private final Plugin plugin; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index 4cb3fecdc..04e54027b 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -22,6 +22,8 @@ import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent; import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent; import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent; import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.briarproject.bramble.api.rendezvous.RendezvousHandler; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; @@ -390,6 +392,16 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { return macToString(mac); } + @Override + public boolean supportsRendezvous() { + return false; + } + + @Override + public RendezvousHandler createRendezvousHandler(KeyMaterialSource k) { + throw new UnsupportedOperationException(); + } + @Override public void eventOccurred(Event e) { if (e instanceof EnableBluetoothEvent) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java index aa35274d7..5bc579487 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java @@ -12,6 +12,8 @@ import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.briarproject.bramble.api.rendezvous.RendezvousHandler; import org.briarproject.bramble.util.IoUtils; import java.io.IOException; @@ -301,6 +303,16 @@ abstract class TcpPlugin implements DuplexPlugin { throw new UnsupportedOperationException(); } + @Override + public boolean supportsRendezvous() { + return false; + } + + @Override + public RendezvousHandler createRendezvousHandler(KeyMaterialSource k) { + throw new UnsupportedOperationException(); + } + Collection getLocalIpAddresses() { try { Enumeration ifaces = getNetworkInterfaces(); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 656b723ce..5cfcf5db4 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -25,6 +25,8 @@ import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.briarproject.bramble.api.rendezvous.RendezvousHandler; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.system.Clock; @@ -605,6 +607,16 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { throw new UnsupportedOperationException(); } + @Override + public boolean supportsRendezvous() { + return false; + } + + @Override + public RendezvousHandler createRendezvousHandler(KeyMaterialSource k) { + throw new UnsupportedOperationException(); + } + @Override public void circuitStatus(String status, String id, String path) { if (status.equals("BUILT") && diff --git a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/KeyMaterialSourceImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/KeyMaterialSourceImpl.java new file mode 100644 index 000000000..7a2ec3508 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/KeyMaterialSourceImpl.java @@ -0,0 +1,33 @@ +package org.briarproject.bramble.rendezvous; + +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.spongycastle.crypto.engines.Salsa20Engine; +import org.spongycastle.crypto.params.KeyParameter; +import org.spongycastle.crypto.params.ParametersWithIV; + +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +@NotNullByDefault +class KeyMaterialSourceImpl implements KeyMaterialSource { + + @GuardedBy("this") + private final Salsa20Engine cipher = new Salsa20Engine(); + + KeyMaterialSourceImpl(SecretKey sourceKey) { + // Initialise the stream cipher with an all-zero nonce + KeyParameter k = new KeyParameter(sourceKey.getBytes()); + cipher.init(true, new ParametersWithIV(k, new byte[8])); + } + + @Override + public synchronized byte[] getKeyMaterial(int length) { + byte[] in = new byte[length]; + byte[] out = new byte[length]; + cipher.processBytes(in, 0, length, out, 0); + return out; + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousCryptoImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousCryptoImpl.java new file mode 100644 index 000000000..01877ae48 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousCryptoImpl.java @@ -0,0 +1,34 @@ +package org.briarproject.bramble.rendezvous; + +import org.briarproject.bramble.api.crypto.CryptoComponent; +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.briarproject.bramble.api.rendezvous.RendezvousCrypto; + +import javax.annotation.concurrent.Immutable; +import javax.inject.Inject; + +import static org.briarproject.bramble.api.rendezvous.RendezvousConstants.KEY_MATERIAL_LABEL; +import static org.briarproject.bramble.util.StringUtils.toUtf8; + +@Immutable +@NotNullByDefault +class RendezvousCryptoImpl implements RendezvousCrypto { + + private final CryptoComponent crypto; + + @Inject + RendezvousCryptoImpl(CryptoComponent crypto) { + this.crypto = crypto; + } + + @Override + public KeyMaterialSource createKeyMaterialSource(SecretKey masterKey, + TransportId t) { + SecretKey sourceKey = crypto.deriveKey(KEY_MATERIAL_LABEL, masterKey, + toUtf8(t.getString())); + return new KeyMaterialSourceImpl(sourceKey); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousModule.java b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousModule.java new file mode 100644 index 000000000..71f9084ec --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousModule.java @@ -0,0 +1,16 @@ +package org.briarproject.bramble.rendezvous; + +import org.briarproject.bramble.api.rendezvous.RendezvousCrypto; + +import dagger.Module; +import dagger.Provides; + +@Module +public class RendezvousModule { + + @Provides + RendezvousCrypto provideKeyMaterialSourceFactory( + RendezvousCryptoImpl keyMaterialSourceFactory) { + return keyMaterialSourceFactory; + } +} diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java index f6449ccc9..980db3af9 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java @@ -13,6 +13,8 @@ import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnect import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.rendezvous.KeyMaterialSource; +import org.briarproject.bramble.api.rendezvous.RendezvousHandler; import java.io.IOException; import java.io.InputStream; @@ -184,6 +186,16 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { throw new UnsupportedOperationException(); } + @Override + public boolean supportsRendezvous() { + return false; + } + + @Override + public RendezvousHandler createRendezvousHandler(KeyMaterialSource k) { + throw new UnsupportedOperationException(); + } + @Override public void incomingCallConnected() { LOG.info("Incoming call connected");