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 0000000000000000000000000000000000000000..5e217f7f4d2752f09ae68d7e0ee9b9cbc68f9d46 --- /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 0000000000000000000000000000000000000000..97313a276b0bf19f582e4177b3680753ac09568f --- /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 0000000000000000000000000000000000000000..f2afe349ebb23c6a9c63d33d518660f7b84e036b --- /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 0000000000000000000000000000000000000000..df3b2cbac5fc6ced89e43a37cee90766a7a2e70b --- /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 0000000000000000000000000000000000000000..a12a9c459a38c3b1131bb605f1b9eb857a13d2f2 --- /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 0000000000000000000000000000000000000000..473c6538adb053d4aeb0551621ebf8a8b2c97aa2 --- /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 521789244d9a8e61ae5926ea24509ebde82fbf4f..f239111269124e8d938f15bbc5561a4670ed5d0a 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 0000000000000000000000000000000000000000..3f772ca28792d58571a82b5da7b6b65a1ab27624 --- /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 0000000000000000000000000000000000000000..443ef42bd68d11f7bae75cf576d8e2721bc0a63f --- /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 0000000000000000000000000000000000000000..f823fcacdbfe44898399ad5851f62a86c542e06e --- /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 0000000000000000000000000000000000000000..434f9cb71ac2ea2bd746fd6dd225d294b1f854bb --- /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 0000000000000000000000000000000000000000..0c749da53ec9e2a70c652cc3dcdf70f5a9d079a6 --- /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 0000000000000000000000000000000000000000..31876c10271146fe99de491bd6d3f1053ad769da --- /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 0000000000000000000000000000000000000000..0df9c653d418d464af843f74547981bc06f7a223 --- /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 0000000000000000000000000000000000000000..ef1d2ff51feb21d04b9e995474e091aede397379 --- /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; +}