From 501c2dab315688ffe007d7419de33b74904ba34e Mon Sep 17 00:00:00 2001 From: akwizgran 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 60cbb45a3..14cb82421 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 { private final Bytes commitment; - private final Map descriptors; + private final List descriptors; - public Payload(byte[] commitment, Map descriptors) { + public Payload(byte[] commitment, List descriptors) { this.commitment = new Bytes(commitment); this.descriptors = descriptors; } @@ -34,7 +32,7 @@ public class Payload implements Comparable { /** * Returns the transport descriptors contained in this payload. */ - public Map getTransportDescriptors() { + public List 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 000000000..7b61d74ff --- /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 44636b31d..ee5c0e10d 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 descriptors = - new HashMap(); + List descriptors = + new ArrayList(); 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 descriptors = - remotePayload.getTransportDescriptors(); - for (Entry 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 c832edd09..f67a85ecd 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; *

* Alice: *

    - *
  • Send A_KEY
  • - *
  • Receive B_KEY - *
      - *
    • Check B_KEY matches B_COMMIT
    • - *
  • - *
  • Calculate s
  • - *
  • Send A_CONFIRM
  • - *
  • Receive B_CONFIRM - *
      - *
    • Check B_CONFIRM matches expected
    • - *
  • - *
  • Derive master
  • + *
  • Send A_KEY
  • + *
  • Receive B_KEY + *
      + *
    • Check B_KEY matches B_COMMIT
    • + *
  • + *
  • Calculate s
  • + *
  • Send A_CONFIRM
  • + *
  • Receive B_CONFIRM + *
      + *
    • Check B_CONFIRM matches expected
    • + *
  • + *
  • Derive master
  • *

* Bob: *

    - *
  • Receive A_KEY - *
      - *
    • Check A_KEY matches A_COMMIT
    • - *
  • - *
  • Send B_KEY
  • - *
  • Calculate s
  • - *
  • Receive A_CONFIRM - *
      - *
    • Check A_CONFIRM matches expected
    • - *
  • - *
  • Send B_CONFIRM
  • - *
  • Derive master
  • + *
  • Receive A_KEY + *
      + *
    • Check A_KEY matches A_COMMIT
    • + *
  • + *
  • Send B_KEY
  • + *
  • Calculate s
  • + *
  • Receive A_CONFIRM + *
      + *
    • Check A_CONFIRM matches expected
    • + *
  • + *
  • Send B_CONFIRM
  • + *
  • Derive master
  • *
*/ 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 32342993c..ac1a647d1 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 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 105311811..1f9b65635 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 recognised = - new HashMap(); + List recognised = + new ArrayList(); 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);