Implement BQP transport descriptors

This commit is contained in:
str4d
2016-01-28 23:23:43 +00:00
parent 65316414ea
commit d2d8d9d46e
11 changed files with 347 additions and 14 deletions

View File

@@ -14,6 +14,9 @@ import org.briarproject.api.TransportId;
import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.keyagreement.KeyAgreementConnection;
import org.briarproject.api.keyagreement.KeyAgreementListener;
import org.briarproject.api.keyagreement.TransportDescriptor;
import org.briarproject.api.plugins.Backoff;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
@@ -67,6 +70,9 @@ class DroidtoothPlugin implements DuplexPlugin {
private static final String DISCOVERY_FINISHED =
"android.bluetooth.adapter.action.DISCOVERY_FINISHED";
private static final String PROP_ADDRESS = "address";
private static final String PROP_UUID = "uuid";
private final Executor ioExecutor;
private final AndroidExecutor androidExecutor;
private final Context appContext;
@@ -161,7 +167,7 @@ class DroidtoothPlugin implements DuplexPlugin {
if (!StringUtils.isNullOrEmpty(address)) {
// Advertise the Bluetooth address to contacts
TransportProperties p = new TransportProperties();
p.put("address", address);
p.put(PROP_ADDRESS, address);
callback.mergeLocalProperties(p);
}
// Bind a server socket to accept connections from contacts
@@ -187,13 +193,13 @@ class DroidtoothPlugin implements DuplexPlugin {
}
private UUID getUuid() {
String uuid = callback.getLocalProperties().get("uuid");
String uuid = callback.getLocalProperties().get(PROP_UUID);
if (uuid == null) {
byte[] random = new byte[UUID_BYTES];
secureRandom.nextBytes(random);
uuid = UUID.nameUUIDFromBytes(random).toString();
TransportProperties p = new TransportProperties();
p.put("uuid", uuid);
p.put(PROP_UUID, uuid);
callback.mergeLocalProperties(p);
}
return UUID.fromString(uuid);
@@ -264,9 +270,9 @@ class DroidtoothPlugin implements DuplexPlugin {
for (Entry<ContactId, TransportProperties> e : remote.entrySet()) {
final ContactId c = e.getKey();
if (connected.contains(c)) continue;
final String address = e.getValue().get("address");
final String address = e.getValue().get(PROP_ADDRESS);
if (StringUtils.isNullOrEmpty(address)) continue;
final String uuid = e.getValue().get("uuid");
final String uuid = e.getValue().get(PROP_UUID);
if (StringUtils.isNullOrEmpty(uuid)) continue;
ioExecutor.execute(new Runnable() {
public void run() {
@@ -325,9 +331,9 @@ class DroidtoothPlugin implements DuplexPlugin {
if (!isRunning()) return null;
TransportProperties p = callback.getRemoteProperties().get(c);
if (p == null) return null;
String address = p.get("address");
String address = p.get(PROP_ADDRESS);
if (StringUtils.isNullOrEmpty(address)) return null;
String uuid = p.get("uuid");
String uuid = p.get(PROP_UUID);
if (StringUtils.isNullOrEmpty(uuid)) return null;
BluetoothSocket s = connect(address, uuid);
if (s == null) return null;
@@ -417,6 +423,48 @@ class DroidtoothPlugin implements DuplexPlugin {
});
}
public boolean supportsKeyAgreement() {
return true;
}
public KeyAgreementListener createKeyAgreementListener(
byte[] localCommitment) {
// No truncation necessary because COMMIT_LENGTH = 16
UUID uuid = UUID.nameUUIDFromBytes(localCommitment);
if (LOG.isLoggable(INFO)) LOG.info("Key agreement UUID " + uuid);
// Bind a server socket for receiving invitation connections
BluetoothServerSocket ss;
try {
ss = InsecureBluetooth.listen(adapter, "RFCOMM", uuid);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null;
}
TransportProperties p = new TransportProperties();
String address = AndroidUtils.getBluetoothAddress(appContext, adapter);
if (!StringUtils.isNullOrEmpty(address))
p.put(PROP_ADDRESS, address);
TransportDescriptor d = new TransportDescriptor(ID, p);
return new BluetoothKeyAgreementListener(d, ss);
}
public DuplexTransportConnection createKeyAgreementConnection(
byte[] remoteCommitment, TransportDescriptor d, long timeout) {
if (!isRunning()) return null;
if (!ID.equals(d.getIdentifier())) return null;
TransportProperties p = d.getProperties();
if (p == null) return null;
String address = p.get(PROP_ADDRESS);
if (StringUtils.isNullOrEmpty(address)) return null;
// No truncation necessary because COMMIT_LENGTH = 16
UUID uuid = UUID.nameUUIDFromBytes(remoteCommitment);
if (LOG.isLoggable(INFO))
LOG.info("Connecting to key agreement UUID " + uuid);
BluetoothSocket s = connect(address, uuid.toString());
if (s == null) return null;
return new DroidtoothTransportConnection(this, s);
}
private class BluetoothStateReceiver extends BroadcastReceiver {
@Override
@@ -545,4 +593,39 @@ class DroidtoothPlugin implements DuplexPlugin {
return s;
}
}
private class BluetoothKeyAgreementListener extends KeyAgreementListener {
private final BluetoothServerSocket ss;
public BluetoothKeyAgreementListener(TransportDescriptor descriptor,
BluetoothServerSocket ss) {
super(descriptor);
this.ss = ss;
}
@Override
public Callable<KeyAgreementConnection> listen() {
return new Callable<KeyAgreementConnection>() {
@Override
public KeyAgreementConnection call() throws IOException {
BluetoothSocket s = ss.accept();
if (LOG.isLoggable(INFO))
LOG.info(ID.getString() + ": Incoming connection");
return new KeyAgreementConnection(
new DroidtoothTransportConnection(
DroidtoothPlugin.this, s), ID);
}
};
}
@Override
public void close() {
try {
ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
}
}

View File

@@ -19,6 +19,8 @@ import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.keyagreement.KeyAgreementListener;
import org.briarproject.api.keyagreement.TransportDescriptor;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
@@ -570,6 +572,20 @@ class TorPlugin implements DuplexPlugin, EventHandler,
throw new UnsupportedOperationException();
}
public boolean supportsKeyAgreement() {
return false;
}
public KeyAgreementListener createKeyAgreementListener(
byte[] commitment) {
throw new UnsupportedOperationException();
}
public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, TransportDescriptor d, long timeout) {
throw new UnsupportedOperationException();
}
public void circuitStatus(String status, String id, String path) {
if (status.equals("BUILT") && !circuitBuilt.getAndSet(true)) {
LOG.info("First circuit built");