Merge branch '748-qr-code-payload-order' into 'master'

Preserve the order of descriptors in QR code payloads

This fixes a regression caused by my recent changes to the Payload class.

Closes #748

See merge request !399
This commit is contained in:
akwizgran
2016-11-10 12:21:36 +00:00
6 changed files with 88 additions and 63 deletions

View File

@@ -1,11 +1,9 @@
package org.briarproject.api.keyagreement;
import org.briarproject.api.Bytes;
import org.briarproject.api.TransportId;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.nullsafety.NotNullByDefault;
import java.util.Map;
import java.util.List;
import javax.annotation.concurrent.Immutable;
@@ -17,9 +15,9 @@ import javax.annotation.concurrent.Immutable;
public class Payload implements Comparable<Payload> {
private final Bytes commitment;
private final Map<TransportId, BdfList> descriptors;
private final List<TransportDescriptor> descriptors;
public Payload(byte[] commitment, Map<TransportId, BdfList> descriptors) {
public Payload(byte[] commitment, List<TransportDescriptor> descriptors) {
this.commitment = new Bytes(commitment);
this.descriptors = descriptors;
}
@@ -34,7 +32,7 @@ public class Payload implements Comparable<Payload> {
/**
* Returns the transport descriptors contained in this payload.
*/
public Map<TransportId, BdfList> getTransportDescriptors() {
public List<TransportDescriptor> getTransportDescriptors() {
return descriptors;
}

View File

@@ -0,0 +1,28 @@
package org.briarproject.api.keyagreement;
import org.briarproject.api.TransportId;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class TransportDescriptor {
private final TransportId id;
private final BdfList descriptor;
public TransportDescriptor(TransportId id, BdfList descriptor) {
this.id = id;
this.descriptor = descriptor;
}
public TransportId getId() {
return id;
}
public BdfList getDescriptor() {
return descriptor;
}
}

View File

@@ -7,6 +7,7 @@ import org.briarproject.api.data.BdfList;
import org.briarproject.api.keyagreement.KeyAgreementConnection;
import org.briarproject.api.keyagreement.KeyAgreementListener;
import org.briarproject.api.keyagreement.Payload;
import org.briarproject.api.keyagreement.TransportDescriptor;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
@@ -16,10 +17,7 @@ import org.briarproject.api.system.Clock;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
@@ -73,13 +71,14 @@ class KeyAgreementConnector {
byte[] commitment = crypto.deriveKeyCommitment(
localKeyPair.getPublic().getEncoded());
// Start all listeners and collect their descriptors
Map<TransportId, BdfList> descriptors =
new HashMap<TransportId, BdfList>();
List<TransportDescriptor> descriptors =
new ArrayList<TransportDescriptor>();
for (DuplexPlugin plugin : pluginManager.getKeyAgreementPlugins()) {
KeyAgreementListener l =
plugin.createKeyAgreementListener(commitment);
if (l != null) {
descriptors.put(plugin.getId(), l.getDescriptor());
TransportId id = plugin.getId();
descriptors.add(new TransportDescriptor(id, l.getDescriptor()));
pending.add(connect.submit(new ReadableTask(l.listen())));
listeners.add(l);
}
@@ -104,15 +103,13 @@ class KeyAgreementConnector {
// Start connecting over supported transports
LOG.info("Starting outgoing BQP connections");
Map<TransportId, BdfList> descriptors =
remotePayload.getTransportDescriptors();
for (Entry<TransportId, BdfList> e : descriptors.entrySet()) {
Plugin p = pluginManager.getPlugin(e.getKey());
for (TransportDescriptor d : remotePayload.getTransportDescriptors()) {
Plugin p = pluginManager.getPlugin(d.getId());
if (p instanceof DuplexPlugin) {
DuplexPlugin plugin = (DuplexPlugin) p;
pending.add(connect.submit(new ReadableTask(
new ConnectorTask(plugin, remotePayload.getCommitment(),
e.getValue(), end))));
d.getDescriptor(), end))));
}
}

View File

@@ -15,51 +15,53 @@ import java.util.Arrays;
* <p/>
* Alice:
* <ul>
* <li>Send A_KEY</li>
* <li>Receive B_KEY
* <ul>
* <li>Check B_KEY matches B_COMMIT</li>
* </ul></li>
* <li>Calculate s</li>
* <li>Send A_CONFIRM</li>
* <li>Receive B_CONFIRM
* <ul>
* <li>Check B_CONFIRM matches expected</li>
* </ul></li>
* <li>Derive master</li>
* <li>Send A_KEY</li>
* <li>Receive B_KEY
* <ul>
* <li>Check B_KEY matches B_COMMIT</li>
* </ul></li>
* <li>Calculate s</li>
* <li>Send A_CONFIRM</li>
* <li>Receive B_CONFIRM
* <ul>
* <li>Check B_CONFIRM matches expected</li>
* </ul></li>
* <li>Derive master</li>
* </ul><p/>
* Bob:
* <ul>
* <li>Receive A_KEY
* <ul>
* <li>Check A_KEY matches A_COMMIT</li>
* </ul></li>
* <li>Send B_KEY</li>
* <li>Calculate s</li>
* <li>Receive A_CONFIRM
* <ul>
* <li>Check A_CONFIRM matches expected</li>
* </ul></li>
* <li>Send B_CONFIRM</li>
* <li>Derive master</li>
* <li>Receive A_KEY
* <ul>
* <li>Check A_KEY matches A_COMMIT</li>
* </ul></li>
* <li>Send B_KEY</li>
* <li>Calculate s</li>
* <li>Receive A_CONFIRM
* <ul>
* <li>Check A_CONFIRM matches expected</li>
* </ul></li>
* <li>Send B_CONFIRM</li>
* <li>Derive master</li>
* </ul>
*/
class KeyAgreementProtocol {
interface Callbacks {
void connectionWaiting();
void initialPacketReceived();
}
private Callbacks callbacks;
private CryptoComponent crypto;
private PayloadEncoder payloadEncoder;
private KeyAgreementTransport transport;
private Payload theirPayload, ourPayload;
private KeyPair ourKeyPair;
private boolean alice;
private final Callbacks callbacks;
private final CryptoComponent crypto;
private final PayloadEncoder payloadEncoder;
private final KeyAgreementTransport transport;
private final Payload theirPayload, ourPayload;
private final KeyPair ourKeyPair;
private final boolean alice;
public KeyAgreementProtocol(Callbacks callbacks, CryptoComponent crypto,
KeyAgreementProtocol(Callbacks callbacks, CryptoComponent crypto,
PayloadEncoder payloadEncoder, KeyAgreementTransport transport,
Payload theirPayload, Payload ourPayload, KeyPair ourKeyPair,
boolean alice) {
@@ -78,9 +80,9 @@ class KeyAgreementProtocol {
*
* @return the negotiated master secret.
* @throws AbortException when the protocol may have been tampered with.
* @throws IOException for all other other connection errors.
* @throws IOException for all other other connection errors.
*/
public SecretKey perform() throws AbortException, IOException {
SecretKey perform() throws AbortException, IOException {
try {
byte[] theirPublicKey;
if (alice) {

View File

@@ -1,16 +1,14 @@
package org.briarproject.keyagreement;
import org.briarproject.api.TransportId;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.BdfWriter;
import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.keyagreement.Payload;
import org.briarproject.api.keyagreement.PayloadEncoder;
import org.briarproject.api.keyagreement.TransportDescriptor;
import org.briarproject.api.nullsafety.NotNullByDefault;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
@@ -36,9 +34,8 @@ class PayloadEncoderImpl implements PayloadEncoder {
w.writeListStart(); // Payload start
w.writeLong(PROTOCOL_VERSION);
w.writeRaw(p.getCommitment());
Map<TransportId, BdfList> descriptors = p.getTransportDescriptors();
for (BdfList descriptor : descriptors.values())
w.writeList(descriptor);
for (TransportDescriptor d : p.getTransportDescriptors())
w.writeList(d.getDescriptor());
w.writeListEnd(); // Payload end
} catch (IOException e) {
// Shouldn't happen with ByteArrayOutputStream

View File

@@ -7,12 +7,13 @@ import org.briarproject.api.data.BdfReader;
import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.keyagreement.Payload;
import org.briarproject.api.keyagreement.PayloadParser;
import org.briarproject.api.keyagreement.TransportDescriptor;
import org.briarproject.api.nullsafety.NotNullByDefault;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
@@ -48,15 +49,17 @@ class PayloadParserImpl implements PayloadParser {
byte[] commitment = payload.getRaw(1);
if (commitment.length != COMMIT_LENGTH) throw new FormatException();
// Remaining elements: transport descriptors
Map<TransportId, BdfList> recognised =
new HashMap<TransportId, BdfList>();
List<TransportDescriptor> recognised =
new ArrayList<TransportDescriptor>();
for (int i = 2; i < payload.size(); i++) {
BdfList descriptor = payload.getList(i);
long transportId = descriptor.getLong(0);
if (transportId == TRANSPORT_ID_BLUETOOTH) {
recognised.put(new TransportId("bt"), descriptor);
TransportId id = new TransportId("bt");
recognised.add(new TransportDescriptor(id, descriptor));
} else if (transportId == TRANSPORT_ID_LAN) {
recognised.put(new TransportId("lan"), descriptor);
TransportId id = new TransportId("lan");
recognised.add(new TransportDescriptor(id, descriptor));
}
}
return new Payload(commitment, recognised);