From 501c2dab315688ffe007d7419de33b74904ba34e Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Wed, 9 Nov 2016 15:55:31 +0000 Subject: [PATCH] Preserve the order of descriptors in QR code payloads. --- .../api/keyagreement/Payload.java | 10 ++- .../api/keyagreement/TransportDescriptor.java | 28 ++++++++ .../keyagreement/KeyAgreementConnector.java | 19 +++-- .../keyagreement/KeyAgreementProtocol.java | 70 ++++++++++--------- .../keyagreement/PayloadEncoderImpl.java | 9 +-- .../keyagreement/PayloadParserImpl.java | 15 ++-- 6 files changed, 88 insertions(+), 63 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/keyagreement/TransportDescriptor.java diff --git a/briar-api/src/org/briarproject/api/keyagreement/Payload.java b/briar-api/src/org/briarproject/api/keyagreement/Payload.java index 60cbb45a36..14cb82421f 100644 --- a/briar-api/src/org/briarproject/api/keyagreement/Payload.java +++ b/briar-api/src/org/briarproject/api/keyagreement/Payload.java @@ -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; } diff --git a/briar-api/src/org/briarproject/api/keyagreement/TransportDescriptor.java b/briar-api/src/org/briarproject/api/keyagreement/TransportDescriptor.java new file mode 100644 index 0000000000..7b61d74ffd --- /dev/null +++ b/briar-api/src/org/briarproject/api/keyagreement/TransportDescriptor.java @@ -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; + } +} diff --git a/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java b/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java index 44636b31d6..ee5c0e10dd 100644 --- a/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java +++ b/briar-core/src/org/briarproject/keyagreement/KeyAgreementConnector.java @@ -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)))); } } diff --git a/briar-core/src/org/briarproject/keyagreement/KeyAgreementProtocol.java b/briar-core/src/org/briarproject/keyagreement/KeyAgreementProtocol.java index c832edd092..f67a85ecd6 100644 --- a/briar-core/src/org/briarproject/keyagreement/KeyAgreementProtocol.java +++ b/briar-core/src/org/briarproject/keyagreement/KeyAgreementProtocol.java @@ -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) { diff --git a/briar-core/src/org/briarproject/keyagreement/PayloadEncoderImpl.java b/briar-core/src/org/briarproject/keyagreement/PayloadEncoderImpl.java index 32342993c1..ac1a647d13 100644 --- a/briar-core/src/org/briarproject/keyagreement/PayloadEncoderImpl.java +++ b/briar-core/src/org/briarproject/keyagreement/PayloadEncoderImpl.java @@ -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 diff --git a/briar-core/src/org/briarproject/keyagreement/PayloadParserImpl.java b/briar-core/src/org/briarproject/keyagreement/PayloadParserImpl.java index 105311811b..1f9b656357 100644 --- a/briar-core/src/org/briarproject/keyagreement/PayloadParserImpl.java +++ b/briar-core/src/org/briarproject/keyagreement/PayloadParserImpl.java @@ -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); -- GitLab