mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 04:18:53 +01:00
Changed the root package from net.sf.briar to org.briarproject.
This commit is contained in:
40
briar-api/src/org/briarproject/api/Author.java
Normal file
40
briar-api/src/org/briarproject/api/Author.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
/** A pseudonym for a user. */
|
||||
public class Author {
|
||||
|
||||
private final AuthorId id;
|
||||
private final String name;
|
||||
private final byte[] publicKey;
|
||||
|
||||
public Author(AuthorId id, String name, byte[] publicKey) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
/** Returns the author's unique identifier. */
|
||||
public AuthorId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Returns the author's name. */
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Returns the public key used to verify the pseudonym's signatures. */
|
||||
public byte[] getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof Author && id.equals(((Author) o).id);
|
||||
}
|
||||
}
|
||||
31
briar-api/src/org/briarproject/api/AuthorConstants.java
Normal file
31
briar-api/src/org/briarproject/api/AuthorConstants.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
public interface AuthorConstants {
|
||||
|
||||
/** The maximum length of an author's name in UTF-8 bytes. */
|
||||
int MAX_AUTHOR_NAME_LENGTH = 50;
|
||||
|
||||
/**
|
||||
* The maximum length of a public key in bytes.
|
||||
* <p>
|
||||
* Public keys use SEC1 format: 0x04 x y, where x and y are unsigned
|
||||
* big-endian integers.
|
||||
* <p>
|
||||
* For a 384-bit elliptic curve, the maximum length is 2 * (384/8) + 1.
|
||||
*/
|
||||
int MAX_PUBLIC_KEY_LENGTH = 97;
|
||||
|
||||
/**
|
||||
* The maximum length of a signature in bytes.
|
||||
* <p>
|
||||
* A signature is an ASN.1 DER sequence containing two integers, r and s.
|
||||
* The format is 0x30 len1 0x02 len2 r 0x02 len3 s, where len1 is
|
||||
* len(0x02 len2 r 0x02 len3 s) as a DER length, len2 is len(r) as a DER
|
||||
* length, len3 is len(s) as a DER length, and r and s are signed
|
||||
* big-endian integers of minimal length.
|
||||
* <p>
|
||||
* For a 384-bit elliptic curve, the lengths are one byte each, so the
|
||||
* maximum length is 2 * (384/8) + 8.
|
||||
*/
|
||||
int MAX_SIGNATURE_LENGTH = 104;
|
||||
}
|
||||
9
briar-api/src/org/briarproject/api/AuthorFactory.java
Normal file
9
briar-api/src/org/briarproject/api/AuthorFactory.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
public interface AuthorFactory {
|
||||
|
||||
Author createAuthor(String name, byte[] publicKey);
|
||||
|
||||
LocalAuthor createLocalAuthor(String name, byte[] publicKey,
|
||||
byte[] privateKey);
|
||||
}
|
||||
21
briar-api/src/org/briarproject/api/AuthorId.java
Normal file
21
briar-api/src/org/briarproject/api/AuthorId.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a byte array that uniquely identifies an
|
||||
* {@link Author}.
|
||||
*/
|
||||
public class AuthorId extends UniqueId {
|
||||
|
||||
public AuthorId(byte[] id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof AuthorId)
|
||||
return Arrays.equals(id, ((AuthorId) o).id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
34
briar-api/src/org/briarproject/api/Bytes.java
Normal file
34
briar-api/src/org/briarproject/api/Bytes.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** A wrapper around a byte array, to allow it to be stored in maps etc. */
|
||||
public class Bytes {
|
||||
|
||||
private final byte[] bytes;
|
||||
|
||||
private int hashCode = -1;
|
||||
|
||||
public Bytes(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// Thread-safe because if two or more threads check and update the
|
||||
// value, they'll calculate the same value
|
||||
if(hashCode == -1) hashCode = Arrays.hashCode(bytes);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof Bytes)
|
||||
return Arrays.equals(bytes, ((Bytes) o).bytes);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
37
briar-api/src/org/briarproject/api/Contact.java
Normal file
37
briar-api/src/org/briarproject/api/Contact.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
public class Contact {
|
||||
|
||||
private final ContactId id;
|
||||
private final Author author;
|
||||
private final AuthorId localAuthorId;
|
||||
|
||||
public Contact(ContactId id, Author author, AuthorId localAuthorId) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.localAuthorId = localAuthorId;
|
||||
}
|
||||
|
||||
public ContactId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public AuthorId getLocalAuthorId() {
|
||||
return localAuthorId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof Contact) return id.equals(((Contact) o).id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
29
briar-api/src/org/briarproject/api/ContactId.java
Normal file
29
briar-api/src/org/briarproject/api/ContactId.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for an integer that uniquely identifies a contact within
|
||||
* the scope of a single node.
|
||||
*/
|
||||
public class ContactId {
|
||||
|
||||
private final int id;
|
||||
|
||||
public ContactId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof ContactId) return id == ((ContactId) o).id;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
9
briar-api/src/org/briarproject/api/FormatException.java
Normal file
9
briar-api/src/org/briarproject/api/FormatException.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/** An exception that indicates an unrecoverable formatting error. */
|
||||
public class FormatException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = 2274966775687766337L;
|
||||
}
|
||||
18
briar-api/src/org/briarproject/api/LocalAuthor.java
Normal file
18
briar-api/src/org/briarproject/api/LocalAuthor.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
/** A pseudonym for the local user. */
|
||||
public class LocalAuthor extends Author {
|
||||
|
||||
private final byte[] privateKey;
|
||||
|
||||
public LocalAuthor(AuthorId id, String name, byte[] publicKey,
|
||||
byte[] privateKey) {
|
||||
super(id, name, publicKey);
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
/** Returns the private key used to generate the pseudonym's signatures. */
|
||||
public byte[] getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
15
briar-api/src/org/briarproject/api/TransportConfig.java
Normal file
15
briar-api/src/org/briarproject/api/TransportConfig.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
public class TransportConfig extends Hashtable<String, String> {
|
||||
|
||||
private static final long serialVersionUID = 2330384620787778596L;
|
||||
|
||||
public TransportConfig(Map<String, String> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public TransportConfig() {}
|
||||
}
|
||||
21
briar-api/src/org/briarproject/api/TransportId.java
Normal file
21
briar-api/src/org/briarproject/api/TransportId.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a byte array that uniquely identifies a transport
|
||||
* plugin.
|
||||
*/
|
||||
public class TransportId extends UniqueId {
|
||||
|
||||
public TransportId(byte[] id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof TransportId)
|
||||
return Arrays.equals(id, ((TransportId) o).id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
15
briar-api/src/org/briarproject/api/TransportProperties.java
Normal file
15
briar-api/src/org/briarproject/api/TransportProperties.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
public class TransportProperties extends Hashtable<String, String> {
|
||||
|
||||
private static final long serialVersionUID = 7533739534204953625L;
|
||||
|
||||
public TransportProperties(Map<String, String> p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
public TransportProperties() {}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
public interface TransportPropertyConstants {
|
||||
|
||||
/** The maximum number of properties per transport. */
|
||||
int MAX_PROPERTIES_PER_TRANSPORT = 100;
|
||||
|
||||
/** The maximum length of a property's key or value in UTF-8 bytes. */
|
||||
int MAX_PROPERTY_LENGTH = 100;
|
||||
}
|
||||
30
briar-api/src/org/briarproject/api/UniqueId.java
Normal file
30
briar-api/src/org/briarproject/api/UniqueId.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class UniqueId {
|
||||
|
||||
/** The length of a unique identifier in bytes. */
|
||||
public static final int LENGTH = 48;
|
||||
|
||||
protected final byte[] id;
|
||||
|
||||
private int hashCode = -1;
|
||||
|
||||
protected UniqueId(byte[] id) {
|
||||
if(id.length != LENGTH) throw new IllegalArgumentException();
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// Thread-safe because if two or more threads check and update the
|
||||
// value, they'll calculate the same value
|
||||
if(hashCode == -1) hashCode = Arrays.hashCode(id);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.briarproject.api.android;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* Enables background threads to make Android API calls that must be made from
|
||||
* a thread with a message queue.
|
||||
*/
|
||||
public interface AndroidExecutor {
|
||||
|
||||
/**
|
||||
* Runs the given task on a thread with a message queue and returns the
|
||||
* result of the task.
|
||||
*/
|
||||
<V> V call(Callable<V> c) throws InterruptedException, ExecutionException;
|
||||
|
||||
void shutdown();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.briarproject.api.android;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
/**
|
||||
* Annotation for injecting the executor for accessing the database from the UI.
|
||||
*/
|
||||
@BindingAnnotation
|
||||
@Target({ FIELD, METHOD, PARAMETER })
|
||||
@Retention(RUNTIME)
|
||||
public @interface DatabaseUiExecutor {}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.briarproject.api.android;
|
||||
|
||||
/**
|
||||
* Manages mappings between object references and serialisable handles. This
|
||||
* enables references to be passed between Android UI objects that belong to
|
||||
* the same process but can only communicate via serialisation.
|
||||
*/
|
||||
public interface ReferenceManager {
|
||||
|
||||
/**
|
||||
* Returns the object with the given handle, or null if no mapping exists
|
||||
* for the handle.
|
||||
*/
|
||||
<T> T getReference(long handle, Class<T> c);
|
||||
|
||||
/**
|
||||
* Creates a mapping between the given reference and a handle, and returns
|
||||
* the handle.
|
||||
*/
|
||||
<T> long putReference(T reference, Class<T> c);
|
||||
|
||||
/**
|
||||
* Removes and returns the object with the given handle, or returns null
|
||||
* if no mapping exists for the handle.
|
||||
*/
|
||||
<T> T removeReference(long handle, Class<T> c);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/** An authenticated cipher that support additional authenticated data. */
|
||||
public interface AuthenticatedCipher {
|
||||
|
||||
/**
|
||||
* Initializes this cipher with a key, an initialisation vector (IV) and
|
||||
* additional authenticated data (AAD).
|
||||
*/
|
||||
void init(int opmode, SecretKey key, byte[] iv, byte[] aad)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/** Encrypts or decrypts data in a single-part operation. */
|
||||
int doFinal(byte[] input, int inputOff, int len, byte[] output,
|
||||
int outputOff) throws GeneralSecurityException;
|
||||
|
||||
/** Returns the length of the message authenticated code (MAC) in bytes. */
|
||||
int getMacLength();
|
||||
|
||||
/** Returns the block size of the cipher in bytes. */
|
||||
int getBlockSize();
|
||||
}
|
||||
105
briar-api/src/org/briarproject/api/crypto/CryptoComponent.java
Normal file
105
briar-api/src/org/briarproject/api/crypto/CryptoComponent.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public interface CryptoComponent {
|
||||
|
||||
SecretKey generateSecretKey();
|
||||
|
||||
MessageDigest getMessageDigest();
|
||||
|
||||
PseudoRandom getPseudoRandom(int seed1, int seed2);
|
||||
|
||||
SecureRandom getSecureRandom();
|
||||
|
||||
Signature getSignature();
|
||||
|
||||
KeyPair generateAgreementKeyPair();
|
||||
|
||||
KeyParser getAgreementKeyParser();
|
||||
|
||||
KeyPair generateSignatureKeyPair();
|
||||
|
||||
KeyParser getSignatureKeyParser();
|
||||
|
||||
/** Generates a random invitation code. */
|
||||
int generateInvitationCode();
|
||||
|
||||
/**
|
||||
* Derives two confirmation codes from the given master secret. The first
|
||||
* code is for Alice to give to Bob; the second is for Bob to give to
|
||||
* Alice.
|
||||
*/
|
||||
int[] deriveConfirmationCodes(byte[] secret);
|
||||
|
||||
/**
|
||||
* Derives two nonces from the given master secret. The first nonce is for
|
||||
* Alice to sign; the second is for Bob to sign.
|
||||
*/
|
||||
byte[][] deriveInvitationNonces(byte[] secret);
|
||||
|
||||
/**
|
||||
* Derives a shared master secret from two public keys and one of the
|
||||
* corresponding private keys.
|
||||
* @param alice indicates whether the private key belongs to Alice or Bob.
|
||||
*/
|
||||
byte[] deriveMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
|
||||
boolean alice) throws GeneralSecurityException;
|
||||
|
||||
/** Derives a group salt from the given master secret. */
|
||||
byte[] deriveGroupSalt(byte[] secret);
|
||||
|
||||
/**
|
||||
* Derives an initial secret for the given transport from the given master
|
||||
* secret.
|
||||
*/
|
||||
byte[] deriveInitialSecret(byte[] secret, int transportIndex);
|
||||
|
||||
/**
|
||||
* Derives a temporary secret for the given period from the given secret,
|
||||
* which is either the initial shared secret or the previous period's
|
||||
* temporary secret.
|
||||
*/
|
||||
byte[] deriveNextSecret(byte[] secret, long period);
|
||||
|
||||
/**
|
||||
* Derives a tag key from the given temporary secret.
|
||||
* @param alice indicates whether the key is for connections initiated by
|
||||
* Alice or Bob.
|
||||
*/
|
||||
SecretKey deriveTagKey(byte[] secret, boolean alice);
|
||||
|
||||
/**
|
||||
* Derives a frame key from the given temporary secret and connection
|
||||
* number.
|
||||
* @param alice indicates whether the key is for a connection initiated by
|
||||
* Alice or Bob.
|
||||
* @param initiator indicates whether the key is for the initiator's or the
|
||||
* responder's side of the connection.
|
||||
*/
|
||||
SecretKey deriveFrameKey(byte[] secret, long connection, boolean alice,
|
||||
boolean initiator);
|
||||
|
||||
/** Returns a cipher for encrypting and authenticating connections. */
|
||||
AuthenticatedCipher getFrameCipher();
|
||||
|
||||
/** Encodes the pseudo-random tag that is used to recognise a connection. */
|
||||
void encodeTag(byte[] tag, SecretKey tagKey, long connection);
|
||||
|
||||
/**
|
||||
* Encrypts and authenticates the given plaintext so it can be written to
|
||||
* storage. The encryption and authentication keys are derived from the
|
||||
* given password. The ciphertext will be decryptable using the same
|
||||
* password after the app restarts.
|
||||
*/
|
||||
byte[] encryptWithPassword(byte[] plaintext, char[] password);
|
||||
|
||||
/**
|
||||
* Decrypts and authenticates the given ciphertext that has been read from
|
||||
* storage. The encryption and authentication keys are derived from the
|
||||
* given password. Returns null if the ciphertext cannot be decrypted and
|
||||
* authenticated (for example, if the password is wrong).
|
||||
*/
|
||||
byte[] decryptWithPassword(byte[] ciphertext, char[] password);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
/** Annotation for injecting the executor for long-running crypto tasks. */
|
||||
@BindingAnnotation
|
||||
@Target({ FIELD, METHOD, PARAMETER })
|
||||
@Retention(RUNTIME)
|
||||
public @interface CryptoExecutor {}
|
||||
23
briar-api/src/org/briarproject/api/crypto/KeyManager.java
Normal file
23
briar-api/src/org/briarproject/api/crypto/KeyManager.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
import org.briarproject.api.transport.ConnectionContext;
|
||||
import org.briarproject.api.transport.Endpoint;
|
||||
|
||||
public interface KeyManager extends Service {
|
||||
|
||||
/**
|
||||
* Returns a connection context for connecting to the given contact over
|
||||
* the given transport, or null if an error occurs or the contact does not
|
||||
* support the transport.
|
||||
*/
|
||||
ConnectionContext getConnectionContext(ContactId c, TransportId t);
|
||||
|
||||
/**
|
||||
* Called whenever an endpoint has been added. The initial secret
|
||||
* is erased before returning.
|
||||
*/
|
||||
void endpointAdded(Endpoint ep, long maxLatency, byte[] initialSecret);
|
||||
}
|
||||
21
briar-api/src/org/briarproject/api/crypto/KeyPair.java
Normal file
21
briar-api/src/org/briarproject/api/crypto/KeyPair.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
/** A key pair consisting of a {@link PublicKey} and a {@link PrivateKey). */
|
||||
public class KeyPair {
|
||||
|
||||
private final PublicKey publicKey;
|
||||
private final PrivateKey privateKey;
|
||||
|
||||
public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
|
||||
this.publicKey = publicKey;
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public PublicKey getPublic() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public PrivateKey getPrivate() {
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
11
briar-api/src/org/briarproject/api/crypto/KeyParser.java
Normal file
11
briar-api/src/org/briarproject/api/crypto/KeyParser.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
public interface KeyParser {
|
||||
|
||||
PublicKey parsePublicKey(byte[] encodedKey) throws GeneralSecurityException;
|
||||
|
||||
PrivateKey parsePrivateKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException;
|
||||
}
|
||||
28
briar-api/src/org/briarproject/api/crypto/MessageDigest.java
Normal file
28
briar-api/src/org/briarproject/api/crypto/MessageDigest.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
public interface MessageDigest {
|
||||
|
||||
/** @see {@link java.security.MessageDigest#digest()} */
|
||||
byte[] digest();
|
||||
|
||||
/** @see {@link java.security.MessageDigest#digest(byte[])} */
|
||||
byte[] digest(byte[] input);
|
||||
|
||||
/** @see {@link java.security.MessageDigest#digest(byte[], int, int)} */
|
||||
int digest(byte[] buf, int offset, int len);
|
||||
|
||||
/** @see {@link java.security.MessageDigest#getDigestLength()} */
|
||||
int getDigestLength();
|
||||
|
||||
/** @see {@link java.security.MessageDigest#reset()} */
|
||||
void reset();
|
||||
|
||||
/** @see {@link java.security.MessageDigest#update(byte)} */
|
||||
void update(byte input);
|
||||
|
||||
/** @see {@link java.security.MessageDigest#update(byte[])} */
|
||||
void update(byte[] input);
|
||||
|
||||
/** @see {@link java.security.MessageDigest#update(byte[], int, int)} */
|
||||
void update(byte[] input, int offset, int len);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
/** The private half of a public/private {@link KeyPair}. */
|
||||
public interface PrivateKey {
|
||||
|
||||
/** Returns the encoded representation of this key. */
|
||||
byte[] getEncoded();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
/** A deterministic PRNG. */
|
||||
public interface PseudoRandom {
|
||||
|
||||
byte[] nextBytes(int bytes);
|
||||
}
|
||||
8
briar-api/src/org/briarproject/api/crypto/PublicKey.java
Normal file
8
briar-api/src/org/briarproject/api/crypto/PublicKey.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
/** The public half of a public/private {@link KeyPair}. */
|
||||
public interface PublicKey {
|
||||
|
||||
/** Returns the encoded representation of this key. */
|
||||
byte[] getEncoded();
|
||||
}
|
||||
21
briar-api/src/org/briarproject/api/crypto/SecretKey.java
Normal file
21
briar-api/src/org/briarproject/api/crypto/SecretKey.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
/** A secret key used for encryption and/or authentication. */
|
||||
public interface SecretKey {
|
||||
|
||||
/** Returns the encoded representation of this key. */
|
||||
byte[] getEncoded();
|
||||
|
||||
/**
|
||||
* Returns a copy of this key - erasing this key will erase the copy and
|
||||
* vice versa.
|
||||
*/
|
||||
SecretKey copy();
|
||||
|
||||
/**
|
||||
* Erases this key from memory. Any copies derived from this key via the
|
||||
* {@link #copy()} method, and any keys from which this key was derived via
|
||||
* the {@link #copy()} method, are also erased.
|
||||
*/
|
||||
void erase();
|
||||
}
|
||||
31
briar-api/src/org/briarproject/api/crypto/Signature.java
Normal file
31
briar-api/src/org/briarproject/api/crypto/Signature.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package org.briarproject.api.crypto;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
public interface Signature {
|
||||
|
||||
/**
|
||||
* @see {@link java.security.Signature#initSign(java.security.PrivateKey)}
|
||||
*/
|
||||
void initSign(PrivateKey k) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* @see {@link java.security.Signature#initVafiry(java.security.PublicKey)}
|
||||
*/
|
||||
void initVerify(PublicKey k) throws GeneralSecurityException;
|
||||
|
||||
/** @see {@link java.security.Signature#update(byte)} */
|
||||
void update(byte b);
|
||||
|
||||
/** @see {@link java.security.Signature#update(byte[])} */
|
||||
void update(byte[] b);
|
||||
|
||||
/** @see {@link java.security.Signature#update(byte[], int, int)} */
|
||||
void update(byte[] b, int off, int len);
|
||||
|
||||
/** @see {@link java.security.Signature#sign()} */
|
||||
byte[] sign();
|
||||
|
||||
/** @see {@link java.security.Signature#verify(byte[])} */
|
||||
boolean verify(byte[] signature);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a duplicate contact is added to the database. This exception may
|
||||
* occur due to concurrent updates and does not indicate a database error.
|
||||
*/
|
||||
public class ContactExistsException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = -6658762011691502411L;
|
||||
}
|
||||
357
briar-api/src/org/briarproject/api/db/DatabaseComponent.java
Normal file
357
briar-api/src/org/briarproject/api/db/DatabaseComponent.java
Normal file
@@ -0,0 +1,357 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.briarproject.api.Author;
|
||||
import org.briarproject.api.AuthorId;
|
||||
import org.briarproject.api.Contact;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.LocalAuthor;
|
||||
import org.briarproject.api.TransportConfig;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.TransportProperties;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.messaging.Ack;
|
||||
import org.briarproject.api.messaging.Group;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.GroupStatus;
|
||||
import org.briarproject.api.messaging.Message;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
import org.briarproject.api.messaging.Offer;
|
||||
import org.briarproject.api.messaging.Request;
|
||||
import org.briarproject.api.messaging.RetentionAck;
|
||||
import org.briarproject.api.messaging.RetentionUpdate;
|
||||
import org.briarproject.api.messaging.SubscriptionAck;
|
||||
import org.briarproject.api.messaging.SubscriptionUpdate;
|
||||
import org.briarproject.api.messaging.TransportAck;
|
||||
import org.briarproject.api.messaging.TransportUpdate;
|
||||
import org.briarproject.api.transport.Endpoint;
|
||||
import org.briarproject.api.transport.TemporarySecret;
|
||||
|
||||
/**
|
||||
* Encapsulates the database implementation and exposes high-level operations
|
||||
* to other components.
|
||||
*/
|
||||
public interface DatabaseComponent {
|
||||
|
||||
/** Opens the database and returns true if the database already existed. */
|
||||
boolean open() throws DbException, IOException;
|
||||
|
||||
/** Waits for any open transactions to finish and closes the database. */
|
||||
void close() throws DbException, IOException;
|
||||
|
||||
/** Adds a listener to be notified when database events occur. */
|
||||
void addListener(EventListener d);
|
||||
|
||||
/** Removes a listener. */
|
||||
void removeListener(EventListener d);
|
||||
|
||||
/**
|
||||
* Stores a contact associated with the given local and remote pseudonyms,
|
||||
* and returns an ID for the contact.
|
||||
*/
|
||||
ContactId addContact(Author remote, AuthorId local) throws DbException;
|
||||
|
||||
/** Stores an endpoint. */
|
||||
void addEndpoint(Endpoint ep) throws DbException;
|
||||
|
||||
/**
|
||||
* Subscribes to a group, or returns false if the user already has the
|
||||
* maximum number of public subscriptions.
|
||||
*/
|
||||
boolean addGroup(Group g) throws DbException;
|
||||
|
||||
/** Stores a local pseudonym. */
|
||||
void addLocalAuthor(LocalAuthor a) throws DbException;
|
||||
|
||||
/** Stores a local message. */
|
||||
void addLocalMessage(Message m) throws DbException;
|
||||
|
||||
/**
|
||||
* Stores the given temporary secrets and deletes any secrets that have
|
||||
* been made obsolete.
|
||||
*/
|
||||
void addSecrets(Collection<TemporarySecret> secrets) throws DbException;
|
||||
|
||||
/**
|
||||
* Stores a transport and returns true if the transport was not previously
|
||||
* in the database.
|
||||
*/
|
||||
boolean addTransport(TransportId t, long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns an acknowledgement for the given contact, or null if there are
|
||||
* no messages to acknowledge.
|
||||
*/
|
||||
Ack generateAck(ContactId c, int maxMessages) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a batch of raw messages for the given contact, with a total
|
||||
* length less than or equal to the given length, for transmission over a
|
||||
* transport with the given maximum latency. Returns null if there are no
|
||||
* sendable messages that fit in the given length.
|
||||
*/
|
||||
Collection<byte[]> generateBatch(ContactId c, int maxLength,
|
||||
long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns an offer for the given contact for transmission over a
|
||||
* transport with the given maximum latency, or null if there are no
|
||||
* messages to offer.
|
||||
*/
|
||||
Offer generateOffer(ContactId c, int maxMessages, long maxLatency)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a request for the given contact, or null if there are no
|
||||
* messages to request.
|
||||
*/
|
||||
Request generateRequest(ContactId c, int maxMessages) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a batch of raw messages for the given contact, with a total
|
||||
* length less than or equal to the given length, for transmission over a
|
||||
* transport with the given maximum latency. Only messages that have been
|
||||
* requested by the contact are returned. Returns null if there are no
|
||||
* sendable messages that fit in the given length.
|
||||
*/
|
||||
Collection<byte[]> generateRequestedBatch(ContactId c, int maxLength,
|
||||
long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a retention ack for the given contact, or null if no retention
|
||||
* ack is due.
|
||||
*/
|
||||
RetentionAck generateRetentionAck(ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a retention update for the given contact, for transmission
|
||||
* over a transport with the given latency. Returns null if no update is
|
||||
* due.
|
||||
*/
|
||||
RetentionUpdate generateRetentionUpdate(ContactId c, long maxLatency)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a subscription ack for the given contact, or null if no
|
||||
* subscription ack is due.
|
||||
*/
|
||||
SubscriptionAck generateSubscriptionAck(ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a subscription update for the given contact, for transmission
|
||||
* over a transport with the given latency. Returns null if no update is
|
||||
* due.
|
||||
*/
|
||||
SubscriptionUpdate generateSubscriptionUpdate(ContactId c, long maxLatency)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a batch of transport acks for the given contact, or null if no
|
||||
* transport acks are due.
|
||||
*/
|
||||
Collection<TransportAck> generateTransportAcks(ContactId c)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a batch of transport updates for the given contact, for
|
||||
* transmission over a transport with the given latency. Returns null if no
|
||||
* updates are due.
|
||||
*/
|
||||
Collection<TransportUpdate> generateTransportUpdates(ContactId c,
|
||||
long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the status of all groups to which the user subscribes or can
|
||||
* subscribe, excluding inbox groups.
|
||||
*/
|
||||
Collection<GroupStatus> getAvailableGroups() throws DbException;
|
||||
|
||||
/** Returns the configuration for the given transport. */
|
||||
TransportConfig getConfig(TransportId t) throws DbException;
|
||||
|
||||
/** Returns the contact with the given ID. */
|
||||
Contact getContact(ContactId c) throws DbException;
|
||||
|
||||
/** Returns all contacts. */
|
||||
Collection<Contact> getContacts() throws DbException;
|
||||
|
||||
/** Returns the group with the given ID, if the user subscribes to it. */
|
||||
Group getGroup(GroupId g) throws DbException;
|
||||
|
||||
/** Returns all groups to which the user subscribes. */
|
||||
Collection<Group> getGroups() throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the ID of the inbox group for the given contact, or null if no
|
||||
* inbox group has been set.
|
||||
*/
|
||||
GroupId getInboxGroupId(ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the headers of all messages in the inbox group for the given
|
||||
* contact, or null if no inbox group has been set.
|
||||
*/
|
||||
Collection<MessageHeader> getInboxMessageHeaders(ContactId c)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the time at which a connection to each contact was last opened
|
||||
* or closed.
|
||||
*/
|
||||
Map<ContactId, Long> getLastConnected() throws DbException;
|
||||
|
||||
/** Returns the local pseudonym with the given ID. */
|
||||
LocalAuthor getLocalAuthor(AuthorId a) throws DbException;
|
||||
|
||||
/** Returns all local pseudonyms. */
|
||||
Collection<LocalAuthor> getLocalAuthors() throws DbException;
|
||||
|
||||
/** Returns the local transport properties for all transports. */
|
||||
Map<TransportId, TransportProperties> getLocalProperties()
|
||||
throws DbException;
|
||||
|
||||
/** Returns the local transport properties for the given transport. */
|
||||
TransportProperties getLocalProperties(TransportId t) throws DbException;
|
||||
|
||||
/** Returns the body of the message with the given ID. */
|
||||
byte[] getMessageBody(MessageId m) throws DbException;
|
||||
|
||||
/** Returns the headers of all messages in the given group. */
|
||||
Collection<MessageHeader> getMessageHeaders(GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/** Returns true if the given message is marked as read. */
|
||||
boolean getReadFlag(MessageId m) throws DbException;
|
||||
|
||||
/** Returns all remote transport properties for the given transport. */
|
||||
Map<ContactId, TransportProperties> getRemoteProperties(TransportId t)
|
||||
throws DbException;
|
||||
|
||||
/** Returns all temporary secrets. */
|
||||
Collection<TemporarySecret> getSecrets() throws DbException;
|
||||
|
||||
/** Returns the maximum latencies of all local transports. */
|
||||
Map<TransportId, Long> getTransportLatencies() throws DbException;
|
||||
|
||||
/** Returns the number of unread messages in each subscribed group. */
|
||||
Map<GroupId, Integer> getUnreadMessageCounts() throws DbException;
|
||||
|
||||
/** Returns the IDs of all contacts to which the given group is visible. */
|
||||
Collection<ContactId> getVisibility(GroupId g) throws DbException;
|
||||
|
||||
/**
|
||||
* Increments the outgoing connection counter for the given endpoint
|
||||
* in the given rotation period and returns the old value, or -1 if the
|
||||
* counter does not exist.
|
||||
*/
|
||||
long incrementConnectionCounter(ContactId c, TransportId t, long period)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Merges the given configuration with existing configuration for the
|
||||
* given transport.
|
||||
*/
|
||||
void mergeConfig(TransportId t, TransportConfig c) throws DbException;
|
||||
|
||||
/**
|
||||
* Merges the given properties with the existing local properties for the
|
||||
* given transport.
|
||||
*/
|
||||
void mergeLocalProperties(TransportId t, TransportProperties p)
|
||||
throws DbException;
|
||||
|
||||
/** Processes an ack from the given contact. */
|
||||
void receiveAck(ContactId c, Ack a) throws DbException;
|
||||
|
||||
/** Processes a message from the given contact. */
|
||||
void receiveMessage(ContactId c, Message m) throws DbException;
|
||||
|
||||
/** Processes an offer from the given contact. */
|
||||
void receiveOffer(ContactId c, Offer o) throws DbException;
|
||||
|
||||
/** Processes a request from the given contact. */
|
||||
void receiveRequest(ContactId c, Request r) throws DbException;
|
||||
|
||||
/** Processes a retention ack from the given contact. */
|
||||
void receiveRetentionAck(ContactId c, RetentionAck a) throws DbException;
|
||||
|
||||
/** Processes a retention update from the given contact. */
|
||||
void receiveRetentionUpdate(ContactId c, RetentionUpdate u)
|
||||
throws DbException;
|
||||
|
||||
/** Processes a subscription ack from the given contact. */
|
||||
void receiveSubscriptionAck(ContactId c, SubscriptionAck a)
|
||||
throws DbException;
|
||||
|
||||
/** Processes a subscription update from the given contact. */
|
||||
void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate u)
|
||||
throws DbException;
|
||||
|
||||
/** Processes a transport ack from the given contact. */
|
||||
void receiveTransportAck(ContactId c, TransportAck a) throws DbException;
|
||||
|
||||
/** Processes a transport update from the given contact. */
|
||||
void receiveTransportUpdate(ContactId c, TransportUpdate u)
|
||||
throws DbException;
|
||||
|
||||
/** Removes a contact (and all associated state) from the database. */
|
||||
void removeContact(ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Unsubscribes from a group. Any messages belonging to the group
|
||||
* are deleted from the database.
|
||||
*/
|
||||
void removeGroup(Group g) throws DbException;
|
||||
|
||||
/**
|
||||
* Removes a local pseudonym (and all associated state) from the database.
|
||||
*/
|
||||
void removeLocalAuthor(AuthorId a) throws DbException;
|
||||
|
||||
/**
|
||||
* Removes a transport (and any associated configuration and local
|
||||
* properties) from the database.
|
||||
*/
|
||||
void removeTransport(TransportId t) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the connection reordering window for the given endpoint in the
|
||||
* given rotation period.
|
||||
*/
|
||||
void setConnectionWindow(ContactId c, TransportId t, long period,
|
||||
long centre, byte[] bitmap) throws DbException;
|
||||
|
||||
/**
|
||||
* Makes a group visible to the given contact, adds it to the contact's
|
||||
* subscriptions, and sets it as the inbox group for the contact.
|
||||
*/
|
||||
public void setInboxGroup(ContactId c, Group g) throws DbException;
|
||||
|
||||
/**
|
||||
* Marks a message as read or unread.
|
||||
*/
|
||||
void setReadFlag(MessageId m, boolean read) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the remote transport properties for the given contact, replacing
|
||||
* any existing properties.
|
||||
*/
|
||||
void setRemoteProperties(ContactId c,
|
||||
Map<TransportId, TransportProperties> p) throws DbException;
|
||||
|
||||
/**
|
||||
* Makes a group visible to the given set of contacts and invisible to any
|
||||
* other current or future contacts.
|
||||
*/
|
||||
void setVisibility(GroupId g, Collection<ContactId> visible)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Makes a group visible to all current and future contacts, or invisible
|
||||
* to future contacts.
|
||||
*/
|
||||
void setVisibleToAll(GroupId g, boolean all) throws DbException;
|
||||
}
|
||||
16
briar-api/src/org/briarproject/api/db/DatabaseConfig.java
Normal file
16
briar-api/src/org/briarproject/api/db/DatabaseConfig.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface DatabaseConfig {
|
||||
|
||||
boolean databaseExists();
|
||||
|
||||
File getDatabaseDirectory();
|
||||
|
||||
void setEncryptionKey(byte[] key);
|
||||
|
||||
byte[] getEncryptionKey();
|
||||
|
||||
long getMaxSize();
|
||||
}
|
||||
17
briar-api/src/org/briarproject/api/db/DatabaseExecutor.java
Normal file
17
briar-api/src/org/briarproject/api/db/DatabaseExecutor.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
/** Annotation for injecting the executor for database tasks. */
|
||||
@BindingAnnotation
|
||||
@Target({ FIELD, METHOD, PARAMETER })
|
||||
@Retention(RUNTIME)
|
||||
public @interface DatabaseExecutor {}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/** Thrown when a database operation is attempted and the database is closed. */
|
||||
public class DbClosedException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = -3679248177625310653L;
|
||||
}
|
||||
12
briar-api/src/org/briarproject/api/db/DbException.java
Normal file
12
briar-api/src/org/briarproject/api/db/DbException.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
public class DbException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 3706581789209939441L;
|
||||
|
||||
public DbException() {}
|
||||
|
||||
public DbException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a duplicate pseudonym is added to the database. This exception
|
||||
* may occur due to concurrent updates and does not indicate a database error.
|
||||
*/
|
||||
public class LocalAuthorExistsException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = -1483877298070151673L;
|
||||
}
|
||||
68
briar-api/src/org/briarproject/api/db/MessageHeader.java
Normal file
68
briar-api/src/org/briarproject/api/db/MessageHeader.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
import org.briarproject.api.Author;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
|
||||
public class MessageHeader {
|
||||
|
||||
private final MessageId id, parent;
|
||||
private final GroupId groupId;
|
||||
private final Author author;
|
||||
private final String contentType;
|
||||
private final long timestamp;
|
||||
private final boolean read;
|
||||
|
||||
public MessageHeader(MessageId id, MessageId parent, GroupId groupId,
|
||||
Author author, String contentType, long timestamp, boolean read) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
this.groupId = groupId;
|
||||
this.author = author;
|
||||
this.contentType = contentType;
|
||||
this.timestamp = timestamp;
|
||||
this.read = read;
|
||||
}
|
||||
|
||||
/** Returns the message's unique identifier. */
|
||||
public MessageId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message's parent, or null if this is the first message in a
|
||||
* thread.
|
||||
*/
|
||||
public MessageId getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique identifier of the group to which the message belongs.
|
||||
*/
|
||||
public GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message's author, or null if this is an anonymous message.
|
||||
*/
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/** Returns the message's content type. */
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/** Returns the timestamp created by the message's author. */
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/** Returns true if the message has been read. */
|
||||
public boolean isRead() {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a database operation is attempted for a contact that is not in
|
||||
* the database. This exception may occur due to concurrent updates and does
|
||||
* not indicate a database error.
|
||||
*/
|
||||
public class NoSuchContactException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = -7048538231308207386L;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a database operation is attempted for a pseudonym that is not in
|
||||
* the database. This exception may occur due to concurrent updates and does
|
||||
* not indicate a database error.
|
||||
*/
|
||||
public class NoSuchLocalAuthorException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = 494398665376703860L;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a database operation is attempted for a message that is not in
|
||||
* the database. This exception may occur due to concurrent updates and does
|
||||
* not indicate a database error.
|
||||
*/
|
||||
public class NoSuchMessageException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = 9191508339698803848L;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a database operation is attempted for a group to which the user
|
||||
* does not subscribe. This exception may occur due to concurrent updates and
|
||||
* does not indicate a database error.
|
||||
*/
|
||||
public class NoSuchSubscriptionException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = -5494178507342571697L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.briarproject.api.db;
|
||||
|
||||
/**
|
||||
* Thrown when a database operation is attempted for a transport that is not in
|
||||
* the database. This exception may occur due to concurrent updates and does
|
||||
* not indicate a database error.
|
||||
*/
|
||||
public class NoSuchTransportException extends DbException {
|
||||
|
||||
private static final long serialVersionUID = -6274982612759573100L;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/** An event that is broadcast when a contact is added. */
|
||||
public class ContactAddedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public ContactAddedEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/** An event that is broadcast when a contact is removed. */
|
||||
public class ContactRemovedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public ContactRemovedEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
6
briar-api/src/org/briarproject/api/event/Event.java
Normal file
6
briar-api/src/org/briarproject/api/event/Event.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
/** An abstract superclass for events. */
|
||||
public abstract class Event {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
/** An interface for receiving notifications when events occur. */
|
||||
public interface EventListener {
|
||||
|
||||
void eventOccurred(Event e);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.AuthorId;
|
||||
|
||||
/** An event that is broadcast when a local pseudonym is added. */
|
||||
public class LocalAuthorAddedEvent extends Event {
|
||||
|
||||
private final AuthorId authorId;
|
||||
|
||||
public LocalAuthorAddedEvent(AuthorId authorId) {
|
||||
this.authorId = authorId;
|
||||
}
|
||||
|
||||
public AuthorId getAuthorId() {
|
||||
return authorId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.AuthorId;
|
||||
|
||||
/** An event that is broadcast when a local pseudonym is removed. */
|
||||
public class LocalAuthorRemovedEvent extends Event {
|
||||
|
||||
private final AuthorId authorId;
|
||||
|
||||
public LocalAuthorRemovedEvent(AuthorId authorId) {
|
||||
this.authorId = authorId;
|
||||
}
|
||||
|
||||
public AuthorId getAuthorId() {
|
||||
return authorId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when the set of subscriptions visible to one or
|
||||
* more contacts is updated.
|
||||
*/
|
||||
public class LocalSubscriptionsUpdatedEvent extends Event {
|
||||
|
||||
private final Collection<ContactId> affected;
|
||||
|
||||
public LocalSubscriptionsUpdatedEvent(Collection<ContactId> affected) {
|
||||
this.affected = affected;
|
||||
}
|
||||
|
||||
/** Returns the contacts affected by the update. */
|
||||
public Collection<ContactId> getAffectedContacts() {
|
||||
return affected;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when the local transport properties are
|
||||
* updated.
|
||||
*/
|
||||
public class LocalTransportsUpdatedEvent extends Event {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.messaging.Group;
|
||||
|
||||
/** An event that is broadcast when a message is added to the database. */
|
||||
public class MessageAddedEvent extends Event {
|
||||
|
||||
private final Group group;
|
||||
private final ContactId contactId;
|
||||
|
||||
public MessageAddedEvent(Group group, ContactId contactId) {
|
||||
this.group = group;
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
/** Returns the group to which the message belongs. */
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the contact from which the message was received, or
|
||||
* null if the message was locally generated.
|
||||
*/
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when one or messages expire from the database,
|
||||
* potentially changing the database's retention time.
|
||||
*/
|
||||
public class MessageExpiredEvent extends Event {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/** An event that is broadcast when a message is requested by a contact. */
|
||||
public class MessageRequestedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public MessageRequestedEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when a message is received from or offered by a
|
||||
* contact and needs to be acknowledged.
|
||||
*/
|
||||
public class MessageToAckEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public MessageToAckEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when a message is offered by a contact and needs
|
||||
* to be requested.
|
||||
*/
|
||||
public class MessageToRequestEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public MessageToRequestEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when the retention time of a contact's database
|
||||
* changes.
|
||||
*/
|
||||
public class RemoteRetentionTimeUpdatedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public RemoteRetentionTimeUpdatedEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
|
||||
/** An event that is broadcast when a contact's subscriptions are updated. */
|
||||
public class RemoteSubscriptionsUpdatedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
|
||||
public RemoteSubscriptionsUpdatedEvent(ContactId contactId) {
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when a contact's remote transport properties
|
||||
* are updated.
|
||||
*/
|
||||
public class RemoteTransportsUpdatedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final TransportId transportId;
|
||||
|
||||
public RemoteTransportsUpdatedEvent(ContactId contactId,
|
||||
TransportId transportId) {
|
||||
this.contactId = contactId;
|
||||
this.transportId = transportId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
public TransportId getTransportId() {
|
||||
return transportId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.messaging.Group;
|
||||
|
||||
/** An event that is broadcast when the user subscribes to a group. */
|
||||
public class SubscriptionAddedEvent extends Event {
|
||||
|
||||
private final Group group;
|
||||
|
||||
public SubscriptionAddedEvent(Group group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.messaging.Group;
|
||||
|
||||
/** An event that is broadcast when the user unsubscribes from a group. */
|
||||
public class SubscriptionRemovedEvent extends Event {
|
||||
|
||||
private final Group group;
|
||||
|
||||
public SubscriptionRemovedEvent(Group group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.TransportId;
|
||||
|
||||
/** An event that is broadcast when a transport is added. */
|
||||
public class TransportAddedEvent extends Event {
|
||||
|
||||
private final TransportId transportId;
|
||||
private final long maxLatency;
|
||||
|
||||
public TransportAddedEvent(TransportId transportId, long maxLatency) {
|
||||
this.transportId = transportId;
|
||||
this.maxLatency = maxLatency;
|
||||
}
|
||||
|
||||
public TransportId getTransportId() {
|
||||
return transportId;
|
||||
}
|
||||
|
||||
public long getMaxLatency() {
|
||||
return maxLatency;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.TransportId;
|
||||
|
||||
/** An event that is broadcast when a transport is removed. */
|
||||
public class TransportRemovedEvent extends Event {
|
||||
|
||||
private final TransportId transportId;
|
||||
|
||||
public TransportRemovedEvent(TransportId transportId) {
|
||||
this.transportId = transportId;
|
||||
}
|
||||
|
||||
public TransportId getTransportId() {
|
||||
return transportId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.briarproject.api.invitation;
|
||||
|
||||
public interface InvitationConstants {
|
||||
|
||||
long CONNECTION_TIMEOUT = 30 * 1000; // Milliseconds
|
||||
|
||||
long CONFIRMATION_TIMEOUT = 60 * 1000; // Milliseconds
|
||||
|
||||
int CODE_BITS = 19; // Codes must fit into six decimal digits
|
||||
|
||||
int HASH_LENGTH = 48; // Bytes
|
||||
|
||||
int MAX_PUBLIC_KEY_LENGTH = 97; // Bytes
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.briarproject.api.invitation;
|
||||
|
||||
/**
|
||||
* An interface for receiving updates about the state of an
|
||||
* {@link InvitationTask}.
|
||||
*/
|
||||
public interface InvitationListener {
|
||||
|
||||
/** Called if a connection to the remote peer is established. */
|
||||
void connectionSucceeded();
|
||||
|
||||
/**
|
||||
* Called if a connection to the remote peer cannot be established. This
|
||||
* indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void connectionFailed();
|
||||
|
||||
/** Called if key agreement with the remote peer succeeds. */
|
||||
void keyAgreementSucceeded(int localCode, int remoteCode);
|
||||
|
||||
/**
|
||||
* Called if key agreement with the remote peer fails or the connection is
|
||||
* lost. This indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void keyAgreementFailed();
|
||||
|
||||
/** Called if the remote peer's confirmation check succeeds. */
|
||||
void remoteConfirmationSucceeded();
|
||||
|
||||
/**
|
||||
* Called if remote peer's confirmation check fails or the connection is
|
||||
* lost. This indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void remoteConfirmationFailed();
|
||||
|
||||
/**
|
||||
* Called if the exchange of pseudonyms succeeds. This indicates that the
|
||||
* protocol has ended successfully.
|
||||
*/
|
||||
void pseudonymExchangeSucceeded(String remoteName);
|
||||
|
||||
/**
|
||||
* Called if the exchange of pseudonyms fails or the connection is lost.
|
||||
* This indicates that the protocol has ended unsuccessfully.
|
||||
*/
|
||||
void pseudonymExchangeFailed();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.briarproject.api.invitation;
|
||||
|
||||
public class InvitationState {
|
||||
|
||||
private final int localInvitationCode, remoteInvitationCode;
|
||||
private final int localConfirmationCode, remoteConfirmationCode;
|
||||
private final boolean connected, connectionFailed;
|
||||
private final boolean localCompared, remoteCompared;
|
||||
private final boolean localMatched, remoteMatched;
|
||||
private final String contactName;
|
||||
|
||||
public InvitationState(int localInvitationCode, int remoteInvitationCode,
|
||||
int localConfirmationCode, int remoteConfirmationCode,
|
||||
boolean connected, boolean connectionFailed, boolean localCompared,
|
||||
boolean remoteCompared, boolean localMatched,
|
||||
boolean remoteMatched, String contactName) {
|
||||
this.localInvitationCode = localInvitationCode;
|
||||
this.remoteInvitationCode = remoteInvitationCode;
|
||||
this.localConfirmationCode = localConfirmationCode;
|
||||
this.remoteConfirmationCode = remoteConfirmationCode;
|
||||
this.connected = connected;
|
||||
this.connectionFailed = connectionFailed;
|
||||
this.localCompared = localCompared;
|
||||
this.remoteCompared = remoteCompared;
|
||||
this.localMatched = localMatched;
|
||||
this.remoteMatched = remoteMatched;
|
||||
this.contactName = contactName;
|
||||
}
|
||||
|
||||
public int getLocalInvitationCode() {
|
||||
return localInvitationCode;
|
||||
}
|
||||
|
||||
public int getRemoteInvitationCode() {
|
||||
return remoteInvitationCode;
|
||||
}
|
||||
|
||||
public int getLocalConfirmationCode() {
|
||||
return localConfirmationCode;
|
||||
}
|
||||
|
||||
public int getRemoteConfirmationCode() {
|
||||
return remoteConfirmationCode;
|
||||
}
|
||||
|
||||
public boolean getConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
public boolean getConnectionFailed() {
|
||||
return connectionFailed;
|
||||
}
|
||||
|
||||
public boolean getLocalCompared() {
|
||||
return localCompared;
|
||||
}
|
||||
|
||||
public boolean getRemoteCompared() {
|
||||
return remoteCompared;
|
||||
}
|
||||
|
||||
public boolean getLocalMatched() {
|
||||
return localMatched;
|
||||
}
|
||||
|
||||
public boolean getRemoteMatched() {
|
||||
return remoteMatched;
|
||||
}
|
||||
|
||||
public String getContactName() {
|
||||
return contactName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.api.invitation;
|
||||
|
||||
/** A task for exchanging invitations with a remote peer. */
|
||||
public interface InvitationTask {
|
||||
|
||||
/**
|
||||
* Adds a listener to be informed of state changes and returns the
|
||||
* task's current state.
|
||||
*/
|
||||
InvitationState addListener(InvitationListener l);
|
||||
|
||||
/** Removes the given listener. */
|
||||
void removeListener(InvitationListener l);
|
||||
|
||||
/** Asynchronously starts the connection process. */
|
||||
void connect();
|
||||
|
||||
/**
|
||||
* Asynchronously informs the remote peer that the local peer's
|
||||
* confirmation codes matched.
|
||||
*/
|
||||
void localConfirmationSucceeded();
|
||||
|
||||
/**
|
||||
* Asynchronously informs the remote peer that the local peer's
|
||||
* confirmation codes did not match.
|
||||
*/
|
||||
void localConfirmationFailed();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.briarproject.api.invitation;
|
||||
|
||||
import org.briarproject.api.AuthorId;
|
||||
|
||||
/** Creates tasks for exchanging invitations with remote peers. */
|
||||
public interface InvitationTaskFactory {
|
||||
|
||||
/** Creates a task using the given pseudonym and invitation codes. */
|
||||
InvitationTask createTask(AuthorId localAuthorId, int localCode,
|
||||
int remoteCode);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.briarproject.api.lifecycle;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public interface LifecycleManager {
|
||||
|
||||
/** Registers a {@link Service} to be started and stopped. */
|
||||
public void register(Service s);
|
||||
|
||||
/**
|
||||
* Registers an {@link java.util.concurrent.ExecutorService ExecutorService}
|
||||
* to be shut down.
|
||||
*/
|
||||
public void registerForShutdown(ExecutorService e);
|
||||
|
||||
/** Starts any registered {@link Service}s. */
|
||||
public void startServices();
|
||||
|
||||
/**
|
||||
* Stops any registered {@link Service}s and shuts down any registered
|
||||
* {@link java.util.concurrent.ExecutorService ExecutorService}s.
|
||||
*/
|
||||
public void stopServices();
|
||||
|
||||
/** Waits for the database to be opened before returning. */
|
||||
public void waitForDatabase() throws InterruptedException;
|
||||
|
||||
/** Waits for all registered {@link Service}s to start before returning. */
|
||||
public void waitForStartup() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Waits for all registered {@link Service}s to stop and all registered
|
||||
* {@link java.util.concurrent.ExecutorService ExecutorService}s to shut
|
||||
* down before returning.
|
||||
*/
|
||||
public void waitForShutdown() throws InterruptedException;
|
||||
}
|
||||
10
briar-api/src/org/briarproject/api/lifecycle/Service.java
Normal file
10
briar-api/src/org/briarproject/api/lifecycle/Service.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.briarproject.api.lifecycle;
|
||||
|
||||
public interface Service {
|
||||
|
||||
/** Starts the service and returns true if it started successfully. */
|
||||
public boolean start();
|
||||
|
||||
/** Stops the service and returns true if it stopped successfully. */
|
||||
public boolean stop();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.lifecycle;
|
||||
|
||||
public interface ShutdownManager {
|
||||
|
||||
/**
|
||||
* Registers a hook to be run when the JVM shuts down and returns a handle
|
||||
* that can be used to remove the hook.
|
||||
*/
|
||||
int addShutdownHook(Runnable hook);
|
||||
|
||||
/**
|
||||
* Removes the shutdown hook identified by the given handle and returns
|
||||
* true if the hook was removed.
|
||||
*/
|
||||
boolean removeShutdownHook(int handle);
|
||||
}
|
||||
18
briar-api/src/org/briarproject/api/messaging/Ack.java
Normal file
18
briar-api/src/org/briarproject/api/messaging/Ack.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/** A packet acknowledging receipt of one or more {@link Message}s. */
|
||||
public class Ack {
|
||||
|
||||
private final Collection<MessageId> acked;
|
||||
|
||||
public Ack(Collection<MessageId> acked) {
|
||||
this.acked = acked;
|
||||
}
|
||||
|
||||
/** Returns the identifiers of the acknowledged messages. */
|
||||
public Collection<MessageId> getMessageIds() {
|
||||
return acked;
|
||||
}
|
||||
}
|
||||
43
briar-api/src/org/briarproject/api/messaging/Group.java
Normal file
43
briar-api/src/org/briarproject/api/messaging/Group.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
/** A group to which users may subscribe. */
|
||||
public class Group {
|
||||
|
||||
private final GroupId id;
|
||||
private final String name;
|
||||
private final byte[] salt;
|
||||
|
||||
public Group(GroupId id, String name, byte[] salt) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
/** Returns the group's unique identifier. */
|
||||
public GroupId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Returns the group's name. */
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the salt used to distinguish the group from other groups with
|
||||
* the same name.
|
||||
*/
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof Group && id.equals(((Group) o).id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
public interface GroupFactory {
|
||||
|
||||
/** Creates a group with the given name and a random salt. */
|
||||
Group createGroup(String name);
|
||||
|
||||
/** Creates a group with the given name and salt. */
|
||||
Group createGroup(String name, byte[] salt);
|
||||
}
|
||||
22
briar-api/src/org/briarproject/api/messaging/GroupId.java
Normal file
22
briar-api/src/org/briarproject/api/messaging/GroupId.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.briarproject.api.UniqueId;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a byte array that uniquely identifies a {@link Group}.
|
||||
*/
|
||||
public class GroupId extends UniqueId {
|
||||
|
||||
public GroupId(byte[] id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof GroupId)
|
||||
return Arrays.equals(id, ((GroupId) o).id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
public class GroupStatus {
|
||||
|
||||
private final Group group;
|
||||
private final boolean subscribed, visibleToAll;
|
||||
|
||||
public GroupStatus(Group group, boolean subscribed, boolean visibleToAll) {
|
||||
this.group = group;
|
||||
this.subscribed = subscribed;
|
||||
this.visibleToAll = visibleToAll;
|
||||
}
|
||||
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public boolean isSubscribed() {
|
||||
return subscribed;
|
||||
}
|
||||
|
||||
public boolean isVisibleToAll() {
|
||||
return visibleToAll;
|
||||
}
|
||||
}
|
||||
42
briar-api/src/org/briarproject/api/messaging/Message.java
Normal file
42
briar-api/src/org/briarproject/api/messaging/Message.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import org.briarproject.api.Author;
|
||||
|
||||
public interface Message {
|
||||
|
||||
/** Returns the message's unique identifier. */
|
||||
MessageId getId();
|
||||
|
||||
/**
|
||||
* Returns the identifier of the message's parent, or null if this is the
|
||||
* first message in a thread.
|
||||
*/
|
||||
MessageId getParent();
|
||||
|
||||
/**
|
||||
* Returns the {@link Group} to which the message belongs, or null if this
|
||||
* is a private message.
|
||||
*/
|
||||
Group getGroup();
|
||||
|
||||
/**
|
||||
* Returns the message's {@link org.briarproject.api.Author Author}, or null
|
||||
* if this is an anonymous message.
|
||||
*/
|
||||
Author getAuthor();
|
||||
|
||||
/** Returns the message's content type. */
|
||||
String getContentType();
|
||||
|
||||
/** Returns the message's timestamp. */
|
||||
long getTimestamp();
|
||||
|
||||
/** Returns the serialised message. */
|
||||
byte[] getSerialised();
|
||||
|
||||
/** Returns the offset of the message body within the serialised message. */
|
||||
int getBodyStart();
|
||||
|
||||
/** Returns the length of the message body in bytes. */
|
||||
int getBodyLength();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import org.briarproject.api.Author;
|
||||
import org.briarproject.api.crypto.PrivateKey;
|
||||
|
||||
public interface MessageFactory {
|
||||
|
||||
Message createAnonymousMessage(MessageId parent, Group group,
|
||||
String contentType, long timestamp, byte[] body) throws IOException,
|
||||
GeneralSecurityException;
|
||||
|
||||
Message createPseudonymousMessage(MessageId parent, Group group,
|
||||
Author author, PrivateKey privateKey, String contentType,
|
||||
long timestamp, byte[] body) throws IOException,
|
||||
GeneralSecurityException;
|
||||
}
|
||||
23
briar-api/src/org/briarproject/api/messaging/MessageId.java
Normal file
23
briar-api/src/org/briarproject/api/messaging/MessageId.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.briarproject.api.UniqueId;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a byte array that uniquely identifies a
|
||||
* {@link Message}.
|
||||
*/
|
||||
public class MessageId extends UniqueId {
|
||||
|
||||
public MessageId(byte[] id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof MessageId)
|
||||
return Arrays.equals(id, ((MessageId) o).id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/** Verifies the signatures on an {@link UnverifiedMessage}. */
|
||||
public interface MessageVerifier {
|
||||
|
||||
Message verifyMessage(UnverifiedMessage m) throws GeneralSecurityException;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.MIN_CONNECTION_LENGTH;
|
||||
|
||||
public interface MessagingConstants {
|
||||
|
||||
/**
|
||||
* The maximum length of a serialised packet in bytes. To allow for future
|
||||
* changes in the protocol, this is smaller than the minimum connection
|
||||
* length minus the maximum encryption and authentication overhead.
|
||||
*/
|
||||
int MAX_PACKET_LENGTH = MIN_CONNECTION_LENGTH / 2;
|
||||
|
||||
/** The maximum number of public groups a user may subscribe to. */
|
||||
int MAX_SUBSCRIPTIONS = 3000;
|
||||
|
||||
/** The maximum length of a group's name in UTF-8 bytes. */
|
||||
int MAX_GROUP_NAME_LENGTH = 50;
|
||||
|
||||
/** The length of a group's random salt in bytes. */
|
||||
int GROUP_SALT_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* The maximum length of a message body in bytes. To allow for future
|
||||
* changes in the protocol, this is smaller than the maximum packet length
|
||||
* even when all the message's other fields have their maximum lengths.
|
||||
*/
|
||||
int MAX_BODY_LENGTH = MAX_PACKET_LENGTH - 1024;
|
||||
|
||||
/** The maximum length of a message's content type in UTF-8 bytes. */
|
||||
int MAX_CONTENT_TYPE_LENGTH = 50;
|
||||
|
||||
/** The maximum length of a message's subject line in UTF-8 bytes. */
|
||||
int MAX_SUBJECT_LENGTH = 100;
|
||||
|
||||
/** The length of a message's random salt in bytes. */
|
||||
int MESSAGE_SALT_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* When calculating the retention time of the database, the timestamp of
|
||||
* the oldest message in the database is rounded down to a multiple of
|
||||
* this value to avoid revealing the presence of any particular message.
|
||||
*/
|
||||
int RETENTION_GRANULARITY = 60 * 1000; // 1 minute
|
||||
}
|
||||
18
briar-api/src/org/briarproject/api/messaging/Offer.java
Normal file
18
briar-api/src/org/briarproject/api/messaging/Offer.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/** A packet offering the recipient one or more {@link Messages}. */
|
||||
public class Offer {
|
||||
|
||||
private final Collection<MessageId> offered;
|
||||
|
||||
public Offer(Collection<MessageId> offered) {
|
||||
this.offered = offered;
|
||||
}
|
||||
|
||||
/** Returns the identifiers of the offered messages. */
|
||||
public Collection<MessageId> getMessageIds() {
|
||||
return offered;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface PacketReader {
|
||||
|
||||
boolean eof() throws IOException;
|
||||
|
||||
boolean hasAck() throws IOException;
|
||||
Ack readAck() throws IOException;
|
||||
|
||||
boolean hasMessage() throws IOException;
|
||||
UnverifiedMessage readMessage() throws IOException;
|
||||
|
||||
boolean hasOffer() throws IOException;
|
||||
Offer readOffer() throws IOException;
|
||||
|
||||
boolean hasRequest() throws IOException;
|
||||
Request readRequest() throws IOException;
|
||||
|
||||
boolean hasRetentionAck() throws IOException;
|
||||
RetentionAck readRetentionAck() throws IOException;
|
||||
|
||||
boolean hasRetentionUpdate() throws IOException;
|
||||
RetentionUpdate readRetentionUpdate() throws IOException;
|
||||
|
||||
boolean hasSubscriptionAck() throws IOException;
|
||||
SubscriptionAck readSubscriptionAck() throws IOException;
|
||||
|
||||
boolean hasSubscriptionUpdate() throws IOException;
|
||||
SubscriptionUpdate readSubscriptionUpdate() throws IOException;
|
||||
|
||||
boolean hasTransportAck() throws IOException;
|
||||
TransportAck readTransportAck() throws IOException;
|
||||
|
||||
boolean hasTransportUpdate() throws IOException;
|
||||
TransportUpdate readTransportUpdate() throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface PacketReaderFactory {
|
||||
|
||||
PacketReader createPacketReader(InputStream in);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface PacketWriter {
|
||||
|
||||
int getMaxMessagesForRequest(long capacity);
|
||||
|
||||
int getMaxMessagesForOffer(long capacity);
|
||||
|
||||
void writeAck(Ack a) throws IOException;
|
||||
|
||||
void writeMessage(byte[] raw) throws IOException;
|
||||
|
||||
void writeOffer(Offer o) throws IOException;
|
||||
|
||||
void writeRequest(Request r) throws IOException;
|
||||
|
||||
void writeRetentionAck(RetentionAck a) throws IOException;
|
||||
|
||||
void writeRetentionUpdate(RetentionUpdate u) throws IOException;
|
||||
|
||||
void writeSubscriptionAck(SubscriptionAck a) throws IOException;
|
||||
|
||||
void writeSubscriptionUpdate(SubscriptionUpdate u) throws IOException;
|
||||
|
||||
void writeTransportAck(TransportAck a) throws IOException;
|
||||
|
||||
void writeTransportUpdate(TransportUpdate u) throws IOException;
|
||||
|
||||
void flush() throws IOException;
|
||||
|
||||
void close() throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface PacketWriterFactory {
|
||||
|
||||
PacketWriter createPacketWriter(OutputStream out, boolean flush);
|
||||
}
|
||||
18
briar-api/src/org/briarproject/api/messaging/Request.java
Normal file
18
briar-api/src/org/briarproject/api/messaging/Request.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/** A packet requesting one or more {@link Message}s from the recipient. */
|
||||
public class Request {
|
||||
|
||||
private final Collection<MessageId> requested;
|
||||
|
||||
public Request(Collection<MessageId> requested) {
|
||||
this.requested = requested;
|
||||
}
|
||||
|
||||
/** Returns the identifiers of the requested messages. */
|
||||
public Collection<MessageId> getMessageIds() {
|
||||
return requested;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
/** A packet acknowledging a (@link RetentionUpdate} */
|
||||
public class RetentionAck {
|
||||
|
||||
private final long version;
|
||||
|
||||
public RetentionAck(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/** Returns the version number of the acknowledged update. */
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
/**
|
||||
* A packet updating the recipient's view of the retention time of the sender's
|
||||
* database.
|
||||
*/
|
||||
public class RetentionUpdate {
|
||||
|
||||
private final long retention, version;
|
||||
|
||||
public RetentionUpdate(long retention, long version) {
|
||||
this.retention = retention;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public long getRetentionTime() {
|
||||
return retention;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
/** A packet acknowledging a {@link SubscriptionUpdate}. */
|
||||
public class SubscriptionAck {
|
||||
|
||||
private final long version;
|
||||
|
||||
public SubscriptionAck(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/** Returns the version number of the acknowledged update. */
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/** A packet updating the recipient's view of the sender's subscriptions. */
|
||||
public class SubscriptionUpdate {
|
||||
|
||||
private final Collection<Group> groups;
|
||||
private final long version;
|
||||
|
||||
public SubscriptionUpdate(Collection<Group> groups, long version) {
|
||||
this.groups = groups;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the groups to which the sender subscribes, and which the sender
|
||||
* has made visible to the recipient.
|
||||
*/
|
||||
public Collection<Group> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
/** Returns the update's version number. */
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import org.briarproject.api.TransportId;
|
||||
|
||||
/** A packet acknowledging a {@link TransportUpdate}. */
|
||||
public class TransportAck {
|
||||
|
||||
private final TransportId id;
|
||||
private final long version;
|
||||
|
||||
public TransportAck(TransportId id, long version) {
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/** Returns the identifier of the updated transport. */
|
||||
public TransportId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Returns the version number of the acknowledged update. */
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.TransportProperties;
|
||||
|
||||
/**
|
||||
* A packet updating the recipient's view of the sender's transport properties.
|
||||
*/
|
||||
public class TransportUpdate {
|
||||
|
||||
private final TransportId id;
|
||||
private final TransportProperties properties;
|
||||
private final long version;
|
||||
|
||||
public TransportUpdate(TransportId id, TransportProperties properties,
|
||||
long version) {
|
||||
this.id = id;
|
||||
this.properties = properties;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/** Returns the identifier of the updated transport. */
|
||||
public TransportId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Returns the transport's updated properties. */
|
||||
public TransportProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/** Returns the update's version number. */
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
18
briar-api/src/org/briarproject/api/messaging/Types.java
Normal file
18
briar-api/src/org/briarproject/api/messaging/Types.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
/** Struct identifiers for encoding and decoding protocol objects. */
|
||||
public interface Types {
|
||||
|
||||
int AUTHOR = 0;
|
||||
int GROUP = 1;
|
||||
int ACK = 2;
|
||||
int MESSAGE = 3;
|
||||
int OFFER = 4;
|
||||
int REQUEST = 5;
|
||||
int RETENTION_ACK = 6;
|
||||
int RETENTION_UPDATE = 7;
|
||||
int SUBSCRIPTION_ACK = 8;
|
||||
int SUBSCRIPTION_UPDATE = 9;
|
||||
int TRANSPORT_ACK = 10;
|
||||
int TRANSPORT_UPDATE = 11;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.briarproject.api.messaging;
|
||||
|
||||
import org.briarproject.api.Author;
|
||||
|
||||
/** A {@link Message} that has not yet had its signatures (if any) verified. */
|
||||
public class UnverifiedMessage {
|
||||
|
||||
private final MessageId parent;
|
||||
private final Group group;
|
||||
private final Author author;
|
||||
private final String contentType;
|
||||
private final long timestamp;
|
||||
private final byte[] raw, signature;
|
||||
private final int bodyStart, bodyLength, signedLength;
|
||||
|
||||
public UnverifiedMessage(MessageId parent, Group group, Author author,
|
||||
String contentType, long timestamp, byte[] raw, byte[] signature,
|
||||
int bodyStart, int bodyLength, int signedLength) {
|
||||
this.parent = parent;
|
||||
this.group = group;
|
||||
this.author = author;
|
||||
this.contentType = contentType;
|
||||
this.timestamp = timestamp;
|
||||
this.raw = raw;
|
||||
this.signature = signature;
|
||||
this.bodyStart = bodyStart;
|
||||
this.bodyLength = bodyLength;
|
||||
this.signedLength = signedLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of the message's parent, or null if this is the
|
||||
* first message in a thread.
|
||||
*/
|
||||
public MessageId getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Group} to which the message belongs, or null if this
|
||||
* is a private message.
|
||||
*/
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message's {@link org.briarproject.api.Author Author}, or null
|
||||
* if this is an anonymous message.
|
||||
*/
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/** Returns the message's content type. */
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/** Returns the message's timestamp. */
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/** Returns the serialised message. */
|
||||
public byte[] getSerialised() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author's signature, or null if this is an anonymous message.
|
||||
*/
|
||||
public byte[] getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
/** Returns the offset of the message body within the serialised message. */
|
||||
public int getBodyStart() {
|
||||
return bodyStart;
|
||||
}
|
||||
|
||||
/** Returns the length of the message body in bytes. */
|
||||
public int getBodyLength() {
|
||||
return bodyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length in bytes of the data covered by the author's
|
||||
* signature.
|
||||
*/
|
||||
public int getSignedLength() {
|
||||
return signedLength;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.api.messaging.duplex;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||
import org.briarproject.api.transport.ConnectionContext;
|
||||
|
||||
public interface DuplexConnectionFactory {
|
||||
|
||||
void createIncomingConnection(ConnectionContext ctx,
|
||||
DuplexTransportConnection d);
|
||||
|
||||
void createOutgoingConnection(ContactId c, TransportId t,
|
||||
DuplexTransportConnection d);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.messaging.simplex;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.plugins.simplex.SimplexTransportReader;
|
||||
import org.briarproject.api.plugins.simplex.SimplexTransportWriter;
|
||||
import org.briarproject.api.transport.ConnectionContext;
|
||||
|
||||
public interface SimplexConnectionFactory {
|
||||
|
||||
void createIncomingConnection(ConnectionContext ctx,
|
||||
SimplexTransportReader r);
|
||||
|
||||
void createOutgoingConnection(ContactId c, TransportId t,
|
||||
SimplexTransportWriter w);
|
||||
}
|
||||
47
briar-api/src/org/briarproject/api/plugins/Plugin.java
Normal file
47
briar-api/src/org/briarproject/api/plugins/Plugin.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package org.briarproject.api.plugins;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
|
||||
public interface Plugin {
|
||||
|
||||
/** Returns the plugin's transport identifier. */
|
||||
TransportId getId();
|
||||
|
||||
/** Returns a label for looking up the plugin's translated name. */
|
||||
String getName();
|
||||
|
||||
/** Returns the transport's maximum frame length in bytes. */
|
||||
int getMaxFrameLength();
|
||||
|
||||
/** Returns the transport's maximum latency in milliseconds. */
|
||||
long getMaxLatency();
|
||||
|
||||
/** Starts the plugin and returns true if it started successfully. */
|
||||
boolean start() throws IOException;
|
||||
|
||||
/** Stops the plugin. */
|
||||
void stop() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns true if the plugin's {@link #poll(Collection)} method should be
|
||||
* called periodically to attempt to establish connections.
|
||||
*/
|
||||
boolean shouldPoll();
|
||||
|
||||
/**
|
||||
* Returns the desired interval in milliseconds between calls to the
|
||||
* plugin's {@link #poll(Collection)} method.
|
||||
*/
|
||||
long getPollingInterval();
|
||||
|
||||
/**
|
||||
* Attempts to establish connections to contacts, passing any created
|
||||
* connections to the callback. To avoid creating redundant connections,
|
||||
* the plugin may exclude the given contacts from polling.
|
||||
*/
|
||||
void poll(Collection<ContactId> connected);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.briarproject.api.plugins;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportConfig;
|
||||
import org.briarproject.api.TransportProperties;
|
||||
|
||||
/**
|
||||
* An interface through which a transport plugin interacts with the rest of
|
||||
* the application.
|
||||
*/
|
||||
public interface PluginCallback {
|
||||
|
||||
/** Returns the plugin's configuration. */
|
||||
TransportConfig getConfig();
|
||||
|
||||
/** Returns the plugin's local transport properties. */
|
||||
TransportProperties getLocalProperties();
|
||||
|
||||
/** Returns the plugin's remote transport properties. */
|
||||
Map<ContactId, TransportProperties> getRemoteProperties();
|
||||
|
||||
/** Merges the given configuration with the plugin's configuration. */
|
||||
void mergeConfig(TransportConfig c);
|
||||
|
||||
/**
|
||||
* Merges the given properties with the plugin's local transport properties.
|
||||
*/
|
||||
void mergeLocalProperties(TransportProperties p);
|
||||
|
||||
/**
|
||||
* Presents the user with a choice among two or more named options and
|
||||
* returns the user's response. The message may consist of a translatable
|
||||
* format string and arguments.
|
||||
* @return an index into the array of options indicating the user's choice,
|
||||
* or -1 if the user cancelled the choice.
|
||||
*/
|
||||
int showChoice(String[] options, String... message);
|
||||
|
||||
/**
|
||||
* Asks the user to confirm an action and returns the user's response. The
|
||||
* message may consist of a translatable format string and arguments.
|
||||
*/
|
||||
boolean showConfirmationMessage(String... message);
|
||||
|
||||
/**
|
||||
* Shows a message to the user. The message may consist of a translatable
|
||||
* format string and arguments.
|
||||
*/
|
||||
void showMessage(String... message);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.briarproject.api.plugins;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
/** Annotation for injecting the executor used by transport plugins. */
|
||||
@BindingAnnotation
|
||||
@Target({ FIELD, METHOD, PARAMETER })
|
||||
@Retention(RUNTIME)
|
||||
public @interface PluginExecutor {}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.plugins;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||
|
||||
/**
|
||||
* Responsible for starting transport plugins at startup, stopping them at
|
||||
* shutdown, and providing access to plugins for exchanging invitations.
|
||||
*/
|
||||
public interface PluginManager extends Service {
|
||||
|
||||
/** Returns any running duplex plugins that support invitations. */
|
||||
Collection<DuplexPlugin> getInvitationPlugins();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user