diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java index 5bb975e1a..a5a28e005 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java @@ -11,7 +11,6 @@ import android.content.IntentFilter; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; @@ -30,23 +29,14 @@ import org.briarproject.bramble.util.StringUtils; import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; import java.security.SecureRandom; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import java.util.concurrent.Callable; -import java.util.concurrent.CompletionService; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; @@ -61,8 +51,6 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERA import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE; import static android.bluetooth.BluetoothAdapter.STATE_OFF; import static android.bluetooth.BluetoothAdapter.STATE_ON; -import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH; @@ -79,10 +67,6 @@ class DroidtoothPlugin implements DuplexPlugin { private static final Logger LOG = Logger.getLogger(DroidtoothPlugin.class.getName()); - private static final String FOUND = - "android.bluetooth.device.action.FOUND"; - private static final String DISCOVERY_FINISHED = - "android.bluetooth.adapter.action.DISCOVERY_FINISHED"; private final Executor ioExecutor; private final AndroidExecutor androidExecutor; @@ -374,90 +358,6 @@ class DroidtoothPlugin implements DuplexPlugin { return new DroidtoothTransportConnection(this, s); } - @Override - public boolean supportsInvitations() { - return true; - } - - @Override - public DuplexTransportConnection createInvitationConnection(PseudoRandom r, - long timeout, boolean alice) { - if (!isRunning()) return null; - // Use the invitation codes to generate the UUID - byte[] b = r.nextBytes(UUID_BYTES); - UUID uuid = UUID.nameUUIDFromBytes(b); - if (LOG.isLoggable(INFO)) LOG.info("Invitation UUID " + uuid); - // Bind a server socket for receiving invitation connections - BluetoothServerSocket ss; - try { - ss = adapter.listenUsingInsecureRfcommWithServiceRecord( - "RFCOMM", uuid); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - return null; - } - // Create the background tasks - CompletionService complete = - new ExecutorCompletionService<>(ioExecutor); - List> futures = new ArrayList<>(); - if (alice) { - // Return the first connected socket - futures.add(complete.submit(new ListeningTask(ss))); - futures.add(complete.submit(new DiscoveryTask(uuid.toString()))); - } else { - // Return the first socket with readable data - futures.add(complete.submit(new ReadableTask( - new ListeningTask(ss)))); - futures.add(complete.submit(new ReadableTask( - new DiscoveryTask(uuid.toString())))); - } - BluetoothSocket chosen = null; - try { - Future f = complete.poll(timeout, MILLISECONDS); - if (f == null) return null; // No task completed within the timeout - chosen = f.get(); - return new DroidtoothTransportConnection(this, chosen); - } catch (InterruptedException e) { - LOG.info("Interrupted while exchanging invitations"); - Thread.currentThread().interrupt(); - return null; - } catch (ExecutionException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - return null; - } finally { - // Closing the socket will terminate the listener task - tryToClose(ss); - closeSockets(futures, chosen); - } - } - - private void closeSockets(final List> futures, - @Nullable final BluetoothSocket chosen) { - ioExecutor.execute(new Runnable() { - @Override - public void run() { - for (Future f : futures) { - try { - if (f.cancel(true)) { - LOG.info("Cancelled task"); - } else { - BluetoothSocket s = f.get(); - if (s != null && s != chosen) { - LOG.info("Closing unwanted socket"); - s.close(); - } - } - } catch (InterruptedException e) { - LOG.info("Interrupted while closing sockets"); - return; - } catch (ExecutionException | IOException e) { - if (LOG.isLoggable(INFO)) LOG.info(e.toString()); - } - } - } - }); - } - @Override public boolean supportsKeyAgreement() { return true; @@ -472,7 +372,7 @@ class DroidtoothPlugin implements DuplexPlugin { // No truncation necessary because COMMIT_LENGTH = 16 UUID uuid = UUID.nameUUIDFromBytes(commitment); if (LOG.isLoggable(INFO)) LOG.info("Key agreement UUID " + uuid); - // Bind a server socket for receiving invitation connections + // Bind a server socket for receiving key agreement connections BluetoothServerSocket ss; try { ss = adapter.listenUsingInsecureRfcommWithServiceRecord( @@ -536,115 +436,6 @@ class DroidtoothPlugin implements DuplexPlugin { } } - private class DiscoveryTask implements Callable { - - private final String uuid; - - private DiscoveryTask(String uuid) { - this.uuid = uuid; - } - - @Override - public BluetoothSocket call() throws Exception { - // Repeat discovery until we connect or get interrupted - while (true) { - // Discover nearby devices - LOG.info("Discovering nearby devices"); - List addresses = discoverDevices(); - if (addresses.isEmpty()) { - LOG.info("No devices discovered"); - continue; - } - // Connect to any device with the right UUID - for (String address : addresses) { - BluetoothSocket s = connect(address, uuid); - if (s != null) { - LOG.info("Outgoing connection"); - return s; - } - } - } - } - - private List discoverDevices() throws InterruptedException { - IntentFilter filter = new IntentFilter(); - filter.addAction(FOUND); - filter.addAction(DISCOVERY_FINISHED); - DiscoveryReceiver disco = new DiscoveryReceiver(); - appContext.registerReceiver(disco, filter); - LOG.info("Starting discovery"); - adapter.startDiscovery(); - return disco.waitForAddresses(); - } - } - - private static class DiscoveryReceiver extends BroadcastReceiver { - - private final CountDownLatch finished = new CountDownLatch(1); - private final List addresses = new CopyOnWriteArrayList<>(); - - @Override - public void onReceive(Context ctx, Intent intent) { - String action = intent.getAction(); - if (action.equals(DISCOVERY_FINISHED)) { - LOG.info("Discovery finished"); - ctx.unregisterReceiver(this); - finished.countDown(); - } else if (action.equals(FOUND)) { - BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE); - if (LOG.isLoggable(INFO)) { - LOG.info("Discovered device: " + - scrubMacAddress(d.getAddress())); - } - addresses.add(d.getAddress()); - } - } - - private List waitForAddresses() throws InterruptedException { - finished.await(); - List shuffled = new ArrayList<>(addresses); - Collections.shuffle(shuffled); - return shuffled; - } - } - - private static class ListeningTask implements Callable { - - private final BluetoothServerSocket serverSocket; - - private ListeningTask(BluetoothServerSocket serverSocket) { - this.serverSocket = serverSocket; - } - - @Override - public BluetoothSocket call() throws IOException { - BluetoothSocket s = serverSocket.accept(); - LOG.info("Incoming connection"); - return s; - } - } - - private static class ReadableTask implements Callable { - - private final Callable connectionTask; - - private ReadableTask(Callable connectionTask) { - this.connectionTask = connectionTask; - } - - @Override - public BluetoothSocket call() throws Exception { - BluetoothSocket s = connectionTask.call(); - InputStream in = s.getInputStream(); - while (in.available() == 0) { - LOG.info("Waiting for data"); - Thread.sleep(1000); - } - LOG.info("Data available"); - return s; - } - } - private class BluetoothKeyAgreementListener extends KeyAgreementListener { private final BluetoothServerSocket ss; diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 9c3609ed6..69eb13d5a 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -17,7 +17,6 @@ import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.TorControlConnection; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; @@ -589,17 +588,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } } - @Override - public boolean supportsInvitations() { - return false; - } - - @Override - public DuplexTransportConnection createInvitationConnection(PseudoRandom r, - long timeout, boolean alice) { - throw new UnsupportedOperationException(); - } - @Override public boolean supportsKeyAgreement() { return false; diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java index 3d610c850..9579e2e9c 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java @@ -10,8 +10,6 @@ public interface CryptoComponent { SecretKey generateSecretKey(); - PseudoRandom getPseudoRandom(int seed1, int seed2); - SecureRandom getSecureRandom(); KeyPair generateAgreementKeyPair(); @@ -24,15 +22,6 @@ public interface CryptoComponent { KeyParser getMessageKeyParser(); - /** Generates a random invitation code. */ - int generateBTInvitationCode(); - - /** - * Derives a confirmation code from the given master secret. - * @param alice whether the code is for use by Alice or Bob. - */ - int deriveBTConfirmationCode(SecretKey master, boolean alice); - /** * Derives a stream header key from the given master secret. * @param alice whether the key is for use by Alice or Bob. diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PseudoRandom.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PseudoRandom.java deleted file mode 100644 index 8e61027d6..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PseudoRandom.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.briarproject.bramble.api.crypto; - -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -/** - * A deterministic pseudo-random number generator. - */ -@NotNullByDefault -public interface PseudoRandom { - - byte[] nextBytes(int bytes); -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamDecrypterFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamDecrypterFactory.java index b07c3239a..beecd1789 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamDecrypterFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamDecrypterFactory.java @@ -14,8 +14,9 @@ public interface StreamDecrypterFactory { StreamDecrypter createStreamDecrypter(InputStream in, StreamContext ctx); /** - * Creates a {@link StreamDecrypter} for decrypting an invitation stream. + * Creates a {@link StreamDecrypter} for decrypting a contact exchange + * stream. */ - StreamDecrypter createInvitationStreamDecrypter(InputStream in, + StreamDecrypter createContactExchangeStreamDecrypter(InputStream in, SecretKey headerKey); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamEncrypterFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamEncrypterFactory.java index 743401337..03ad5e143 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamEncrypterFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/StreamEncrypterFactory.java @@ -14,8 +14,9 @@ public interface StreamEncrypterFactory { StreamEncrypter createStreamEncrypter(OutputStream out, StreamContext ctx); /** - * Creates a {@link StreamEncrypter} for encrypting an invitation stream. + * Creates a {@link StreamEncrypter} for encrypting a contact exchange + * stream. */ - StreamEncrypter createInvitationStreamEncrypter(OutputStream out, + StreamEncrypter createContactExchangeStreamDecrypter(OutputStream out, SecretKey headerKey); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationConstants.java deleted file mode 100644 index f7c6ed331..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationConstants.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.briarproject.bramble.api.invitation; - -public interface InvitationConstants { - - /** - * The connection timeout in milliseconds. - */ - long CONNECTION_TIMEOUT = 60 * 1000; - - /** - * The confirmation timeout in milliseconds. - */ - long CONFIRMATION_TIMEOUT = 60 * 1000; - - /** - * The number of bits in an invitation or confirmation code. Codes must fit - * into six decimal digits. - */ - int CODE_BITS = 19; -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationListener.java b/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationListener.java deleted file mode 100644 index acf545f1a..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationListener.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.briarproject.bramble.api.invitation; - -/** - * An interface for receiving updates about the state of an - * {@link InvitationTask}. - */ -public interface InvitationListener { - - /** Called if a connection to the remote peer is established. */ - void connectionSucceeded(); - - /** - * Called if a connection to the remote peer cannot be established. This - * indicates that the protocol has ended unsuccessfully. - */ - void connectionFailed(); - - /** Called if key agreement with the remote peer succeeds. */ - void keyAgreementSucceeded(int localCode, int remoteCode); - - /** - * Called if key agreement with the remote peer fails or the connection is - * lost. This indicates that the protocol has ended unsuccessfully. - */ - void keyAgreementFailed(); - - /** Called if the remote peer's confirmation check succeeds. */ - void remoteConfirmationSucceeded(); - - /** - * Called if remote peer's confirmation check fails or the connection is - * lost. This indicates that the protocol has ended unsuccessfully. - */ - void remoteConfirmationFailed(); - - /** - * Called if the exchange of pseudonyms succeeds. This indicates that the - * protocol has ended successfully. - */ - void pseudonymExchangeSucceeded(String remoteName); - - /** - * Called if the exchange of pseudonyms fails or the connection is lost. - * This indicates that the protocol has ended unsuccessfully. - */ - void pseudonymExchangeFailed(); -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationState.java b/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationState.java deleted file mode 100644 index 456230837..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationState.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.briarproject.bramble.api.invitation; - -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A snapshot of the state of an {@link InvitationTask}. - */ -@Immutable -@NotNullByDefault -public class InvitationState { - - private final int localInvitationCode, remoteInvitationCode; - private final int localConfirmationCode, remoteConfirmationCode; - private final boolean connected, connectionFailed; - private final boolean localCompared, remoteCompared; - private final boolean localMatched, remoteMatched; - @Nullable - private final String contactName; - - public InvitationState(int localInvitationCode, int remoteInvitationCode, - int localConfirmationCode, int remoteConfirmationCode, - boolean connected, boolean connectionFailed, boolean localCompared, - boolean remoteCompared, boolean localMatched, - boolean remoteMatched, @Nullable String contactName) { - this.localInvitationCode = localInvitationCode; - this.remoteInvitationCode = remoteInvitationCode; - this.localConfirmationCode = localConfirmationCode; - this.remoteConfirmationCode = remoteConfirmationCode; - this.connected = connected; - this.connectionFailed = connectionFailed; - this.localCompared = localCompared; - this.remoteCompared = remoteCompared; - this.localMatched = localMatched; - this.remoteMatched = remoteMatched; - this.contactName = contactName; - } - - public int getLocalInvitationCode() { - return localInvitationCode; - } - - public int getRemoteInvitationCode() { - return remoteInvitationCode; - } - - public int getLocalConfirmationCode() { - return localConfirmationCode; - } - - public int getRemoteConfirmationCode() { - return remoteConfirmationCode; - } - - public boolean getConnected() { - return connected; - } - - public boolean getConnectionFailed() { - return connectionFailed; - } - - public boolean getLocalCompared() { - return localCompared; - } - - public boolean getRemoteCompared() { - return remoteCompared; - } - - public boolean getLocalMatched() { - return localMatched; - } - - public boolean getRemoteMatched() { - return remoteMatched; - } - - @Nullable - public String getContactName() { - return contactName; - } -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTask.java b/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTask.java deleted file mode 100644 index b09d940f3..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTask.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.briarproject.bramble.api.invitation; - -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -/** - * A task for exchanging invitations with a remote peer. - */ -@NotNullByDefault -public interface InvitationTask { - - /** - * Adds a listener to be informed of state changes and returns the - * task's current state. - */ - InvitationState addListener(InvitationListener l); - - /** - * Removes the given listener. - */ - void removeListener(InvitationListener l); - - /** - * Asynchronously starts the connection process. - */ - void connect(); - - /** - * Asynchronously informs the remote peer that the local peer's - * confirmation codes matched. - */ - void localConfirmationSucceeded(); - - /** - * Asynchronously informs the remote peer that the local peer's - * confirmation codes did not match. - */ - void localConfirmationFailed(); -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTaskFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTaskFactory.java deleted file mode 100644 index 76f94908a..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTaskFactory.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.briarproject.bramble.api.invitation; - -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -/** - * Creates tasks for exchanging invitations with remote peers. - */ -@NotNullByDefault -public interface InvitationTaskFactory { - - /** - * Creates a task using the given local and remote invitation codes. - */ - InvitationTask createTask(int localCode, int remoteCode); -} 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 1056a6438..32c3a8012 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 @@ -32,11 +32,6 @@ public interface PluginManager { */ Collection getDuplexPlugins(); - /** - * Returns any duplex plugins that support invitations. - */ - Collection getInvitationPlugins(); - /** * Returns any duplex plugins that support key agreement. */ 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 f2c2027f9..83fc64248 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 @@ -1,7 +1,6 @@ package org.briarproject.bramble.api.plugin.duplex; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @@ -23,20 +22,6 @@ public interface DuplexPlugin extends Plugin { @Nullable DuplexTransportConnection createConnection(ContactId c); - /** - * Returns true if the plugin supports exchanging invitations. - */ - boolean supportsInvitations(); - - /** - * Attempts to create and return an invitation connection to the remote - * peer. Returns null if no connection can be established within the given - * time. - */ - @Nullable - DuplexTransportConnection createInvitationConnection(PseudoRandom r, - long timeout, boolean alice); - /** * Returns true if the plugin supports short-range key agreement. */ diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamReaderFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamReaderFactory.java index 44e31a671..87823679b 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamReaderFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamReaderFactory.java @@ -15,9 +15,9 @@ public interface StreamReaderFactory { InputStream createStreamReader(InputStream in, StreamContext ctx); /** - * Creates an {@link InputStream InputStream} for reading from an - * invitation stream. + * Creates an {@link InputStream InputStream} for reading from a contact + * exchangestream. */ - InputStream createInvitationStreamReader(InputStream in, + InputStream createContactExchangeStreamReader(InputStream in, SecretKey headerKey); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamWriterFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamWriterFactory.java index 134bde50e..3277acee0 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamWriterFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/transport/StreamWriterFactory.java @@ -15,9 +15,9 @@ public interface StreamWriterFactory { OutputStream createStreamWriter(OutputStream out, StreamContext ctx); /** - * Creates an {@link OutputStream OutputStream} for writing to an - * invitation stream. + * Creates an {@link OutputStream OutputStream} for writing to a contact + * exchange stream. */ - OutputStream createInvitationStreamWriter(OutputStream out, + OutputStream createContactExchangeStreamWriter(OutputStream out, SecretKey headerKey); } 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 eb9c2eb5d..365b50de9 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java @@ -8,7 +8,6 @@ import org.briarproject.bramble.db.DatabaseExecutorModule; import org.briarproject.bramble.db.DatabaseModule; import org.briarproject.bramble.event.EventModule; import org.briarproject.bramble.identity.IdentityModule; -import org.briarproject.bramble.invitation.InvitationModule; import org.briarproject.bramble.keyagreement.KeyAgreementModule; import org.briarproject.bramble.lifecycle.LifecycleModule; import org.briarproject.bramble.plugin.PluginModule; @@ -32,7 +31,6 @@ import dagger.Module; DatabaseExecutorModule.class, EventModule.class, IdentityModule.class, - InvitationModule.class, KeyAgreementModule.class, LifecycleModule.class, PluginModule.class, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java index e33b1deb0..d97c8c9ee 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java @@ -80,7 +80,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask { private volatile boolean alice; @Inject - public ContactExchangeTaskImpl(DatabaseComponent db, + ContactExchangeTaskImpl(DatabaseComponent db, AuthorFactory authorFactory, BdfReaderFactory bdfReaderFactory, BdfWriterFactory bdfWriterFactory, Clock clock, ConnectionManager connectionManager, ContactManager contactManager, @@ -146,12 +146,12 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask { // Create the readers InputStream streamReader = - streamReaderFactory.createInvitationStreamReader(in, + streamReaderFactory.createContactExchangeStreamReader(in, alice ? bobHeaderKey : aliceHeaderKey); BdfReader r = bdfReaderFactory.createReader(streamReader); // Create the writers OutputStream streamWriter = - streamWriterFactory.createInvitationStreamWriter(out, + streamWriterFactory.createContactExchangeStreamWriter(out, alice ? aliceHeaderKey : bobHeaderKey); BdfWriter w = bdfWriterFactory.createWriter(streamWriter); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java index f0c26edd9..6c97f1c2c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java @@ -4,7 +4,6 @@ import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyParser; import org.briarproject.bramble.api.crypto.PrivateKey; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.plugin.TransportId; @@ -41,7 +40,6 @@ import java.util.logging.Logger; import javax.inject.Inject; import static java.util.logging.Level.INFO; -import static org.briarproject.bramble.api.invitation.InvitationConstants.CODE_BITS; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.bramble.crypto.EllipticCurveConstants.PARAMETERS; @@ -68,9 +66,6 @@ class CryptoComponentImpl implements CryptoComponent { return s.getBytes(Charset.forName("US-ASCII")); } - // KDF labels for bluetooth confirmation code derivation - private static final byte[] BT_A_CONFIRM = ascii("ALICE_CONFIRMATION_CODE"); - private static final byte[] BT_B_CONFIRM = ascii("BOB_CONFIRMATION_CODE"); // KDF labels for contact exchange stream header key derivation private static final byte[] A_INVITE = ascii("ALICE_INVITATION_KEY"); private static final byte[] B_INVITE = ascii("BOB_INVITATION_KEY"); @@ -171,14 +166,6 @@ class CryptoComponentImpl implements CryptoComponent { return new SecretKey(b); } - @Override - public PseudoRandom getPseudoRandom(int seed1, int seed2) { - byte[] seed = new byte[INT_32_BYTES * 2]; - ByteUtils.writeUint32(seed1, seed, 0); - ByteUtils.writeUint32(seed2, seed, INT_32_BYTES); - return new PseudoRandomImpl(seed); - } - @Override public SecureRandom getSecureRandom() { return secureRandom; @@ -250,20 +237,6 @@ class CryptoComponentImpl implements CryptoComponent { return messageEncrypter.getKeyParser(); } - @Override - public int generateBTInvitationCode() { - int codeBytes = (CODE_BITS + 7) / 8; - byte[] random = new byte[codeBytes]; - secureRandom.nextBytes(random); - return ByteUtils.readUint(random, CODE_BITS); - } - - @Override - public int deriveBTConfirmationCode(SecretKey master, boolean alice) { - byte[] b = macKdf(master, alice ? BT_A_CONFIRM : BT_B_CONFIRM); - return ByteUtils.readUint(b, CODE_BITS); - } - @Override public SecretKey deriveHeaderKey(SecretKey master, boolean alice) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamDecrypterFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamDecrypterFactoryImpl.java index 49fd6ba2e..aac3e504e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamDecrypterFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamDecrypterFactoryImpl.java @@ -32,7 +32,7 @@ class StreamDecrypterFactoryImpl implements StreamDecrypterFactory { } @Override - public StreamDecrypter createInvitationStreamDecrypter(InputStream in, + public StreamDecrypter createContactExchangeStreamDecrypter(InputStream in, SecretKey headerKey) { return new StreamDecrypterImpl(in, cipherProvider.get(), 0, headerKey); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterFactoryImpl.java index be7f553de..0d9b4a0fc 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterFactoryImpl.java @@ -46,8 +46,8 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory { } @Override - public StreamEncrypter createInvitationStreamEncrypter(OutputStream out, - SecretKey headerKey) { + public StreamEncrypter createContactExchangeStreamDecrypter( + OutputStream out, SecretKey headerKey) { AuthenticatedCipher cipher = cipherProvider.get(); byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH]; crypto.getSecureRandom().nextBytes(streamHeaderNonce); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/invitation/AliceConnector.java b/bramble-core/src/main/java/org/briarproject/bramble/invitation/AliceConnector.java deleted file mode 100644 index 871db9b4c..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/invitation/AliceConnector.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.briarproject.bramble.invitation; - -import org.briarproject.bramble.api.contact.ContactExchangeTask; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.PseudoRandom; -import org.briarproject.bramble.api.crypto.SecretKey; -import org.briarproject.bramble.api.data.BdfReader; -import org.briarproject.bramble.api.data.BdfReaderFactory; -import org.briarproject.bramble.api.data.BdfWriter; -import org.briarproject.bramble.api.data.BdfWriterFactory; -import org.briarproject.bramble.api.identity.LocalAuthor; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.util.logging.Logger; - -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; - -/** - * A connection thread for the peer being Alice in the invitation protocol. - */ -@NotNullByDefault -class AliceConnector extends Connector { - - private static final Logger LOG = - Logger.getLogger(AliceConnector.class.getName()); - - AliceConnector(CryptoComponent crypto, BdfReaderFactory bdfReaderFactory, - BdfWriterFactory bdfWriterFactory, - ContactExchangeTask contactExchangeTask, ConnectorGroup group, - DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) { - super(crypto, bdfReaderFactory, bdfWriterFactory, contactExchangeTask, - group, plugin, localAuthor, random); - } - - @Override - public void run() { - // Create an incoming or outgoing connection - DuplexTransportConnection conn = createInvitationConnection(true); - if (conn == null) return; - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " connected"); - // Don't proceed with more than one connection - if (group.getAndSetConnected()) { - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " redundant"); - tryToClose(conn, false); - return; - } - // Carry out the key agreement protocol - InputStream in; - OutputStream out; - BdfReader r; - BdfWriter w; - SecretKey master; - try { - in = conn.getReader().getInputStream(); - out = conn.getWriter().getOutputStream(); - r = bdfReaderFactory.createReader(in); - w = bdfWriterFactory.createWriter(out); - // Alice goes first - sendPublicKeyHash(w); - byte[] hash = receivePublicKeyHash(r); - sendPublicKey(w); - byte[] key = receivePublicKey(r); - master = deriveMasterSecret(hash, key, true); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - group.keyAgreementFailed(); - tryToClose(conn, true); - return; - } catch (GeneralSecurityException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - group.keyAgreementFailed(); - tryToClose(conn, true); - return; - } - // The key agreement succeeded - derive the confirmation codes - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded"); - int aliceCode = crypto.deriveBTConfirmationCode(master, true); - int bobCode = crypto.deriveBTConfirmationCode(master, false); - group.keyAgreementSucceeded(aliceCode, bobCode); - // Exchange confirmation results - boolean localMatched, remoteMatched; - try { - localMatched = group.waitForLocalConfirmationResult(); - sendConfirmation(w, localMatched); - remoteMatched = receiveConfirmation(r); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - group.remoteConfirmationFailed(); - tryToClose(conn, true); - return; - } catch (InterruptedException e) { - LOG.warning("Interrupted while waiting for confirmation"); - group.remoteConfirmationFailed(); - tryToClose(conn, true); - Thread.currentThread().interrupt(); - return; - } - if (remoteMatched) group.remoteConfirmationSucceeded(); - else group.remoteConfirmationFailed(); - if (!(localMatched && remoteMatched)) { - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " confirmation failed"); - tryToClose(conn, false); - return; - } - // Confirmation succeeded - upgrade to a secure connection - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " confirmation succeeded"); - contactExchangeTask.startExchange(group, localAuthor, master, conn, - plugin.getId(), true); - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/invitation/BobConnector.java b/bramble-core/src/main/java/org/briarproject/bramble/invitation/BobConnector.java deleted file mode 100644 index d87a9334a..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/invitation/BobConnector.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.briarproject.bramble.invitation; - -import org.briarproject.bramble.api.contact.ContactExchangeTask; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.PseudoRandom; -import org.briarproject.bramble.api.crypto.SecretKey; -import org.briarproject.bramble.api.data.BdfReader; -import org.briarproject.bramble.api.data.BdfReaderFactory; -import org.briarproject.bramble.api.data.BdfWriter; -import org.briarproject.bramble.api.data.BdfWriterFactory; -import org.briarproject.bramble.api.identity.LocalAuthor; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.util.logging.Logger; - -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; - -/** - * A connection thread for the peer being Bob in the invitation protocol. - */ -@NotNullByDefault -class BobConnector extends Connector { - - private static final Logger LOG = - Logger.getLogger(BobConnector.class.getName()); - - BobConnector(CryptoComponent crypto, BdfReaderFactory bdfReaderFactory, - BdfWriterFactory bdfWriterFactory, - ContactExchangeTask contactExchangeTask, ConnectorGroup group, - DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) { - super(crypto, bdfReaderFactory, bdfWriterFactory, contactExchangeTask, - group, plugin, localAuthor, random); - } - - @Override - public void run() { - // Create an incoming or outgoing connection - DuplexTransportConnection conn = createInvitationConnection(false); - if (conn == null) return; - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " connected"); - // Carry out the key agreement protocol - InputStream in; - OutputStream out; - BdfReader r; - BdfWriter w; - SecretKey master; - try { - in = conn.getReader().getInputStream(); - out = conn.getWriter().getOutputStream(); - r = bdfReaderFactory.createReader(in); - w = bdfWriterFactory.createWriter(out); - // Alice goes first - byte[] hash = receivePublicKeyHash(r); - // Don't proceed with more than one connection - if (group.getAndSetConnected()) { - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " redundant"); - tryToClose(conn, false); - return; - } - sendPublicKeyHash(w); - byte[] key = receivePublicKey(r); - sendPublicKey(w); - master = deriveMasterSecret(hash, key, false); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - group.keyAgreementFailed(); - tryToClose(conn, true); - return; - } catch (GeneralSecurityException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - group.keyAgreementFailed(); - tryToClose(conn, true); - return; - } - // The key agreement succeeded - derive the confirmation codes - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded"); - int aliceCode = crypto.deriveBTConfirmationCode(master, true); - int bobCode = crypto.deriveBTConfirmationCode(master, false); - group.keyAgreementSucceeded(bobCode, aliceCode); - // Exchange confirmation results - boolean localMatched, remoteMatched; - try { - remoteMatched = receiveConfirmation(r); - localMatched = group.waitForLocalConfirmationResult(); - sendConfirmation(w, localMatched); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - group.remoteConfirmationFailed(); - tryToClose(conn, true); - return; - } catch (InterruptedException e) { - LOG.warning("Interrupted while waiting for confirmation"); - group.remoteConfirmationFailed(); - tryToClose(conn, true); - Thread.currentThread().interrupt(); - return; - } - if (remoteMatched) group.remoteConfirmationSucceeded(); - else group.remoteConfirmationFailed(); - if (!(localMatched && remoteMatched)) { - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " confirmation failed"); - tryToClose(conn, false); - return; - } - // Confirmation succeeded - upgrade to a secure connection - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " confirmation succeeded"); - contactExchangeTask.startExchange(group, localAuthor, master, conn, - plugin.getId(), false); - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/invitation/Connector.java b/bramble-core/src/main/java/org/briarproject/bramble/invitation/Connector.java deleted file mode 100644 index 4c1a63c67..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/invitation/Connector.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.briarproject.bramble.invitation; - -import org.briarproject.bramble.api.FormatException; -import org.briarproject.bramble.api.contact.ContactExchangeTask; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.KeyPair; -import org.briarproject.bramble.api.crypto.KeyParser; -import org.briarproject.bramble.api.crypto.PseudoRandom; -import org.briarproject.bramble.api.crypto.SecretKey; -import org.briarproject.bramble.api.data.BdfReader; -import org.briarproject.bramble.api.data.BdfReaderFactory; -import org.briarproject.bramble.api.data.BdfWriter; -import org.briarproject.bramble.api.data.BdfWriterFactory; -import org.briarproject.bramble.api.identity.LocalAuthor; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.Arrays; -import java.util.logging.Logger; - -import javax.annotation.Nullable; - -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; -import static org.briarproject.bramble.api.invitation.InvitationConstants.CONNECTION_TIMEOUT; - -// FIXME: This class has way too many dependencies -@NotNullByDefault -abstract class Connector extends Thread { - - private static final Logger LOG = - Logger.getLogger(Connector.class.getName()); - private static final String LABEL_PUBLIC_KEY = - "org.briarproject.bramble.invitation.PUBLIC_KEY"; - - protected final CryptoComponent crypto; - protected final BdfReaderFactory bdfReaderFactory; - protected final BdfWriterFactory bdfWriterFactory; - protected final ContactExchangeTask contactExchangeTask; - protected final ConnectorGroup group; - protected final DuplexPlugin plugin; - protected final LocalAuthor localAuthor; - protected final PseudoRandom random; - protected final String pluginName; - - private final KeyPair keyPair; - private final KeyParser keyParser; - - Connector(CryptoComponent crypto, BdfReaderFactory bdfReaderFactory, - BdfWriterFactory bdfWriterFactory, - ContactExchangeTask contactExchangeTask, ConnectorGroup group, - DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) { - super("Connector"); - this.crypto = crypto; - this.bdfReaderFactory = bdfReaderFactory; - this.bdfWriterFactory = bdfWriterFactory; - this.contactExchangeTask = contactExchangeTask; - this.group = group; - this.plugin = plugin; - this.localAuthor = localAuthor; - this.random = random; - pluginName = plugin.getClass().getName(); - keyPair = crypto.generateAgreementKeyPair(); - keyParser = crypto.getAgreementKeyParser(); - } - - @Nullable - DuplexTransportConnection createInvitationConnection(boolean alice) { - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " creating invitation connection"); - return plugin.createInvitationConnection(random, CONNECTION_TIMEOUT, - alice); - } - - void sendPublicKeyHash(BdfWriter w) throws IOException { - byte[] hash = - crypto.hash(LABEL_PUBLIC_KEY, keyPair.getPublic().getEncoded()); - w.writeRaw(hash); - w.flush(); - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " sent hash"); - } - - byte[] receivePublicKeyHash(BdfReader r) throws IOException { - int hashLength = crypto.getHashLength(); - byte[] b = r.readRaw(hashLength); - if (b.length < hashLength) throw new FormatException(); - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash"); - return b; - } - - void sendPublicKey(BdfWriter w) throws IOException { - byte[] key = keyPair.getPublic().getEncoded(); - w.writeRaw(key); - w.flush(); - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " sent key"); - } - - byte[] receivePublicKey(BdfReader r) - throws GeneralSecurityException, IOException { - byte[] b = r.readRaw(MAX_PUBLIC_KEY_LENGTH); - keyParser.parsePublicKey(b); - if (LOG.isLoggable(INFO)) LOG.info(pluginName + " received key"); - return b; - } - - SecretKey deriveMasterSecret(byte[] hash, byte[] key, boolean alice) - throws GeneralSecurityException { - // Check that the hash matches the key - byte[] keyHash = - crypto.hash(LABEL_PUBLIC_KEY, keyPair.getPublic().getEncoded()); - if (!Arrays.equals(hash, keyHash)) { - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " hash does not match key"); - throw new GeneralSecurityException(); - } - // Derive the master secret - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " deriving master secret"); - return crypto.deriveMasterSecret(key, keyPair, alice); - } - - void sendConfirmation(BdfWriter w, boolean confirmed) throws IOException { - w.writeBoolean(confirmed); - w.flush(); - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " sent confirmation: " + confirmed); - } - - boolean receiveConfirmation(BdfReader r) throws IOException { - boolean confirmed = r.readBoolean(); - if (LOG.isLoggable(INFO)) - LOG.info(pluginName + " received confirmation: " + confirmed); - return confirmed; - } - - protected void tryToClose(DuplexTransportConnection conn, - boolean exception) { - try { - LOG.info("Closing connection"); - conn.getReader().dispose(exception, true); - conn.getWriter().dispose(exception); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/invitation/ConnectorGroup.java b/bramble-core/src/main/java/org/briarproject/bramble/invitation/ConnectorGroup.java deleted file mode 100644 index 103dd03c6..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/invitation/ConnectorGroup.java +++ /dev/null @@ -1,278 +0,0 @@ -package org.briarproject.bramble.invitation; - -import org.briarproject.bramble.api.contact.ContactExchangeListener; -import org.briarproject.bramble.api.contact.ContactExchangeTask; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.PseudoRandom; -import org.briarproject.bramble.api.data.BdfReaderFactory; -import org.briarproject.bramble.api.data.BdfWriterFactory; -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.identity.Author; -import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.identity.LocalAuthor; -import org.briarproject.bramble.api.invitation.InvitationListener; -import org.briarproject.bramble.api.invitation.InvitationState; -import org.briarproject.bramble.api.invitation.InvitationTask; -import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; -import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.bramble.api.plugin.PluginManager; -import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.logging.Logger; - -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.logging.Level.WARNING; -import static org.briarproject.bramble.api.invitation.InvitationConstants.CONFIRMATION_TIMEOUT; - -/** - * A task consisting of one or more parallel connection attempts. - */ -@MethodsNotNullByDefault -@ParametersNotNullByDefault -class ConnectorGroup extends Thread implements InvitationTask, - ContactExchangeListener { - - private static final Logger LOG = - Logger.getLogger(ConnectorGroup.class.getName()); - - private final CryptoComponent crypto; - private final BdfReaderFactory bdfReaderFactory; - private final BdfWriterFactory bdfWriterFactory; - private final ContactExchangeTask contactExchangeTask; - private final IdentityManager identityManager; - private final PluginManager pluginManager; - private final int localInvitationCode, remoteInvitationCode; - private final Collection listeners; - private final AtomicBoolean connected; - private final CountDownLatch localConfirmationLatch; - private final Lock lock = new ReentrantLock(); - - // The following are locking: lock - private int localConfirmationCode = -1, remoteConfirmationCode = -1; - private boolean connectionFailed = false; - private boolean localCompared = false, remoteCompared = false; - private boolean localMatched = false, remoteMatched = false; - private String remoteName = null; - - ConnectorGroup(CryptoComponent crypto, BdfReaderFactory bdfReaderFactory, - BdfWriterFactory bdfWriterFactory, - ContactExchangeTask contactExchangeTask, - IdentityManager identityManager, PluginManager pluginManager, - int localInvitationCode, int remoteInvitationCode) { - super("ConnectorGroup"); - this.crypto = crypto; - this.bdfReaderFactory = bdfReaderFactory; - this.bdfWriterFactory = bdfWriterFactory; - this.contactExchangeTask = contactExchangeTask; - this.identityManager = identityManager; - this.pluginManager = pluginManager; - this.localInvitationCode = localInvitationCode; - this.remoteInvitationCode = remoteInvitationCode; - listeners = new CopyOnWriteArrayList(); - connected = new AtomicBoolean(false); - localConfirmationLatch = new CountDownLatch(1); - } - - @Override - public InvitationState addListener(InvitationListener l) { - lock.lock(); - try { - listeners.add(l); - return new InvitationState(localInvitationCode, - remoteInvitationCode, localConfirmationCode, - remoteConfirmationCode, connected.get(), connectionFailed, - localCompared, remoteCompared, localMatched, remoteMatched, - remoteName); - } finally { - lock.unlock(); - } - } - - @Override - public void removeListener(InvitationListener l) { - listeners.remove(l); - } - - @Override - public void connect() { - start(); - } - - @Override - public void run() { - LocalAuthor localAuthor; - // Load the local pseudonym - try { - localAuthor = identityManager.getLocalAuthor(); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - lock.lock(); - try { - connectionFailed = true; - } finally { - lock.unlock(); - } - for (InvitationListener l : listeners) l.connectionFailed(); - return; - } - // Start the connection threads - Collection connectors = new ArrayList(); - // Alice is the party with the smaller invitation code - if (localInvitationCode < remoteInvitationCode) { - for (DuplexPlugin plugin : pluginManager.getInvitationPlugins()) { - Connector c = createAliceConnector(plugin, localAuthor); - connectors.add(c); - c.start(); - } - } else { - for (DuplexPlugin plugin : pluginManager.getInvitationPlugins()) { - Connector c = createBobConnector(plugin, localAuthor); - connectors.add(c); - c.start(); - } - } - // Wait for the connection threads to finish - try { - for (Connector c : connectors) c.join(); - } catch (InterruptedException e) { - LOG.warning("Interrupted while waiting for connectors"); - Thread.currentThread().interrupt(); - } - // If none of the threads connected, inform the listeners - if (!connected.get()) { - lock.lock(); - try { - connectionFailed = true; - } finally { - lock.unlock(); - } - for (InvitationListener l : listeners) l.connectionFailed(); - } - } - - private Connector createAliceConnector(DuplexPlugin plugin, - LocalAuthor localAuthor) { - PseudoRandom random = crypto.getPseudoRandom(localInvitationCode, - remoteInvitationCode); - return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory, - contactExchangeTask, this, plugin, localAuthor, random); - } - - private Connector createBobConnector(DuplexPlugin plugin, - LocalAuthor localAuthor) { - PseudoRandom random = crypto.getPseudoRandom(remoteInvitationCode, - localInvitationCode); - return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory, - contactExchangeTask, this, plugin, localAuthor, random); - } - - @Override - public void localConfirmationSucceeded() { - lock.lock(); - try { - localCompared = true; - localMatched = true; - } finally { - lock.unlock(); - } - localConfirmationLatch.countDown(); - } - - @Override - public void localConfirmationFailed() { - lock.lock(); - try { - localCompared = true; - localMatched = false; - } finally { - lock.unlock(); - } - localConfirmationLatch.countDown(); - } - - boolean getAndSetConnected() { - boolean redundant = connected.getAndSet(true); - if (!redundant) - for (InvitationListener l : listeners) l.connectionSucceeded(); - return redundant; - } - - void keyAgreementSucceeded(int localCode, int remoteCode) { - lock.lock(); - try { - localConfirmationCode = localCode; - remoteConfirmationCode = remoteCode; - } finally { - lock.unlock(); - } - for (InvitationListener l : listeners) - l.keyAgreementSucceeded(localCode, remoteCode); - } - - void keyAgreementFailed() { - for (InvitationListener l : listeners) l.keyAgreementFailed(); - } - - boolean waitForLocalConfirmationResult() throws InterruptedException { - localConfirmationLatch.await(CONFIRMATION_TIMEOUT, MILLISECONDS); - lock.lock(); - try { - return localMatched; - } finally { - lock.unlock(); - } - } - - void remoteConfirmationSucceeded() { - lock.lock(); - try { - remoteCompared = true; - remoteMatched = true; - } finally { - lock.unlock(); - } - for (InvitationListener l : listeners) l.remoteConfirmationSucceeded(); - } - - void remoteConfirmationFailed() { - lock.lock(); - try { - remoteCompared = true; - remoteMatched = false; - } finally { - lock.unlock(); - } - for (InvitationListener l : listeners) l.remoteConfirmationFailed(); - } - - @Override - public void contactExchangeSucceeded(Author remoteAuthor) { - String name = remoteAuthor.getName(); - lock.lock(); - try { - remoteName = name; - } finally { - lock.unlock(); - } - for (InvitationListener l : listeners) - l.pseudonymExchangeSucceeded(name); - } - - @Override - public void duplicateContact(Author remoteAuthor) { - // TODO differentiate - for (InvitationListener l : listeners) l.pseudonymExchangeFailed(); - } - - @Override - public void contactExchangeFailed() { - for (InvitationListener l : listeners) l.pseudonymExchangeFailed(); - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationModule.java b/bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationModule.java deleted file mode 100644 index 0c6dbcfac..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationModule.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.briarproject.bramble.invitation; - -import org.briarproject.bramble.api.invitation.InvitationTaskFactory; - -import dagger.Module; -import dagger.Provides; - -@Module -public class InvitationModule { - - @Provides - InvitationTaskFactory provideInvitationTaskFactory( - InvitationTaskFactoryImpl invitationTaskFactory) { - return invitationTaskFactory; - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationTaskFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationTaskFactoryImpl.java deleted file mode 100644 index 19bd8c6b9..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationTaskFactoryImpl.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.briarproject.bramble.invitation; - -import org.briarproject.bramble.api.contact.ContactExchangeTask; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.data.BdfReaderFactory; -import org.briarproject.bramble.api.data.BdfWriterFactory; -import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.invitation.InvitationTask; -import org.briarproject.bramble.api.invitation.InvitationTaskFactory; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.PluginManager; - -import javax.annotation.concurrent.Immutable; -import javax.inject.Inject; - -@Immutable -@NotNullByDefault -class InvitationTaskFactoryImpl implements InvitationTaskFactory { - - private final CryptoComponent crypto; - private final BdfReaderFactory bdfReaderFactory; - private final BdfWriterFactory bdfWriterFactory; - private final ContactExchangeTask contactExchangeTask; - private final IdentityManager identityManager; - private final PluginManager pluginManager; - - @Inject - InvitationTaskFactoryImpl(CryptoComponent crypto, - BdfReaderFactory bdfReaderFactory, - BdfWriterFactory bdfWriterFactory, - ContactExchangeTask contactExchangeTask, - IdentityManager identityManager, PluginManager pluginManager) { - this.crypto = crypto; - this.bdfReaderFactory = bdfReaderFactory; - this.bdfWriterFactory = bdfWriterFactory; - this.contactExchangeTask = contactExchangeTask; - this.identityManager = identityManager; - this.pluginManager = pluginManager; - } - - @Override - public InvitationTask createTask(int localCode, int remoteCode) { - return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory, - contactExchangeTask, identityManager, pluginManager, - localCode, remoteCode); - } -} 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 442f3ed89..087d943da 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 @@ -164,14 +164,6 @@ class PluginManagerImpl implements PluginManager, Service { return new ArrayList(duplexPlugins); } - @Override - public Collection getInvitationPlugins() { - List supported = new ArrayList(); - for (DuplexPlugin d : duplexPlugins) - if (d.supportsInvitations()) supported.add(d); - return supported; - } - @Override public Collection getKeyAgreementPlugins() { List supported = new ArrayList(); 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 a1bed0075..247950ff5 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 @@ -1,7 +1,6 @@ package org.briarproject.bramble.plugin.tcp; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; @@ -281,17 +280,6 @@ abstract class TcpPlugin implements DuplexPlugin { } } - @Override - public boolean supportsInvitations() { - return false; - } - - @Override - public DuplexTransportConnection createInvitationConnection(PseudoRandom r, - long timeout, boolean alice) { - throw new UnsupportedOperationException(); - } - @Override public boolean supportsKeyAgreement() { return false; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamReaderFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamReaderFactoryImpl.java index 0d2e9cfb7..4d6475b23 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamReaderFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamReaderFactoryImpl.java @@ -29,10 +29,10 @@ class StreamReaderFactoryImpl implements StreamReaderFactory { } @Override - public InputStream createInvitationStreamReader(InputStream in, + public InputStream createContactExchangeStreamReader(InputStream in, SecretKey headerKey) { return new StreamReaderImpl( - streamDecrypterFactory.createInvitationStreamDecrypter(in, + streamDecrypterFactory.createContactExchangeStreamDecrypter(in, headerKey)); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamWriterFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamWriterFactoryImpl.java index 77dc7657d..b443a20e3 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamWriterFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/StreamWriterFactoryImpl.java @@ -30,10 +30,10 @@ class StreamWriterFactoryImpl implements StreamWriterFactory { } @Override - public OutputStream createInvitationStreamWriter(OutputStream out, + public OutputStream createContactExchangeStreamWriter(OutputStream out, SecretKey headerKey) { return new StreamWriterImpl( - streamEncrypterFactory.createInvitationStreamEncrypter(out, + streamEncrypterFactory.createContactExchangeStreamDecrypter(out, headerKey)); } } \ No newline at end of file diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/PseudoRandomImpl.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoRandom.java similarity index 82% rename from bramble-core/src/main/java/org/briarproject/bramble/crypto/PseudoRandomImpl.java rename to bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoRandom.java index 1eabb29df..fdc715c46 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/PseudoRandomImpl.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoRandom.java @@ -1,6 +1,5 @@ package org.briarproject.bramble.crypto; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.spongycastle.crypto.Digest; import org.spongycastle.crypto.engines.Salsa20Engine; @@ -11,11 +10,11 @@ import javax.annotation.concurrent.NotThreadSafe; @NotThreadSafe @NotNullByDefault -class PseudoRandomImpl implements PseudoRandom { +class PseudoRandom { private final Salsa20Engine cipher = new Salsa20Engine(); - PseudoRandomImpl(byte[] seed) { + PseudoRandom(byte[] seed) { // Hash the seed to produce a 32-byte key byte[] key = new byte[32]; Digest digest = new Blake2sDigest(); @@ -26,8 +25,7 @@ class PseudoRandomImpl implements PseudoRandom { cipher.init(true, new ParametersWithIV(new KeyParameter(key), nonce)); } - @Override - public byte[] nextBytes(int length) { + byte[] nextBytes(int length) { byte[] in = new byte[length], out = new byte[length]; cipher.processBytes(in, 0, length, out, 0); return out; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoSecureRandom.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoSecureRandom.java index 92702ca90..5e75bf20e 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoSecureRandom.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/PseudoSecureRandom.java @@ -1,7 +1,5 @@ package org.briarproject.bramble.crypto; -import org.briarproject.bramble.api.crypto.PseudoRandom; - import java.security.Provider; import java.security.SecureRandom; import java.security.SecureRandomSpi; @@ -19,7 +17,7 @@ class PseudoSecureRandom extends SecureRandom { private final PseudoRandom pseudoRandom; private PseudoSecureRandomSpi(byte[] seed) { - pseudoRandom = new PseudoRandomImpl(seed); + pseudoRandom = new PseudoRandom(seed); } @Override diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index 924079103..426f387b3 100644 --- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -2,7 +2,6 @@ package org.briarproject.bramble.plugin.bluetooth; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; @@ -19,33 +18,23 @@ import org.briarproject.bramble.util.OsUtils; import org.briarproject.bramble.util.StringUtils; import java.io.IOException; -import java.io.InputStream; import java.security.SecureRandom; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import java.util.concurrent.Callable; -import java.util.concurrent.CompletionService; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import javax.annotation.Nullable; import javax.bluetooth.BluetoothStateException; -import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.LocalDevice; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import javax.microedition.io.StreamConnectionNotifier; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static javax.bluetooth.DiscoveryAgent.GIAC; @@ -67,7 +56,6 @@ class BluetoothPlugin implements DuplexPlugin { private final Backoff backoff; private final DuplexPluginCallback callback; private final int maxLatency; - private final Semaphore discoverySemaphore = new Semaphore(1); private final AtomicBoolean used = new AtomicBoolean(false); private volatile boolean running = false; @@ -273,95 +261,6 @@ class BluetoothPlugin implements DuplexPlugin { return new BluetoothTransportConnection(this, s); } - @Override - public boolean supportsInvitations() { - return true; - } - - @Override - public DuplexTransportConnection createInvitationConnection(PseudoRandom r, - long timeout, boolean alice) { - if (!running) return null; - // Use the invitation codes to generate the UUID - byte[] b = r.nextBytes(UUID_BYTES); - String uuid = UUID.nameUUIDFromBytes(b).toString(); - String url = makeUrl("localhost", uuid); - // Make the device discoverable if possible - makeDeviceDiscoverable(); - // Bind a server socket for receiving invitation connections - final StreamConnectionNotifier ss; - try { - ss = (StreamConnectionNotifier) Connector.open(url); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - return null; - } - if (!running) { - tryToClose(ss); - return null; - } - // Create the background tasks - CompletionService complete = - new ExecutorCompletionService<>(ioExecutor); - List> futures = new ArrayList<>(); - if (alice) { - // Return the first connected socket - futures.add(complete.submit(new ListeningTask(ss))); - futures.add(complete.submit(new DiscoveryTask(uuid))); - } else { - // Return the first socket with readable data - futures.add(complete.submit(new ReadableTask( - new ListeningTask(ss)))); - futures.add(complete.submit(new ReadableTask( - new DiscoveryTask(uuid)))); - } - StreamConnection chosen = null; - try { - Future f = complete.poll(timeout, MILLISECONDS); - if (f == null) return null; // No task completed within the timeout - chosen = f.get(); - return new BluetoothTransportConnection(this, chosen); - } catch (InterruptedException e) { - LOG.info("Interrupted while exchanging invitations"); - Thread.currentThread().interrupt(); - return null; - } catch (ExecutionException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - return null; - } finally { - // Closing the socket will terminate the listener task - tryToClose(ss); - closeSockets(futures, chosen); - } - } - - private void closeSockets(final List> futures, - @Nullable final StreamConnection chosen) { - ioExecutor.execute(new Runnable() { - @Override - public void run() { - for (Future f : futures) { - try { - if (f.cancel(true)) { - LOG.info("Cancelled task"); - } else { - StreamConnection s = f.get(); - if (s != null && s != chosen) { - LOG.info("Closing unwanted socket"); - s.close(); - } - } - } catch (InterruptedException e) { - LOG.info("Interrupted while closing sockets"); - return; - } catch (ExecutionException | IOException e) { - if (LOG.isLoggable(INFO)) LOG.info(e.toString()); - } - } - } - }); - } - @Override public boolean supportsKeyAgreement() { return true; @@ -376,7 +275,7 @@ class BluetoothPlugin implements DuplexPlugin { String url = makeUrl("localhost", uuid); // Make the device discoverable if possible makeDeviceDiscoverable(); - // Bind a server socket for receiving invitation connections + // Bind a server socket for receiving key agreementconnections final StreamConnectionNotifier ss; try { ss = (StreamConnectionNotifier) Connector.open(url); @@ -431,77 +330,6 @@ class BluetoothPlugin implements DuplexPlugin { } } - private class DiscoveryTask implements Callable { - - private final String uuid; - - private DiscoveryTask(String uuid) { - this.uuid = uuid; - } - - @Override - public StreamConnection call() throws Exception { - // Repeat discovery until we connect or get interrupted - DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent(); - while (true) { - if (!discoverySemaphore.tryAcquire()) - throw new Exception("Discovery is already in progress"); - try { - InvitationListener listener = - new InvitationListener(discoveryAgent, uuid); - discoveryAgent.startInquiry(GIAC, listener); - String url = listener.waitForUrl(); - if (url != null) { - StreamConnection s = connect(url); - if (s != null) { - LOG.info("Outgoing connection"); - return s; - } - } - } finally { - discoverySemaphore.release(); - } - } - } - } - - private static class ListeningTask implements Callable { - - private final StreamConnectionNotifier serverSocket; - - private ListeningTask(StreamConnectionNotifier serverSocket) { - this.serverSocket = serverSocket; - } - - @Override - public StreamConnection call() throws Exception { - StreamConnection s = serverSocket.acceptAndOpen(); - LOG.info("Incoming connection"); - return s; - } - } - - private static class ReadableTask implements Callable { - - private final Callable connectionTask; - - private ReadableTask(Callable connectionTask) { - this.connectionTask = connectionTask; - } - - @Override - public StreamConnection call() throws Exception { - StreamConnection s = connectionTask.call(); - InputStream in = s.openInputStream(); - while (in.available() == 0) { - LOG.info("Waiting for data"); - Thread.sleep(1000); - } - LOG.info("Data available"); - return s; - } - } - private class BluetoothKeyAgreementListener extends KeyAgreementListener { private final StreamConnectionNotifier ss; diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/InvitationListener.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/InvitationListener.java deleted file mode 100644 index 0a389134b..000000000 --- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/InvitationListener.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.briarproject.bramble.plugin.bluetooth; - -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.TreeSet; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Logger; - -import javax.bluetooth.BluetoothStateException; -import javax.bluetooth.DataElement; -import javax.bluetooth.DeviceClass; -import javax.bluetooth.DiscoveryAgent; -import javax.bluetooth.DiscoveryListener; -import javax.bluetooth.RemoteDevice; -import javax.bluetooth.ServiceRecord; -import javax.bluetooth.UUID; - -import static java.util.logging.Level.WARNING; - -class InvitationListener implements DiscoveryListener { - - private static final Logger LOG = - Logger.getLogger(InvitationListener.class.getName()); - - private final AtomicInteger searches = new AtomicInteger(1); - private final CountDownLatch finished = new CountDownLatch(1); - private final DiscoveryAgent discoveryAgent; - private final String uuid; - - private volatile String url = null; - - InvitationListener(DiscoveryAgent discoveryAgent, String uuid) { - this.discoveryAgent = discoveryAgent; - this.uuid = uuid; - } - - String waitForUrl() throws InterruptedException { - finished.await(); - return url; - } - - @Override - public void deviceDiscovered(RemoteDevice device, DeviceClass deviceClass) { - UUID[] uuids = new UUID[] {new UUID(uuid, false)}; - // Try to discover the services associated with the UUID - try { - discoveryAgent.searchServices(null, uuids, device, this); - searches.incrementAndGet(); - } catch (BluetoothStateException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } - } - - @Override - public void servicesDiscovered(int transaction, ServiceRecord[] services) { - for (ServiceRecord record : services) { - // Does this service have a URL? - String serviceUrl = record.getConnectionURL( - ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); - if (serviceUrl == null) continue; - // Does this service have the UUID we're looking for? - Collection uuids = new TreeSet<>(); - findNestedClassIds(record.getAttributeValue(0x1), uuids); - for (String u : uuids) { - if (uuid.equalsIgnoreCase(u)) { - // The UUID matches - store the URL - url = serviceUrl; - finished.countDown(); - return; - } - } - } - } - - @Override - public void inquiryCompleted(int discoveryType) { - if (searches.decrementAndGet() == 0) finished.countDown(); - } - - @Override - public void serviceSearchCompleted(int transaction, int response) { - if (searches.decrementAndGet() == 0) finished.countDown(); - } - - // UUIDs are sometimes buried in nested data elements - private void findNestedClassIds(Object o, Collection ids) { - o = getDataElementValue(o); - if (o instanceof Enumeration) { - for (Object o1 : Collections.list((Enumeration) o)) - findNestedClassIds(o1, ids); - } else if (o instanceof UUID) { - ids.add(o.toString()); - } - } - - private Object getDataElementValue(Object o) { - if (o instanceof DataElement) { - // Bluecove throws an exception if the type is unknown - try { - return ((DataElement) o).getValue(); - } catch (ClassCastException e) { - return null; - } - } - return null; - } -} diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java index 98094f36d..2e9f3819c 100644 --- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java +++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java @@ -1,7 +1,6 @@ package org.briarproject.bramble.plugin.modem; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.crypto.PseudoRandom; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; @@ -167,17 +166,6 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { return new ModemTransportConnection(); } - @Override - public boolean supportsInvitations() { - return false; - } - - @Override - public DuplexTransportConnection createInvitationConnection(PseudoRandom r, - long timeout, boolean alice) { - throw new UnsupportedOperationException(); - } - @Override public boolean supportsKeyAgreement() { return false; diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 22e0c0dd8..cadb84903 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -15,8 +15,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - -