From d24b1884a2146169665c362c5a0a4b51a88212b1 Mon Sep 17 00:00:00 2001 From: Michael Rogers <michael@briarproject.org> Date: Fri, 11 Aug 2017 12:42:47 +0100 Subject: [PATCH] Removed old Bluetooth code and the location permission it requires. --- .../plugin/droidtooth/DroidtoothPlugin.java | 211 +------- .../bramble/plugin/tor/TorPlugin.java | 12 - .../bramble/api/crypto/CryptoComponent.java | 11 - .../bramble/api/crypto/PseudoRandom.java | 12 - .../api/crypto/StreamDecrypterFactory.java | 5 +- .../api/crypto/StreamEncrypterFactory.java | 5 +- .../api/invitation/InvitationConstants.java | 20 - .../api/invitation/InvitationListener.java | 47 -- .../api/invitation/InvitationState.java | 85 ---- .../api/invitation/InvitationTask.java | 38 -- .../api/invitation/InvitationTaskFactory.java | 15 - .../bramble/api/plugin/PluginManager.java | 5 - .../api/plugin/duplex/DuplexPlugin.java | 15 - .../api/transport/StreamReaderFactory.java | 6 +- .../api/transport/StreamWriterFactory.java | 6 +- .../bramble/BrambleCoreModule.java | 2 - .../contact/ContactExchangeTaskImpl.java | 6 +- .../bramble/crypto/CryptoComponentImpl.java | 27 -- .../crypto/StreamDecrypterFactoryImpl.java | 2 +- .../crypto/StreamEncrypterFactoryImpl.java | 4 +- .../bramble/invitation/AliceConnector.java | 119 ----- .../bramble/invitation/BobConnector.java | 119 ----- .../bramble/invitation/Connector.java | 150 ------ .../bramble/invitation/ConnectorGroup.java | 278 ----------- .../bramble/invitation/InvitationModule.java | 16 - .../invitation/InvitationTaskFactoryImpl.java | 47 -- .../bramble/plugin/PluginManagerImpl.java | 8 - .../bramble/plugin/tcp/TcpPlugin.java | 12 - .../transport/StreamReaderFactoryImpl.java | 4 +- .../transport/StreamWriterFactoryImpl.java | 4 +- .../bramble/crypto/PseudoRandom.java} | 8 +- .../bramble/crypto/PseudoSecureRandom.java | 4 +- .../plugin/bluetooth/BluetoothPlugin.java | 174 +------ .../plugin/bluetooth/InvitationListener.java | 109 ----- .../bramble/plugin/modem/ModemPlugin.java | 12 - briar-android/src/main/AndroidManifest.xml | 12 - .../briar/android/AndroidComponent.java | 3 - .../android/activity/ActivityComponent.java | 3 - .../invitation/AddContactActivity.java | 449 ------------------ .../android/invitation/AddContactView.java | 22 - .../invitation/ChooseIdentityView.java | 43 -- .../invitation/ConfirmationCodeView.java | 121 ----- .../briar/android/invitation/ErrorView.java | 59 --- .../invitation/InvitationCodeView.java | 111 ----- ...invitation_bluetooth_confirmation_code.xml | 109 ----- .../invitation_bluetooth_invitation_code.xml | 96 ---- .../res/layout/invitation_bluetooth_start.xml | 60 --- .../src/main/res/layout/invitation_error.xml | 43 -- .../src/main/res/layout/view_code_entry.xml | 16 - briar-android/src/main/res/values/strings.xml | 12 - 50 files changed, 28 insertions(+), 2729 deletions(-) delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PseudoRandom.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationConstants.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationListener.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationState.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTask.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/invitation/InvitationTaskFactory.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/invitation/AliceConnector.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/invitation/BobConnector.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/invitation/Connector.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/invitation/ConnectorGroup.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationModule.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/invitation/InvitationTaskFactoryImpl.java rename bramble-core/src/{main/java/org/briarproject/bramble/crypto/PseudoRandomImpl.java => test/java/org/briarproject/bramble/crypto/PseudoRandom.java} (82%) delete mode 100644 bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/InvitationListener.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactActivity.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactView.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/invitation/ChooseIdentityView.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/invitation/ConfirmationCodeView.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/invitation/ErrorView.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/invitation/InvitationCodeView.java delete mode 100644 briar-android/src/main/res/layout/invitation_bluetooth_confirmation_code.xml delete mode 100644 briar-android/src/main/res/layout/invitation_bluetooth_invitation_code.xml delete mode 100644 briar-android/src/main/res/layout/invitation_bluetooth_start.xml delete mode 100644 briar-android/src/main/res/layout/invitation_error.xml delete mode 100644 briar-android/src/main/res/layout/view_code_entry.xml 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 5bb975e1a6..a5a28e0054 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<BluetoothSocket> complete = - new ExecutorCompletionService<>(ioExecutor); - List<Future<BluetoothSocket>> 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<BluetoothSocket> 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<Future<BluetoothSocket>> futures, - @Nullable final BluetoothSocket chosen) { - ioExecutor.execute(new Runnable() { - @Override - public void run() { - for (Future<BluetoothSocket> 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<BluetoothSocket> { - - 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<String> 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<String> 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<String> 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<String> waitForAddresses() throws InterruptedException { - finished.await(); - List<String> shuffled = new ArrayList<>(addresses); - Collections.shuffle(shuffled); - return shuffled; - } - } - - private static class ListeningTask implements Callable<BluetoothSocket> { - - 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<BluetoothSocket> { - - private final Callable<BluetoothSocket> connectionTask; - - private ReadableTask(Callable<BluetoothSocket> 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 9c3609ed65..69eb13d5a4 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 3d610c8506..9579e2e9ce 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 8e61027d6f..0000000000 --- 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 b07c3239a1..beecd1789f 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 7434013374..03ad5e1439 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 f7c6ed3319..0000000000 --- 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 acf545f1a7..0000000000 --- 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 456230837c..0000000000 --- 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 b09d940f30..0000000000 --- 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 76f94908a3..0000000000 --- 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 1056a6438c..32c3a80125 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<DuplexPlugin> getDuplexPlugins(); - /** - * Returns any duplex plugins that support invitations. - */ - Collection<DuplexPlugin> 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 f2c2027f90..83fc642487 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 44e31a671b..87823679b0 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 134bde50e7..3277acee08 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 eb9c2eb5d9..365b50de91 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 e33b1deb0c..d97c8c9eef 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 f0c26edd9e..6c97f1c2cd 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 49fd6ba2ec..aac3e504ec 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 be7f553de2..0d9b4a0fc2 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 871db9b4ce..0000000000 --- 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 d87a9334a0..0000000000 --- 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 4c1a63c673..0000000000 --- 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 103dd03c63..0000000000 --- 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<InvitationListener> 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<InvitationListener>(); - 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<Connector> connectors = new ArrayList<Connector>(); - // 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 0c6dbcfac5..0000000000 --- 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 19bd8c6b9d..0000000000 --- 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 442f3ed892..087d943da1 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<DuplexPlugin>(duplexPlugins); } - @Override - public Collection<DuplexPlugin> getInvitationPlugins() { - List<DuplexPlugin> supported = new ArrayList<DuplexPlugin>(); - for (DuplexPlugin d : duplexPlugins) - if (d.supportsInvitations()) supported.add(d); - return supported; - } - @Override public Collection<DuplexPlugin> getKeyAgreementPlugins() { List<DuplexPlugin> supported = new ArrayList<DuplexPlugin>(); 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 a1bed00752..247950ff57 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 0d2e9cfb73..4d6475b23c 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 77dc7657d7..b443a20e3d 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 1eabb29df3..fdc715c469 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 92702ca90a..5e75bf20e7 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 9240791039..426f387b33 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<StreamConnection> complete = - new ExecutorCompletionService<>(ioExecutor); - List<Future<StreamConnection>> 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<StreamConnection> 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<Future<StreamConnection>> futures, - @Nullable final StreamConnection chosen) { - ioExecutor.execute(new Runnable() { - @Override - public void run() { - for (Future<StreamConnection> 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<StreamConnection> { - - 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<StreamConnection> { - - 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<StreamConnection> { - - private final Callable<StreamConnection> connectionTask; - - private ReadableTask(Callable<StreamConnection> 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 0a389134b3..0000000000 --- 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<String> 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<String> 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 98094f36d0..2e9f3819c8 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 22e0c0dd88..cadb849039 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -15,8 +15,6 @@ <uses-permission android:name="android.permission.READ_LOGS"/> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> - <!-- Since API 23, this is needed to add contacts via Bluetooth --> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <application android:name="org.briarproject.briar.android.BriarApplicationImpl" @@ -292,16 +290,6 @@ /> </activity> - <activity - android:name="org.briarproject.briar.android.invitation.AddContactActivity" - android:label="@string/add_contact_title" - android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"> - <meta-data - android:name="android.support.PARENT_ACTIVITY" - android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" - /> - </activity> - <activity android:name="org.briarproject.briar.android.keyagreement.KeyAgreementActivity" android:label="@string/add_contact_title" diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index 9394f9d02e..4ad3f75b2f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -12,7 +12,6 @@ import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.invitation.InvitationTaskFactory; import org.briarproject.bramble.api.keyagreement.KeyAgreementTaskFactory; import org.briarproject.bramble.api.keyagreement.PayloadEncoder; import org.briarproject.bramble.api.keyagreement.PayloadParser; @@ -89,8 +88,6 @@ public interface AndroidComponent EventBus eventBus(); - InvitationTaskFactory invitationTaskFactory(); - AndroidNotificationManager androidNotificationManager(); ScreenFilterMonitor screenFilterMonitor(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java index 7b9bb80ce2..61eea88b24 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java @@ -24,7 +24,6 @@ import org.briarproject.briar.android.forum.ForumModule; import org.briarproject.briar.android.introduction.ContactChooserFragment; import org.briarproject.briar.android.introduction.IntroductionActivity; import org.briarproject.briar.android.introduction.IntroductionMessageFragment; -import org.briarproject.briar.android.invitation.AddContactActivity; import org.briarproject.briar.android.keyagreement.IntroFragment; import org.briarproject.briar.android.keyagreement.KeyAgreementActivity; import org.briarproject.briar.android.keyagreement.ShowQrCodeFragment; @@ -91,8 +90,6 @@ public interface ActivityComponent { void inject(PanicPreferencesActivity activity); - void inject(AddContactActivity activity); - void inject(KeyAgreementActivity activity); void inject(ConversationActivity activity); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactActivity.java deleted file mode 100644 index 1036382a31..0000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactActivity.java +++ /dev/null @@ -1,449 +0,0 @@ -package org.briarproject.briar.android.invitation; - -import android.content.Intent; -import android.os.Bundle; -import android.widget.Toast; - -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.identity.AuthorId; -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.invitation.InvitationTaskFactory; -import org.briarproject.briar.R; -import org.briarproject.briar.android.activity.ActivityComponent; -import org.briarproject.briar.android.activity.BriarActivity; -import org.briarproject.briar.api.android.ReferenceManager; - -import java.util.logging.Logger; - -import javax.inject.Inject; - -import static android.widget.Toast.LENGTH_LONG; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH; -import static org.briarproject.briar.android.invitation.ConfirmationCodeView.ConfirmationState.CONNECTED; -import static org.briarproject.briar.android.invitation.ConfirmationCodeView.ConfirmationState.DETAILS; -import static org.briarproject.briar.android.invitation.ConfirmationCodeView.ConfirmationState.WAIT_FOR_CONTACT; - -public class AddContactActivity extends BriarActivity - implements InvitationListener { - - private static final Logger LOG = - Logger.getLogger(AddContactActivity.class.getName()); - - @Inject - CryptoComponent crypto; - @Inject - InvitationTaskFactory invitationTaskFactory; - @Inject - ReferenceManager referenceManager; - - private AddContactView view = null; - private InvitationTask task = null; - private long taskHandle = -1; - private AuthorId localAuthorId = null; - private int localInvitationCode = -1, remoteInvitationCode = -1; - private int localConfirmationCode = -1, remoteConfirmationCode = -1; - private boolean connected = false, connectionFailed = false; - private boolean localCompared = false, remoteCompared = false; - private boolean localMatched = false, remoteMatched = false; - private String contactName = null; - - // Fields that are accessed from background threads must be volatile - @Inject - volatile IdentityManager identityManager; - - @Override - public void onCreate(Bundle state) { - super.onCreate(state); - if (state == null) { - // This is a new activity - setView(new ChooseIdentityView(this)); - } else { - // Restore the activity's state - byte[] b = state.getByteArray("briar.LOCAL_AUTHOR_ID"); - if (b != null) localAuthorId = new AuthorId(b); - taskHandle = state.getLong("briar.TASK_HANDLE", -1); - task = referenceManager.getReference(taskHandle, - InvitationTask.class); - - if (task == null) { - // No background task - we must be in an initial or final state - localInvitationCode = state.getInt("briar.LOCAL_CODE"); - remoteInvitationCode = state.getInt("briar.REMOTE_CODE"); - connectionFailed = state.getBoolean("briar.FAILED"); - contactName = state.getString("briar.CONTACT_NAME"); - if (contactName != null) { - localCompared = remoteCompared = true; - localMatched = remoteMatched = true; - } - // Set the appropriate view for the state - if (localInvitationCode == -1) { - setView(new ChooseIdentityView(this)); - } else if (remoteInvitationCode == -1) { - setView(new InvitationCodeView(this)); - } else if (connectionFailed) { - setView(new ErrorView(this, R.string.connection_failed, - R.string.could_not_find_contact)); - } else if (contactName == null) { - setView(new ErrorView(this, R.string.codes_do_not_match, - R.string.interfering)); - } else { - showToastAndFinish(); - } - } else { - // A background task exists - listen to it and get its state - InvitationState s = task.addListener(this); - localInvitationCode = s.getLocalInvitationCode(); - remoteInvitationCode = s.getRemoteInvitationCode(); - localConfirmationCode = s.getLocalConfirmationCode(); - remoteConfirmationCode = s.getRemoteConfirmationCode(); - connected = s.getConnected(); - connectionFailed = s.getConnectionFailed(); - localCompared = s.getLocalCompared(); - remoteCompared = s.getRemoteCompared(); - localMatched = s.getLocalMatched(); - remoteMatched = s.getRemoteMatched(); - contactName = s.getContactName(); - // Set the appropriate view for the state - if (localInvitationCode == -1) { - setView(new ChooseIdentityView(this)); - } else if (remoteInvitationCode == -1) { - setView(new InvitationCodeView(this)); - } else if (connectionFailed) { - setView(new ErrorView(AddContactActivity.this, - R.string.connection_failed, - R.string.could_not_find_contact)); - } else if (connected && localConfirmationCode == -1) { - setView(new ConfirmationCodeView(this, CONNECTED)); - } else if (localConfirmationCode == -1) { - setView(new InvitationCodeView(this, true)); - } else if (!localCompared) { - setView(new ConfirmationCodeView(this)); - } else if (!remoteCompared) { - setView(new ConfirmationCodeView(this, WAIT_FOR_CONTACT)); - } else if (localMatched && remoteMatched) { - if (contactName == null) { - setView(new ConfirmationCodeView(this, DETAILS)); - } else { - showToastAndFinish(); - } - } else { - setView(new ErrorView(this, R.string.codes_do_not_match, - R.string.interfering)); - } - } - } - } - - @Override - public void injectActivity(ActivityComponent component) { - component.inject(this); - } - - private void showToastAndFinish() { - String format = getString(R.string.contact_added_toast); - String text = String.format(format, contactName); - Toast.makeText(this, text, LENGTH_LONG).show(); - supportFinishAfterTransition(); - } - - @Override - public void onStart() { - super.onStart(); - view.populate(); - } - - @Override - public void onSaveInstanceState(Bundle state) { - super.onSaveInstanceState(state); - if (localAuthorId != null) { - byte[] b = localAuthorId.getBytes(); - state.putByteArray("briar.LOCAL_AUTHOR_ID", b); - } - state.putInt("briar.LOCAL_CODE", localInvitationCode); - state.putInt("briar.REMOTE_CODE", remoteInvitationCode); - state.putBoolean("briar.FAILED", connectionFailed); - state.putString("briar.CONTACT_NAME", contactName); - if (task != null) state.putLong("briar.TASK_HANDLE", taskHandle); - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (task != null) task.removeListener(this); - } - - @Override - public void onActivityResult(int request, int result, Intent data) { - if (request == REQUEST_BLUETOOTH) { - if (result != RESULT_CANCELED) reset(new InvitationCodeView(this)); - } - } - - @SuppressWarnings("ConstantConditions") - void setView(AddContactView view) { - this.view = view; - view.init(this); - setContentView(view); - getSupportActionBar().setTitle(R.string.add_contact_title); - } - - void reset(AddContactView view) { - // Don't reset localAuthorId - task = null; - taskHandle = -1; - localInvitationCode = -1; - localConfirmationCode = remoteConfirmationCode = -1; - connected = connectionFailed = false; - localCompared = remoteCompared = false; - localMatched = remoteMatched = false; - contactName = null; - setView(view); - } - - void loadLocalAuthor() { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - long now = System.currentTimeMillis(); - LocalAuthor author = identityManager.getLocalAuthor(); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Loading author took " + duration + " ms"); - setLocalAuthorId(author.getId()); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - void setLocalAuthorId(final AuthorId localAuthorId) { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - AddContactActivity.this.localAuthorId = localAuthorId; - } - }); - } - - int getLocalInvitationCode() { - if (localInvitationCode == -1) - localInvitationCode = crypto.generateBTInvitationCode(); - return localInvitationCode; - } - - int getRemoteInvitationCode() { - return remoteInvitationCode; - } - - void remoteInvitationCodeEntered(int code) { - if (localAuthorId == null) throw new IllegalStateException(); - if (localInvitationCode == -1) throw new IllegalStateException(); - remoteInvitationCode = code; - - // change UI to show a progress indicator - setView(new InvitationCodeView(this, true)); - - task = invitationTaskFactory.createTask(localInvitationCode, code); - taskHandle = referenceManager.putReference(task, InvitationTask.class); - task.addListener(AddContactActivity.this); - // Add a second listener so we can remove the first in onDestroy(), - // allowing the activity to be garbage collected if it's destroyed - task.addListener(new ReferenceCleaner(referenceManager, taskHandle)); - task.connect(); - } - - int getLocalConfirmationCode() { - return localConfirmationCode; - } - - void remoteConfirmationCodeEntered(int code) { - localCompared = true; - if (code == remoteConfirmationCode) { - localMatched = true; - if (remoteMatched) { - setView(new ConfirmationCodeView(this, DETAILS)); - } else if (remoteCompared) { - setView(new ErrorView(this, R.string.codes_do_not_match, - R.string.interfering)); - } else { - setView(new ConfirmationCodeView(this, WAIT_FOR_CONTACT)); - } - task.localConfirmationSucceeded(); - } else { - localMatched = false; - setView(new ErrorView(this, R.string.codes_do_not_match, - R.string.interfering)); - task.localConfirmationFailed(); - } - } - - @Override - public void connectionSucceeded() { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - connected = true; - setView(new ConfirmationCodeView(AddContactActivity.this, - CONNECTED)); - } - }); - } - - @Override - public void connectionFailed() { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - connectionFailed = true; - setView(new ErrorView(AddContactActivity.this, - R.string.connection_failed, - R.string.could_not_find_contact)); - } - }); - } - - @Override - public void keyAgreementSucceeded(final int localCode, - final int remoteCode) { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - localConfirmationCode = localCode; - remoteConfirmationCode = remoteCode; - setView(new ConfirmationCodeView(AddContactActivity.this)); - } - }); - } - - @Override - public void keyAgreementFailed() { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - connectionFailed = true; - setView(new ErrorView(AddContactActivity.this, - R.string.connection_failed, - R.string.could_not_find_contact)); - } - }); - } - - @Override - public void remoteConfirmationSucceeded() { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - remoteCompared = true; - remoteMatched = true; - if (localMatched) { - setView(new ConfirmationCodeView(AddContactActivity.this, - DETAILS)); - } - } - }); - } - - @Override - public void remoteConfirmationFailed() { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - remoteCompared = true; - remoteMatched = false; - if (localMatched) { - setView(new ErrorView(AddContactActivity.this, - R.string.codes_do_not_match, R.string.interfering)); - } - } - }); - } - - @Override - public void pseudonymExchangeSucceeded(final String remoteName) { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - contactName = remoteName; - showToastAndFinish(); - } - }); - } - - @Override - public void pseudonymExchangeFailed() { - runOnUiThreadUnlessDestroyed(new Runnable() { - @Override - public void run() { - setView(new ErrorView(AddContactActivity.this, - R.string.connection_failed, - R.string.could_not_find_contact)); - } - }); - } - - /** - * Cleans up the reference to the invitation task when the task completes. - * This class is static to prevent memory leaks. - */ - private static class ReferenceCleaner implements InvitationListener { - - private final ReferenceManager referenceManager; - private final long handle; - - private ReferenceCleaner(ReferenceManager referenceManager, - long handle) { - this.referenceManager = referenceManager; - this.handle = handle; - } - - @Override - public void connectionSucceeded() { - // Wait for key agreement to succeed or fail - } - - @Override - public void connectionFailed() { - referenceManager.removeReference(handle, InvitationTask.class); - } - - @Override - public void keyAgreementSucceeded(int localCode, int remoteCode) { - // Wait for remote confirmation to succeed or fail - } - - @Override - public void keyAgreementFailed() { - referenceManager.removeReference(handle, InvitationTask.class); - } - - @Override - public void remoteConfirmationSucceeded() { - // Wait for the pseudonym exchange to succeed or fail - } - - @Override - public void remoteConfirmationFailed() { - referenceManager.removeReference(handle, InvitationTask.class); - } - - @Override - public void pseudonymExchangeSucceeded(String remoteName) { - referenceManager.removeReference(handle, InvitationTask.class); - } - - @Override - public void pseudonymExchangeFailed() { - referenceManager.removeReference(handle, InvitationTask.class); - } - } -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactView.java b/briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactView.java deleted file mode 100644 index 3ca73869a2..0000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/invitation/AddContactView.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.briarproject.briar.android.invitation; - -import android.content.Context; -import android.widget.LinearLayout; - -abstract class AddContactView extends LinearLayout { - - static final public int CODE_LEN = 6; - protected AddContactActivity container = null; - - AddContactView(Context ctx) { - super(ctx); - } - - void init(AddContactActivity container) { - this.container = container; - populate(); - } - - abstract void populate(); - -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/invitation/ChooseIdentityView.java b/briar-android/src/main/java/org/briarproject/briar/android/invitation/ChooseIdentityView.java deleted file mode 100644 index d392a6ef2c..0000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/invitation/ChooseIdentityView.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.briarproject.briar.android.invitation; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; - -import org.briarproject.briar.R; - -import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE; -import static android.bluetooth.BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION; -import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH; - -class ChooseIdentityView extends AddContactView implements OnClickListener { - - ChooseIdentityView(Context ctx) { - super(ctx); - } - - @Override - void populate() { - removeAllViews(); - Context ctx = getContext(); - - LayoutInflater inflater = (LayoutInflater) ctx.getSystemService - (Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.invitation_bluetooth_start, this); - - Button continueButton = (Button) view.findViewById(R.id.continueButton); - continueButton.setOnClickListener(this); - - container.loadLocalAuthor(); - } - - @Override - public void onClick(View view) { - Intent i = new Intent(ACTION_REQUEST_DISCOVERABLE); - i.putExtra(EXTRA_DISCOVERABLE_DURATION, 120); - container.startActivityForResult(i, REQUEST_BLUETOOTH); - } -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/invitation/ConfirmationCodeView.java b/briar-android/src/main/java/org/briarproject/briar/android/invitation/ConfirmationCodeView.java deleted file mode 100644 index 2bd953a9b6..0000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/invitation/ConfirmationCodeView.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.briarproject.briar.android.invitation; - -import android.content.Context; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import org.briarproject.briar.R; - -import static android.content.Context.INPUT_METHOD_SERVICE; - -class ConfirmationCodeView extends AddContactView { - - public enum ConfirmationState { CONNECTED, ENTER_CODE, WAIT_FOR_CONTACT, DETAILS } - private ConfirmationState state; - - ConfirmationCodeView(Context ctx) { - super(ctx); - this.state = ConfirmationState.ENTER_CODE; - } - - ConfirmationCodeView(Context ctx, ConfirmationState state) { - super(ctx); - this.state = state; - } - - @Override - void populate() { - removeAllViews(); - Context ctx = getContext(); - - LayoutInflater inflater = (LayoutInflater) ctx.getSystemService - (Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.invitation_bluetooth_confirmation_code, this); - - // local confirmation code - TextView code = (TextView) view.findViewById(R.id.codeView); - int localCode = container.getLocalConfirmationCode(); - code.setText(String.format("%06d", localCode)); - - if (state != ConfirmationState.ENTER_CODE) { - // hide views we no longer need - view.findViewById(R.id.enterCodeTextView).setVisibility(View.GONE); - view.findViewById(R.id.codeEntryView).setVisibility(View.GONE); - view.findViewById(R.id.continueButton).setVisibility(View.GONE); - - // show progress indicator - view.findViewById(R.id.progressBar).setVisibility(View.VISIBLE); - - // show what we are waiting for - TextView connecting = (TextView) view.findViewById(R.id.waitingView); - int textId; - if (state == ConfirmationState.CONNECTED) { - textId = R.string.calculating_confirmation_code; - view.findViewById(R.id.yourConfirmationCodeView).setVisibility(View.GONE); - view.findViewById(R.id.codeView).setVisibility(View.GONE); - } else if (state == ConfirmationState.WAIT_FOR_CONTACT) { - textId = R.string.waiting_for_contact; - } else { - textId = R.string.exchanging_contact_details; - } - connecting.setText(ctx.getString(textId)); - connecting.setVisibility(View.VISIBLE); - } - else { - // handle click on continue button - final EditText codeEntry = (EditText) view.findViewById(R.id.codeEntryView); - final Button continueButton = (Button) view.findViewById(R.id.continueButton); - continueButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - send(codeEntry); - } - }); - - // activate continue button only when we have a 6 digit (CODE_LEN) code - codeEntry.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - continueButton.setEnabled(codeEntry.getText().length() == CODE_LEN); - } - - @Override - public void afterTextChanged(Editable s) { - } - }); - - codeEntry.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_GO && v.getText().length() == CODE_LEN) { - send(v); - return true; - } - return false; - } - }); - } - } - - private void send(TextView codeEntry) { - int code = Integer.parseInt(codeEntry.getText().toString()); - container.remoteConfirmationCodeEntered(code); - - // Hide the soft keyboard - Object o = getContext().getSystemService(INPUT_METHOD_SERVICE); - ((InputMethodManager) o).hideSoftInputFromWindow(codeEntry.getWindowToken(), 0); - } - -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/invitation/ErrorView.java b/briar-android/src/main/java/org/briarproject/briar/android/invitation/ErrorView.java deleted file mode 100644 index 0535a76020..0000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/invitation/ErrorView.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.briarproject.briar.android.invitation; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.TextView; - -import org.briarproject.briar.R; - -import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE; -import static android.bluetooth.BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION; -import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH; - -class ErrorView extends AddContactView implements OnClickListener { - - private final int error; - private final int explanation; - - ErrorView(Context ctx) { - super(ctx); - this.error = R.string.connection_failed; - this.explanation = R.string.could_not_find_contact; - } - - ErrorView(Context ctx, int error, int explanation) { - super(ctx); - this.error = error; - this.explanation = explanation; - } - - @Override - void populate() { - removeAllViews(); - Context ctx = getContext(); - - LayoutInflater inflater = (LayoutInflater) ctx.getSystemService - (Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.invitation_error, this); - - TextView errorView = (TextView) view.findViewById(R.id.errorTextView); - errorView.setText(ctx.getString(error)); - - TextView explanationView = (TextView) view.findViewById(R.id.explanationTextView); - explanationView.setText(ctx.getString(explanation)); - - Button tryAgainButton = (Button) view.findViewById(R.id.tryAgainButton); - tryAgainButton.setOnClickListener(this); - } - - @Override - public void onClick(View view) { - Intent i = new Intent(ACTION_REQUEST_DISCOVERABLE); - i.putExtra(EXTRA_DISCOVERABLE_DURATION, 120); - container.startActivityForResult(i, REQUEST_BLUETOOTH); - } -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/invitation/InvitationCodeView.java b/briar-android/src/main/java/org/briarproject/briar/android/invitation/InvitationCodeView.java deleted file mode 100644 index bfc7272a66..0000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/invitation/InvitationCodeView.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.briarproject.briar.android.invitation; - -import android.content.Context; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import org.briarproject.briar.R; - -import static android.content.Context.INPUT_METHOD_SERVICE; - -class InvitationCodeView extends AddContactView { - - private boolean waiting; - - InvitationCodeView(Context ctx, boolean waiting) { - super(ctx); - this.waiting = waiting; - } - - InvitationCodeView(Context ctx) { - this(ctx, false); - } - - @Override - void populate() { - removeAllViews(); - Context ctx = getContext(); - - LayoutInflater inflater = (LayoutInflater) ctx.getSystemService - (Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.invitation_bluetooth_invitation_code, this); - - // local invitation code - TextView code = (TextView) view.findViewById(R.id.codeView); - int localCode = container.getLocalInvitationCode(); - code.setText(String.format("%06d", localCode)); - - if (waiting) { - // hide views we no longer need - view.findViewById(R.id.enterCodeTextView).setVisibility(View.GONE); - view.findViewById(R.id.codeEntryView).setVisibility(View.GONE); - view.findViewById(R.id.continueButton).setVisibility(View.GONE); - - // show progress indicator - view.findViewById(R.id.progressBar).setVisibility(View.VISIBLE); - - // show which code we are waiting for - TextView connecting = (TextView) view.findViewById(R.id.waitingView); - int remoteCode = container.getRemoteInvitationCode(); - String format = container.getString(R.string.searching_format); - connecting.setText(String.format(format, remoteCode)); - connecting.setVisibility(View.VISIBLE); - } - else { - // handle click on continue button - final EditText codeEntry = (EditText) view.findViewById(R.id.codeEntryView); - final Button continueButton = (Button) view.findViewById(R.id.continueButton); - continueButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - send(codeEntry); - } - }); - - // activate continue button only when we have a 6 digit (CODE_LEN) code - codeEntry.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - continueButton.setEnabled(codeEntry.getText().length() == CODE_LEN); - } - - @Override - public void afterTextChanged(Editable s) { - } - }); - - codeEntry.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_GO && v.getText().length() == CODE_LEN) { - send(v); - return true; - } - return false; - } - }); - } - } - - private void send(TextView codeEntry) { - int code = Integer.parseInt(codeEntry.getText().toString()); - container.remoteInvitationCodeEntered(code); - - // Hide the soft keyboard - Object o = getContext().getSystemService(INPUT_METHOD_SERVICE); - ((InputMethodManager) o).hideSoftInputFromWindow(codeEntry.getWindowToken(), 0); - } - -} diff --git a/briar-android/src/main/res/layout/invitation_bluetooth_confirmation_code.xml b/briar-android/src/main/res/layout/invitation_bluetooth_confirmation_code.xml deleted file mode 100644 index a5919e47f5..0000000000 --- a/briar-android/src/main/res/layout/invitation_bluetooth_confirmation_code.xml +++ /dev/null @@ -1,109 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ScrollView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <RelativeLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingBottom="@dimen/margin_activity_vertical" - android:paddingEnd="@dimen/margin_activity_horizontal" - android:paddingRight="@dimen/margin_activity_horizontal" - android:paddingStart="@dimen/margin_activity_horizontal" - android:paddingLeft="@dimen/margin_activity_horizontal" - android:paddingTop="@dimen/margin_activity_vertical"> - - <TextView - android:id="@+id/connectedView" - style="@style/BriarTextTitle" - android:textSize="@dimen/text_size_large" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/connected_to_contact" - android:padding="@dimen/margin_medium" - android:layout_centerHorizontal="true" - android:drawableLeft="@drawable/navigation_accept" - android:drawableStart="@drawable/navigation_accept" - android:gravity="center_vertical"/> - - <TextView - android:id="@+id/yourConfirmationCodeView" - style="@style/BriarTextBody" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/your_confirmation_code" - android:padding="@dimen/margin_medium" - android:layout_below="@+id/connectedView" - android:layout_centerHorizontal="true"/> - - <TextView - android:id="@+id/codeView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="@dimen/margin_medium" - android:textSize="50sp" - android:textColor="@color/briar_text_secondary" - android:layout_below="@+id/yourConfirmationCodeView" - android:layout_centerHorizontal="true" - tools:text="1337"/> - - <TextView - android:id="@+id/waitingView" - style="@style/BriarTextBody" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/searching_format" - android:layout_gravity="center_horizontal" - android:padding="@dimen/margin_medium" - android:layout_below="@+id/codeView" - android:layout_centerHorizontal="true" - android:visibility="gone" - android:gravity="center_horizontal"/> - - <ProgressBar - android:id="@+id/progressBar" - style="?android:attr/progressBarStyleLarge" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:indeterminate="true" - android:layout_below="@+id/waitingView" - android:layout_centerHorizontal="true" - android:visibility="gone"/> - - <TextView - android:id="@+id/enterCodeTextView" - style="@style/BriarTextBody" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/enter_confirmation_code" - android:layout_gravity="center_horizontal" - android:padding="@dimen/margin_medium" - android:layout_below="@+id/codeView" - android:layout_centerHorizontal="true"/> - - <include - android:id="@+id/codeEntryView" - layout="@layout/view_code_entry" - android:layout_below="@+id/enterCodeTextView" - android:layout_centerHorizontal="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_margin="@dimen/margin_medium"/> - - <Button - android:id="@+id/continueButton" - style="@style/BriarButton.Default" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/continue_button" - android:layout_gravity="center_horizontal" - android:enabled="false" - android:layout_below="@+id/codeEntryView" - android:layout_centerHorizontal="true" - android:layout_margin="@dimen/margin_medium"/> - - </RelativeLayout> -</ScrollView> \ No newline at end of file diff --git a/briar-android/src/main/res/layout/invitation_bluetooth_invitation_code.xml b/briar-android/src/main/res/layout/invitation_bluetooth_invitation_code.xml deleted file mode 100644 index 9f8aaa9e4a..0000000000 --- a/briar-android/src/main/res/layout/invitation_bluetooth_invitation_code.xml +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ScrollView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <RelativeLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingBottom="@dimen/margin_activity_vertical" - android:paddingEnd="@dimen/margin_activity_horizontal" - android:paddingRight="@dimen/margin_activity_horizontal" - android:paddingStart="@dimen/margin_activity_horizontal" - android:paddingLeft="@dimen/margin_activity_horizontal" - android:paddingTop="@dimen/margin_activity_vertical"> - - <TextView - android:id="@+id/yourCodeView" - style="@style/BriarTextBody" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/your_invitation_code" - android:layout_marginTop="@dimen/margin_medium" - android:layout_centerHorizontal="true"/> - - <TextView - android:id="@+id/codeView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/margin_medium" - android:textSize="50sp" - android:textColor="@color/briar_text_secondary" - android:layout_below="@+id/yourCodeView" - android:layout_centerHorizontal="true" - tools:text="1337"/> - - <TextView - android:id="@+id/waitingView" - style="@style/BriarTextBody" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/searching_format" - android:layout_gravity="center_horizontal" - android:layout_marginTop="@dimen/margin_medium" - android:layout_below="@+id/codeView" - android:layout_centerHorizontal="true" - android:visibility="gone" - android:gravity="center_horizontal"/> - - <ProgressBar - android:id="@+id/progressBar" - style="?android:attr/progressBarStyleLarge" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/margin_medium" - android:indeterminate="true" - android:layout_below="@+id/waitingView" - android:layout_centerHorizontal="true" - android:visibility="gone"/> - - <TextView - android:id="@+id/enterCodeTextView" - style="@style/BriarTextBody" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/enter_invitation_code" - android:layout_gravity="center_horizontal" - android:padding="@dimen/margin_medium" - android:layout_below="@+id/codeView" - android:layout_centerHorizontal="true"/> - - <include - android:id="@+id/codeEntryView" - layout="@layout/view_code_entry" - android:layout_below="@+id/enterCodeTextView" - android:layout_centerHorizontal="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_margin="@dimen/margin_medium"/> - - <Button - android:id="@+id/continueButton" - style="@style/BriarButton.Default" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/continue_button" - android:layout_gravity="center_horizontal" - android:enabled="false" - android:layout_below="@+id/codeEntryView" - android:layout_centerHorizontal="true" - android:layout_margin="@dimen/margin_medium"/> - - </RelativeLayout> -</ScrollView> \ No newline at end of file diff --git a/briar-android/src/main/res/layout/invitation_bluetooth_start.xml b/briar-android/src/main/res/layout/invitation_bluetooth_start.xml deleted file mode 100644 index af184c6411..0000000000 --- a/briar-android/src/main/res/layout/invitation_bluetooth_start.xml +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ScrollView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:paddingBottom="@dimen/margin_activity_vertical" - android:paddingEnd="@dimen/margin_activity_horizontal" - android:paddingLeft="@dimen/margin_activity_horizontal" - android:paddingRight="@dimen/margin_activity_horizontal" - android:paddingStart="@dimen/margin_activity_horizontal" - android:paddingTop="@dimen/margin_activity_vertical"> - - <TextView - style="@style/BriarTextBody" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/your_nickname" - android:visibility="gone"/> - - <Spinner - android:id="@+id/spinner" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@drawable/border_spinner" - android:layout_marginTop="@dimen/margin_medium" - android:spinnerMode="dropdown" - android:visibility="gone"/> - - <ImageView - android:id="@+id/imageView" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/margin_xlarge" - android:adjustViewBounds="true" - android:scaleType="fitCenter" - android:src="@drawable/bluetooth"/> - - <TextView - style="@style/BriarTextBody" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/margin_xlarge" - android:text="@string/face_to_face"/> - - <Button - android:id="@+id/continueButton" - style="@style/BriarButton.Default" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="center_horizontal" - android:layout_marginTop="@dimen/margin_medium" - android:text="@string/continue_button"/> - </LinearLayout> - -</ScrollView> \ No newline at end of file diff --git a/briar-android/src/main/res/layout/invitation_error.xml b/briar-android/src/main/res/layout/invitation_error.xml deleted file mode 100644 index 01fc51da70..0000000000 --- a/briar-android/src/main/res/layout/invitation_error.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingBottom="@dimen/margin_activity_vertical" - android:paddingEnd="@dimen/margin_activity_horizontal" - android:paddingStart="@dimen/margin_activity_horizontal" - android:paddingTop="@dimen/margin_activity_vertical"> - - <TextView - android:id="@+id/errorTextView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/connection_failed" - android:layout_gravity="center_horizontal" - android:textSize="@dimen/text_size_large" - android:textColor="@color/briar_text_primary" - android:drawableStart="@drawable/alerts_and_states_error" - android:drawableLeft="@drawable/alerts_and_states_error" - android:gravity="center_vertical" - android:padding="@dimen/margin_medium"/> - - <TextView - android:id="@+id/explanationTextView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/interfering" - android:textColor="@color/briar_text_primary" - android:layout_gravity="center_horizontal" - android:padding="@dimen/margin_medium"/> - - <Button - android:id="@+id/tryAgainButton" - style="@style/BriarButton.Default" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/try_again_button" - android:layout_gravity="center_horizontal" - android:layout_margin="@dimen/margin_medium"/> - -</LinearLayout> \ No newline at end of file diff --git a/briar-android/src/main/res/layout/view_code_entry.xml b/briar-android/src/main/res/layout/view_code_entry.xml deleted file mode 100644 index 2c735f0461..0000000000 --- a/briar-android/src/main/res/layout/view_code_entry.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<EditText - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/codeEntryView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:inputType="number" - android:layout_gravity="center_horizontal" - android:textSize="@dimen/text_size_xlarge" - android:ems="4" - android:maxLines="1" - android:maxLength="6" - android:layout_margin="@dimen/margin_medium" - android:imeOptions="actionGo" - tools:text="123456"/> \ No newline at end of file diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 3a20ab2e72..821642c2f8 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -98,24 +98,12 @@ <!-- Adding Contacts --> <string name="add_contact_title">Add a Contact</string> - <string name="your_nickname">Choose the identity you want to use:</string> <string name="face_to_face">You must meet up with the person you want to add as a contact.\n\nThis will prevent anyone from impersonating you or reading your messages in future.</string> <string name="continue_button">Continue</string> - <string name="your_invitation_code">Your invitation code is</string> - <string name="enter_invitation_code">Please enter your contact\'s invitation code:</string> - <string name="searching_format">Searching for contact with invitation code %06d\u2026</string> <string name="connection_failed">Connection failed</string> - <string name="could_not_find_contact">Briar could not find your contact nearby</string> <string name="try_again_button">Try Again</string> - <string name="connected_to_contact">Connected to contact</string> - <string name="calculating_confirmation_code">Calculating confirmation code\u2026</string> - <string name="your_confirmation_code">Your confirmation code is</string> - <string name="enter_confirmation_code">Please enter your contact\'s confirmation code:</string> - <string name="waiting_for_contact">Waiting for contact\u2026</string> <string name="waiting_for_contact_to_scan">Waiting for contact to scan and connect\u2026</string> <string name="exchanging_contact_details">Exchanging contact details\u2026</string> - <string name="codes_do_not_match">Codes do not match</string> - <string name="interfering">This could mean that someone is trying to interfere with your connection</string> <string name="contact_added_toast">Contact added: %s</string> <string name="contact_already_exists">Contact %s already exists</string> <string name="contact_exchange_failed">Contact exchange failed</string> -- GitLab