From ce7c189923d7b553361f19584a45626e76f7f7e6 Mon Sep 17 00:00:00 2001
From: str4d <str4d@mail.i2p>
Date: Tue, 2 Feb 2016 05:52:30 +0000
Subject: [PATCH] Create BQP API

---
 .../api/event/KeyAgreementAbortedEvent.java   | 15 ++++++++
 .../api/event/KeyAgreementFailedEvent.java    |  6 +++
 .../api/event/KeyAgreementFinishedEvent.java  | 17 +++++++++
 .../api/event/KeyAgreementListeningEvent.java | 17 +++++++++
 .../api/event/KeyAgreementStartedEvent.java   |  6 +++
 .../api/event/KeyAgreementWaitingEvent.java   |  9 +++++
 .../keyagreement/KeyAgreementConstants.java   | 11 ++++++
 .../api/keyagreement/KeyAgreementResult.java  | 38 +++++++++++++++++++
 .../api/keyagreement/KeyAgreementTask.java    | 21 ++++++++++
 .../keyagreement/KeyAgreementTaskFactory.java |  8 ++++
 .../api/keyagreement/KeyAgreementTaskId.java  | 18 +++++++++
 .../api/keyagreement/Payload.java             | 34 +++++++++++++++++
 .../api/keyagreement/PayloadEncoder.java      |  6 +++
 .../api/keyagreement/PayloadParser.java       |  8 ++++
 .../api/keyagreement/RecordTypes.java         |  9 +++++
 15 files changed, 223 insertions(+)
 create mode 100644 briar-api/src/org/briarproject/api/event/KeyAgreementAbortedEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/event/KeyAgreementFailedEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/event/KeyAgreementFinishedEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/event/KeyAgreementListeningEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/event/KeyAgreementStartedEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/event/KeyAgreementWaitingEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/KeyAgreementResult.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTask.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskFactory.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskId.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/Payload.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/PayloadEncoder.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/PayloadParser.java
 create mode 100644 briar-api/src/org/briarproject/api/keyagreement/RecordTypes.java

diff --git a/briar-api/src/org/briarproject/api/event/KeyAgreementAbortedEvent.java b/briar-api/src/org/briarproject/api/event/KeyAgreementAbortedEvent.java
new file mode 100644
index 0000000000..5e217f7f4d
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/KeyAgreementAbortedEvent.java
@@ -0,0 +1,15 @@
+package org.briarproject.api.event;
+
+/** An event that is broadcast when a BQP protocol aborts. */
+public class KeyAgreementAbortedEvent extends Event {
+
+	private final boolean remoteAborted;
+
+	public KeyAgreementAbortedEvent(boolean remoteAborted) {
+		this.remoteAborted = remoteAborted;
+	}
+
+	public boolean didRemoteAbort() {
+		return remoteAborted;
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/event/KeyAgreementFailedEvent.java b/briar-api/src/org/briarproject/api/event/KeyAgreementFailedEvent.java
new file mode 100644
index 0000000000..97313a276b
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/KeyAgreementFailedEvent.java
@@ -0,0 +1,6 @@
+package org.briarproject.api.event;
+
+/** An event that is broadcast when a BQP connection cannot be created. */
+public class KeyAgreementFailedEvent extends Event {
+
+}
diff --git a/briar-api/src/org/briarproject/api/event/KeyAgreementFinishedEvent.java b/briar-api/src/org/briarproject/api/event/KeyAgreementFinishedEvent.java
new file mode 100644
index 0000000000..f2afe349eb
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/KeyAgreementFinishedEvent.java
@@ -0,0 +1,17 @@
+package org.briarproject.api.event;
+
+import org.briarproject.api.keyagreement.KeyAgreementResult;
+
+/** An event that is broadcast when a BQP protocol completes. */
+public class KeyAgreementFinishedEvent extends Event {
+
+	private final KeyAgreementResult result;
+
+	public KeyAgreementFinishedEvent(KeyAgreementResult result) {
+		this.result = result;
+	}
+
+	public KeyAgreementResult getResult() {
+		return result;
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/event/KeyAgreementListeningEvent.java b/briar-api/src/org/briarproject/api/event/KeyAgreementListeningEvent.java
new file mode 100644
index 0000000000..df3b2cbac5
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/KeyAgreementListeningEvent.java
@@ -0,0 +1,17 @@
+package org.briarproject.api.event;
+
+import org.briarproject.api.keyagreement.Payload;
+
+/** An event that is broadcast when a BQP task is listening. */
+public class KeyAgreementListeningEvent extends Event {
+
+	private final Payload localPayload;
+
+	public KeyAgreementListeningEvent(Payload localPayload) {
+		this.localPayload = localPayload;
+	}
+
+	public Payload getLocalPayload() {
+		return localPayload;
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/event/KeyAgreementStartedEvent.java b/briar-api/src/org/briarproject/api/event/KeyAgreementStartedEvent.java
new file mode 100644
index 0000000000..a12a9c459a
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/KeyAgreementStartedEvent.java
@@ -0,0 +1,6 @@
+package org.briarproject.api.event;
+
+/** An event that is broadcast when a BQP protocol completes. */
+public class KeyAgreementStartedEvent extends Event {
+
+}
diff --git a/briar-api/src/org/briarproject/api/event/KeyAgreementWaitingEvent.java b/briar-api/src/org/briarproject/api/event/KeyAgreementWaitingEvent.java
new file mode 100644
index 0000000000..473c6538ad
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/KeyAgreementWaitingEvent.java
@@ -0,0 +1,9 @@
+package org.briarproject.api.event;
+
+/**
+ * An event that is broadcast when a BQP protocol is waiting on the remote
+ * peer to start.
+ */
+public class KeyAgreementWaitingEvent extends Event {
+
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementConstants.java b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementConstants.java
index 521789244d..f239111269 100644
--- a/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementConstants.java
+++ b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementConstants.java
@@ -3,6 +3,17 @@ package org.briarproject.api.keyagreement;
 
 public interface KeyAgreementConstants {
 
+	/** The current version of the BQP protocol. */
+	byte PROTOCOL_VERSION = 1;
+
+	/** The length of the record header in bytes. */
+	int RECORD_HEADER_LENGTH = 4;
+
+	/** The offset of the payload length in the record header, in bytes. */
+	int RECORD_HEADER_PAYLOAD_LENGTH_OFFSET = 2;
+
 	/** The length of the BQP key commitment in bytes. */
 	int COMMIT_LENGTH = 16;
+
+	long CONNECTION_TIMEOUT = 20 * 1000; // Milliseconds
 }
diff --git a/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementResult.java b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementResult.java
new file mode 100644
index 0000000000..3f772ca287
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementResult.java
@@ -0,0 +1,38 @@
+package org.briarproject.api.keyagreement;
+
+import org.briarproject.api.TransportId;
+import org.briarproject.api.crypto.SecretKey;
+import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+
+public class KeyAgreementResult {
+
+	private final SecretKey masterKey;
+	private final DuplexTransportConnection connection;
+	private final TransportId transportId;
+	private final boolean alice;
+
+	public KeyAgreementResult(SecretKey masterKey,
+			DuplexTransportConnection connection, TransportId transportId,
+			boolean alice) {
+		this.masterKey = masterKey;
+		this.connection = connection;
+		this.transportId = transportId;
+		this.alice = alice;
+	}
+
+	public SecretKey getMasterKey() {
+		return masterKey;
+	}
+
+	public DuplexTransportConnection getConnection() {
+		return connection;
+	}
+
+	public TransportId getTransportId() {
+		return transportId;
+	}
+
+	public boolean wasAlice() {
+		return alice;
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTask.java b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTask.java
new file mode 100644
index 0000000000..443ef42bd6
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTask.java
@@ -0,0 +1,21 @@
+package org.briarproject.api.keyagreement;
+
+/** A task for conducting a key agreement with a remote peer. */
+public interface KeyAgreementTask {
+
+	/**
+	 * Start listening for short-range BQP connections, if we are not already.
+	 * <p/>
+	 * Will trigger a KeyAgreementListeningEvent containing the local Payload,
+	 * even if we are already listening.
+	 */
+	void listen();
+
+	/**
+	 * Stop listening for short-range BQP connections.
+	 */
+	void stopListening();
+
+	/** Asynchronously start the connection process. */
+	void connectAndRunProtocol(Payload remotePayload);
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskFactory.java b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskFactory.java
new file mode 100644
index 0000000000..f823fcacdb
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskFactory.java
@@ -0,0 +1,8 @@
+package org.briarproject.api.keyagreement;
+
+/** Manages tasks for conducting key agreements with remote peers. */
+public interface KeyAgreementTaskFactory {
+
+	/** Gets the current key agreement task. */
+	KeyAgreementTask getTask();
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskId.java b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskId.java
new file mode 100644
index 0000000000..434f9cb71a
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/KeyAgreementTaskId.java
@@ -0,0 +1,18 @@
+package org.briarproject.api.keyagreement;
+
+import org.briarproject.api.UniqueId;
+
+/**
+ * Type-safe wrapper for a byte array that uniquely identifies a BQP task.
+ */
+public class KeyAgreementTaskId extends UniqueId {
+
+	public KeyAgreementTaskId(byte[] id) {
+		super(id);
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		return o instanceof KeyAgreementTaskId && super.equals(o);
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/Payload.java b/briar-api/src/org/briarproject/api/keyagreement/Payload.java
new file mode 100644
index 0000000000..0c749da53e
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/Payload.java
@@ -0,0 +1,34 @@
+package org.briarproject.api.keyagreement;
+
+import org.briarproject.api.Bytes;
+
+import java.util.List;
+
+/**
+ * A BQP payload.
+ */
+public class Payload implements Comparable<Payload> {
+
+	private final Bytes commitment;
+	private final List<TransportDescriptor> descriptors;
+
+	public Payload(byte[] commitment, List<TransportDescriptor> descriptors) {
+		this.commitment = new Bytes(commitment);
+		this.descriptors = descriptors;
+	}
+
+	/** Returns the commitment contained in this payload. */
+	public byte[] getCommitment() {
+		return commitment.getBytes();
+	}
+
+	/** Returns the transport descriptors contained in this payload. */
+	public List<TransportDescriptor> getTransportDescriptors() {
+		return descriptors;
+	}
+
+	@Override
+	public int compareTo(Payload p) {
+		return commitment.compareTo(p.commitment);
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/PayloadEncoder.java b/briar-api/src/org/briarproject/api/keyagreement/PayloadEncoder.java
new file mode 100644
index 0000000000..31876c1027
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/PayloadEncoder.java
@@ -0,0 +1,6 @@
+package org.briarproject.api.keyagreement;
+
+public interface PayloadEncoder {
+
+	byte[] encode(Payload p);
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/PayloadParser.java b/briar-api/src/org/briarproject/api/keyagreement/PayloadParser.java
new file mode 100644
index 0000000000..0df9c653d4
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/PayloadParser.java
@@ -0,0 +1,8 @@
+package org.briarproject.api.keyagreement;
+
+import java.io.IOException;
+
+public interface PayloadParser {
+
+	Payload parse(byte[] raw) throws IOException;
+}
diff --git a/briar-api/src/org/briarproject/api/keyagreement/RecordTypes.java b/briar-api/src/org/briarproject/api/keyagreement/RecordTypes.java
new file mode 100644
index 0000000000..ef1d2ff51f
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/keyagreement/RecordTypes.java
@@ -0,0 +1,9 @@
+package org.briarproject.api.keyagreement;
+
+/** Record types for BQP. */
+public interface RecordTypes {
+
+	byte KEY = 0;
+	byte CONFIRM = 1;
+	byte ABORT = 2;
+}
-- 
GitLab