Use a versioned format for encoding authors.

This commit is contained in:
akwizgran
2017-11-29 15:48:54 +00:00
parent 7d8d169b0a
commit 030b9ef053
76 changed files with 1649 additions and 1784 deletions

View File

@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
@@ -99,4 +100,5 @@ public interface ClientHelper {
void verifySignature(String label, byte[] sig, byte[] publicKey,
BdfList signed) throws FormatException, GeneralSecurityException;
Author parseAndValidateAuthor(BdfList author) throws FormatException;
}

View File

@@ -1,11 +0,0 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
@NotNullByDefault
public interface ObjectReader<T> {
T readObject(BdfReader r) throws IOException;
}

View File

@@ -1,11 +1,13 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.UnsupportedEncodingException;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
/**
* A pseudonym for a user.
*/
@@ -17,20 +19,25 @@ public class Author {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
}
/**
* The current version of the author structure.
*/
public static final int FORMAT_VERSION = 0;
private final AuthorId id;
private final int formatVersion;
private final String name;
private final byte[] publicKey;
public Author(AuthorId id, String name, byte[] publicKey) {
int length;
try {
length = name.getBytes("UTF-8").length;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (length == 0 || length > AuthorConstants.MAX_AUTHOR_NAME_LENGTH)
public Author(AuthorId id, int formatVersion, String name,
byte[] publicKey) {
int nameLength = StringUtils.toUtf8(name).length;
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)
throw new IllegalArgumentException();
this.id = id;
this.formatVersion = formatVersion;
this.name = name;
this.publicKey = publicKey;
}
@@ -42,6 +49,13 @@ public class Author {
return id;
}
/**
* Returns the version of the author structure used to create the author.
*/
public int getFormatVersion() {
return formatVersion;
}
/**
* Returns the author's name.
*/

View File

@@ -5,8 +5,27 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface AuthorFactory {
/**
* Creates an author with the current format version and the given name and
* public key.
*/
Author createAuthor(String name, byte[] publicKey);
/**
* Creates an author with the given format version, name and public key.
*/
Author createAuthor(int formatVersion, String name, byte[] publicKey);
/**
* Creates a local author with the current format version and the given
* name and keys.
*/
LocalAuthor createLocalAuthor(String name, byte[] publicKey,
byte[] privateKey);
/**
* Creates a local author with the given format version, name and keys.
*/
LocalAuthor createLocalAuthor(int formatVersion, String name,
byte[] publicKey, byte[] privateKey);
}

View File

@@ -14,9 +14,9 @@ public class LocalAuthor extends Author {
private final byte[] privateKey;
private final long created;
public LocalAuthor(AuthorId id, String name, byte[] publicKey,
byte[] privateKey, long created) {
super(id, name, publicKey);
public LocalAuthor(AuthorId id, int formatVersion, String name,
byte[] publicKey, byte[] privateKey, long created) {
super(id, formatVersion, name, publicKey);
this.privateKey = privateKey;
this.created = created;
}

View File

@@ -20,6 +20,7 @@ import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
@@ -67,7 +68,8 @@ public class TestUtils {
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
long created = System.currentTimeMillis();
return new LocalAuthor(id, name, publicKey, privateKey, created);
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey,
created);
}
public static Author getAuthor() {
@@ -78,7 +80,7 @@ public class TestUtils {
AuthorId id = new AuthorId(getRandomId());
String name = getRandomString(nameLength);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
return new Author(id, name, publicKey);
return new Author(id, FORMAT_VERSION, name, publicKey);
}
public static Group getGroup(ClientId clientId) {

View File

@@ -15,6 +15,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
@@ -32,7 +34,12 @@ import java.util.Map.Entry;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
@Immutable
@NotNullByDefault
@@ -51,12 +58,14 @@ class ClientHelperImpl implements ClientHelper {
private final MetadataParser metadataParser;
private final MetadataEncoder metadataEncoder;
private final CryptoComponent crypto;
private final AuthorFactory authorFactory;
@Inject
ClientHelperImpl(DatabaseComponent db, MessageFactory messageFactory,
BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory, MetadataParser metadataParser,
MetadataEncoder metadataEncoder, CryptoComponent crypto) {
MetadataEncoder metadataEncoder, CryptoComponent crypto,
AuthorFactory authorFactory) {
this.db = db;
this.messageFactory = messageFactory;
this.bdfReaderFactory = bdfReaderFactory;
@@ -64,6 +73,7 @@ class ClientHelperImpl implements ClientHelper {
this.metadataParser = metadataParser;
this.metadataEncoder = metadataEncoder;
this.crypto = crypto;
this.authorFactory = authorFactory;
}
@Override
@@ -355,4 +365,16 @@ class ClientHelperImpl implements ClientHelper {
}
}
@Override
public Author parseAndValidateAuthor(BdfList author)
throws FormatException {
checkSize(author, 3);
int formatVersion = author.getLong(0).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = author.getString(1);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = author.getRaw(2);
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
return authorFactory.createAuthor(formatVersion, name, publicKey);
}
}

View File

@@ -2,14 +2,6 @@ package org.briarproject.bramble.client;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.data.BdfReaderFactory;
import org.briarproject.bramble.api.data.BdfWriterFactory;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.sync.GroupFactory;
import org.briarproject.bramble.api.sync.MessageFactory;
import dagger.Module;
import dagger.Provides;
@@ -18,19 +10,14 @@ import dagger.Provides;
public class ClientModule {
@Provides
ClientHelper provideClientHelper(DatabaseComponent db,
MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory, MetadataParser metadataParser,
MetadataEncoder metadataEncoder, CryptoComponent cryptoComponent) {
return new ClientHelperImpl(db, messageFactory, bdfReaderFactory,
bdfWriterFactory, metadataParser, metadataEncoder,
cryptoComponent);
ClientHelper provideClientHelper(ClientHelperImpl clientHelper) {
return clientHelper;
}
@Provides
ContactGroupFactory provideContactGroupFactory(GroupFactory groupFactory,
ClientHelper clientHelper) {
return new ContactGroupFactoryImpl(groupFactory, clientHelper);
ContactGroupFactory provideContactGroupFactory(
ContactGroupFactoryImpl contactGroupFactory) {
return contactGroupFactory;
}
}

View File

@@ -43,6 +43,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
@@ -227,6 +228,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
// Write the name, public key and signature
w.writeListStart();
w.writeLong(localAuthor.getFormatVersion());
w.writeString(localAuthor.getName());
w.writeRaw(localAuthor.getPublicKey());
w.writeRaw(sig);
@@ -236,11 +238,16 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
private Author receivePseudonym(BdfReader r, byte[] nonce)
throws GeneralSecurityException, IOException {
// Read the name, public key and signature
// Read the format version, name, public key and signature
r.readListStart();
int formatVersion = (int) r.readLong();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
if (name.isEmpty()) throw new FormatException();
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
if (publicKey.length == 0) throw new FormatException();
byte[] sig = r.readRaw(MAX_SIGNATURE_LENGTH);
if (sig.length == 0) throw new FormatException();
r.readListEnd();
LOG.info("Received pseudonym");
// Verify the signature
@@ -249,7 +256,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
LOG.info("Invalid signature");
throw new GeneralSecurityException();
}
return authorFactory.createAuthor(name, publicKey);
return authorFactory.createAuthor(formatVersion, name, publicKey);
}
private void sendTimestamp(BdfWriter w, long timestamp)

View File

@@ -81,6 +81,7 @@ abstract class JdbcDatabase implements Database<Connection> {
private static final String CREATE_LOCAL_AUTHORS =
"CREATE TABLE localAuthors"
+ " (authorId _HASH NOT NULL,"
+ " formatVersion INT NOT NULL,"
+ " name _STRING NOT NULL,"
+ " publicKey _BINARY NOT NULL,"
+ " privateKey _BINARY NOT NULL,"
@@ -91,6 +92,7 @@ abstract class JdbcDatabase implements Database<Connection> {
"CREATE TABLE contacts"
+ " (contactId _COUNTER,"
+ " authorId _HASH NOT NULL,"
+ " formatVersion INT NOT NULL,"
+ " name _STRING NOT NULL,"
+ " publicKey _BINARY NOT NULL,"
+ " localAuthorId _HASH NOT NULL,"
@@ -513,16 +515,18 @@ abstract class JdbcDatabase implements Database<Connection> {
try {
// Create a contact row
String sql = "INSERT INTO contacts"
+ " (authorId, name, publicKey, localAuthorId,"
+ " (authorId, formatVersion, name, publicKey,"
+ " localAuthorId,"
+ " verified, active)"
+ " VALUES (?, ?, ?, ?, ?, ?)";
+ " VALUES (?, ?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, remote.getId().getBytes());
ps.setString(2, remote.getName());
ps.setBytes(3, remote.getPublicKey());
ps.setBytes(4, local.getBytes());
ps.setBoolean(5, verified);
ps.setBoolean(6, active);
ps.setInt(2, remote.getFormatVersion());
ps.setString(3, remote.getName());
ps.setBytes(4, remote.getPublicKey());
ps.setBytes(5, local.getBytes());
ps.setBoolean(6, verified);
ps.setBoolean(7, active);
int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException();
ps.close();
@@ -590,14 +594,16 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
try {
String sql = "INSERT INTO localAuthors"
+ " (authorId, name, publicKey, privateKey, created)"
+ " VALUES (?, ?, ?, ?, ?)";
+ " (authorId, formatVersion, name, publicKey,"
+ " privateKey, created)"
+ " VALUES (?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getId().getBytes());
ps.setString(2, a.getName());
ps.setBytes(3, a.getPublicKey());
ps.setBytes(4, a.getPrivateKey());
ps.setLong(5, a.getTimeCreated());
ps.setInt(2, a.getFormatVersion());
ps.setString(3, a.getName());
ps.setBytes(4, a.getPublicKey());
ps.setBytes(5, a.getPrivateKey());
ps.setLong(6, a.getTimeCreated());
int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException();
ps.close();
@@ -1013,7 +1019,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT authorId, name, publicKey,"
String sql = "SELECT authorId, formatVersion, name, publicKey,"
+ " localAuthorId, verified, active"
+ " FROM contacts"
+ " WHERE contactId = ?";
@@ -1022,14 +1028,16 @@ abstract class JdbcDatabase implements Database<Connection> {
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
AuthorId authorId = new AuthorId(rs.getBytes(1));
String name = rs.getString(2);
byte[] publicKey = rs.getBytes(3);
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
boolean verified = rs.getBoolean(5);
boolean active = rs.getBoolean(6);
int formatVersion = rs.getInt(2);
String name = rs.getString(3);
byte[] publicKey = rs.getBytes(4);
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
boolean verified = rs.getBoolean(6);
boolean active = rs.getBoolean(7);
rs.close();
ps.close();
Author author = new Author(authorId, name, publicKey);
Author author =
new Author(authorId, formatVersion, name, publicKey);
return new Contact(c, author, localAuthorId, verified, active);
} catch (SQLException e) {
tryToClose(rs);
@@ -1044,8 +1052,8 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT contactId, authorId, name, publicKey,"
+ " localAuthorId, verified, active"
String sql = "SELECT contactId, authorId, formatVersion, name,"
+ " publicKey, localAuthorId, verified, active"
+ " FROM contacts";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
@@ -1053,12 +1061,14 @@ abstract class JdbcDatabase implements Database<Connection> {
while (rs.next()) {
ContactId contactId = new ContactId(rs.getInt(1));
AuthorId authorId = new AuthorId(rs.getBytes(2));
String name = rs.getString(3);
byte[] publicKey = rs.getBytes(4);
Author author = new Author(authorId, name, publicKey);
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
boolean verified = rs.getBoolean(6);
boolean active = rs.getBoolean(7);
int formatVersion = rs.getInt(3);
String name = rs.getString(4);
byte[] publicKey = rs.getBytes(5);
Author author =
new Author(authorId, formatVersion, name, publicKey);
AuthorId localAuthorId = new AuthorId(rs.getBytes(6));
boolean verified = rs.getBoolean(7);
boolean active = rs.getBoolean(8);
contacts.add(new Contact(contactId, author, localAuthorId,
verified, active));
}
@@ -1101,7 +1111,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT contactId, name, publicKey,"
String sql = "SELECT contactId, formatVersion, name, publicKey,"
+ " localAuthorId, verified, active"
+ " FROM contacts"
+ " WHERE authorId = ?";
@@ -1111,12 +1121,14 @@ abstract class JdbcDatabase implements Database<Connection> {
List<Contact> contacts = new ArrayList<>();
while (rs.next()) {
ContactId c = new ContactId(rs.getInt(1));
String name = rs.getString(2);
byte[] publicKey = rs.getBytes(3);
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
boolean verified = rs.getBoolean(5);
boolean active = rs.getBoolean(6);
Author author = new Author(remote, name, publicKey);
int formatVersion = rs.getInt(2);
String name = rs.getString(3);
byte[] publicKey = rs.getBytes(4);
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
boolean verified = rs.getBoolean(6);
boolean active = rs.getBoolean(7);
Author author =
new Author(remote, formatVersion, name, publicKey);
contacts.add(new Contact(c, author, localAuthorId, verified,
active));
}
@@ -1235,19 +1247,21 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT name, publicKey, privateKey, created"
String sql = "SELECT formatVersion, name, publicKey,"
+ " privateKey, created"
+ " FROM localAuthors"
+ " WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getBytes());
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
String name = rs.getString(1);
byte[] publicKey = rs.getBytes(2);
byte[] privateKey = rs.getBytes(3);
long created = rs.getLong(4);
LocalAuthor localAuthor = new LocalAuthor(a, name, publicKey,
privateKey, created);
int formatVersion = rs.getInt(1);
String name = rs.getString(2);
byte[] publicKey = rs.getBytes(3);
byte[] privateKey = rs.getBytes(4);
long created = rs.getLong(5);
LocalAuthor localAuthor = new LocalAuthor(a, formatVersion, name,
publicKey, privateKey, created);
if (rs.next()) throw new DbStateException();
rs.close();
ps.close();
@@ -1265,19 +1279,21 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT authorId, name, publicKey, privateKey, created"
String sql = "SELECT authorId, formatVersion, name, publicKey,"
+ " privateKey, created"
+ " FROM localAuthors";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
List<LocalAuthor> authors = new ArrayList<>();
while (rs.next()) {
AuthorId authorId = new AuthorId(rs.getBytes(1));
String name = rs.getString(2);
byte[] publicKey = rs.getBytes(3);
byte[] privateKey = rs.getBytes(4);
long created = rs.getLong(5);
authors.add(new LocalAuthor(authorId, name, publicKey,
privateKey, created));
int formatVersion = rs.getInt(2);
String name = rs.getString(3);
byte[] publicKey = rs.getBytes(4);
byte[] privateKey = rs.getBytes(5);
long created = rs.getLong(6);
authors.add(new LocalAuthor(authorId, formatVersion, name,
publicKey, privateKey, created));
}
rs.close();
ps.close();

View File

@@ -1,61 +1,65 @@
package org.briarproject.bramble.identity;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.data.BdfWriter;
import org.briarproject.bramble.api.data.BdfWriterFactory;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.Clock;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorId.LABEL;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
@Immutable
@NotNullByDefault
class AuthorFactoryImpl implements AuthorFactory {
private final CryptoComponent crypto;
private final BdfWriterFactory bdfWriterFactory;
private final Clock clock;
@Inject
AuthorFactoryImpl(CryptoComponent crypto, BdfWriterFactory bdfWriterFactory,
Clock clock) {
AuthorFactoryImpl(CryptoComponent crypto, Clock clock) {
this.crypto = crypto;
this.bdfWriterFactory = bdfWriterFactory;
this.clock = clock;
}
@Override
public Author createAuthor(String name, byte[] publicKey) {
return new Author(getId(name, publicKey), name, publicKey);
return createAuthor(FORMAT_VERSION, name, publicKey);
}
@Override
public Author createAuthor(int formatVersion, String name,
byte[] publicKey) {
AuthorId id = getId(formatVersion, name, publicKey);
return new Author(id, formatVersion, name, publicKey);
}
@Override
public LocalAuthor createLocalAuthor(String name, byte[] publicKey,
byte[] privateKey) {
return new LocalAuthor(getId(name, publicKey), name, publicKey,
privateKey, clock.currentTimeMillis());
return createLocalAuthor(FORMAT_VERSION, name, publicKey, privateKey);
}
private AuthorId getId(String name, byte[] publicKey) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BdfWriter w = bdfWriterFactory.createWriter(out);
try {
w.writeListStart();
w.writeString(name);
w.writeRaw(publicKey);
w.writeListEnd();
} catch (IOException e) {
// Shouldn't happen with ByteArrayOutputStream
throw new RuntimeException(e);
}
return new AuthorId(crypto.hash(AuthorId.LABEL, out.toByteArray()));
@Override
public LocalAuthor createLocalAuthor(int formatVersion, String name,
byte[] publicKey, byte[] privateKey) {
AuthorId id = getId(formatVersion, name, publicKey);
return new LocalAuthor(id, formatVersion, name, publicKey, privateKey,
clock.currentTimeMillis());
}
private AuthorId getId(int formatVersion, String name, byte[] publicKey) {
byte[] formatVersionBytes = new byte[INT_32_BYTES];
ByteUtils.writeUint32(formatVersion, formatVersionBytes, 0);
return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
StringUtils.toUtf8(name), publicKey));
}
}

View File

@@ -1,36 +0,0 @@
package org.briarproject.bramble.identity;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfReader;
import org.briarproject.bramble.api.data.ObjectReader;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
@Immutable
@NotNullByDefault
class AuthorReader implements ObjectReader<Author> {
private final AuthorFactory authorFactory;
AuthorReader(AuthorFactory authorFactory) {
this.authorFactory = authorFactory;
}
@Override
public Author readObject(BdfReader r) throws IOException {
r.readListStart();
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
if (name.length() == 0) throw new FormatException();
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
r.readListEnd();
return authorFactory.createAuthor(name, publicKey);
}
}

View File

@@ -1,13 +1,7 @@
package org.briarproject.bramble.identity;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.data.BdfWriterFactory;
import org.briarproject.bramble.api.data.ObjectReader;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.system.Clock;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -24,19 +18,14 @@ public class IdentityModule {
}
@Provides
AuthorFactory provideAuthorFactory(CryptoComponent crypto,
BdfWriterFactory bdfWriterFactory, Clock clock) {
return new AuthorFactoryImpl(crypto, bdfWriterFactory, clock);
AuthorFactory provideAuthorFactory(AuthorFactoryImpl authorFactory) {
return authorFactory;
}
@Provides
@Singleton
IdentityManager provideIdentityModule(DatabaseComponent db) {
return new IdentityManagerImpl(db);
}
@Provides
ObjectReader<Author> provideAuthorReader(AuthorFactory authorFactory) {
return new AuthorReader(authorFactory);
IdentityManager provideIdentityManager(
IdentityManagerImpl identityManager) {
return identityManager;
}
}

View File

@@ -15,6 +15,8 @@ import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageFactory;
@@ -31,9 +33,14 @@ import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -54,7 +61,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
context.mock(MetadataEncoder.class);
private final CryptoComponent cryptoComponent =
context.mock(CryptoComponent.class);
private final ClientHelper clientHelper;
private final AuthorFactory authorFactory =
context.mock(AuthorFactory.class);
private final GroupId groupId = new GroupId(getRandomId());
private final BdfDictionary dictionary = new BdfDictionary();
@@ -66,17 +74,15 @@ public class ClientHelperImplTest extends BrambleTestCase {
private final Metadata metadata = new Metadata();
private final BdfList list = BdfList.of("Sign this!", getRandomBytes(42));
private final String label = StringUtils.getRandomString(5);
private final Author author = getAuthor();
public ClientHelperImplTest() {
clientHelper =
new ClientHelperImpl(db, messageFactory, bdfReaderFactory,
bdfWriterFactory, metadataParser, metadataEncoder,
cryptoComponent);
}
private final ClientHelper clientHelper = new ClientHelperImpl(db,
messageFactory, bdfReaderFactory, bdfWriterFactory, metadataParser,
metadataEncoder, cryptoComponent, authorFactory);
@Test
public void testAddLocalMessage() throws Exception {
boolean shared = true;
boolean shared = new Random().nextBoolean();
Transaction txn = new Transaction(null, false);
context.checking(new Expectations() {{
@@ -180,8 +186,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
oneOf(db).endTransaction(txn);
}});
assertEquals(map,
clientHelper.getMessageMetadataAsDictionary(groupId));
assertEquals(map, clientHelper.getMessageMetadataAsDictionary(groupId));
context.assertIsSatisfied();
}
@@ -318,8 +323,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
}});
try {
clientHelper
.verifySignature(label, rawMessage, publicKey, list);
clientHelper.verifySignature(label, rawMessage, publicKey, list);
fail();
} catch (GeneralSecurityException e) {
// expected
@@ -327,6 +331,154 @@ public class ClientHelperImplTest extends BrambleTestCase {
}
}
@Test
public void testAcceptsValidAuthor() throws Exception {
BdfList authorList = BdfList.of(
author.getFormatVersion(),
author.getName(),
author.getPublicKey()
);
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(author.getFormatVersion(),
author.getName(), author.getPublicKey());
will(returnValue(author));
}});
assertEquals(author, clientHelper.parseAndValidateAuthor(authorList));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortAuthor() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongAuthor() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName(),
author.getPublicKey(),
"foo"
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithNullFormatVersion() throws Exception {
BdfList invalidAuthor = BdfList.of(
null,
author.getName(),
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithNonIntegerFormatVersion()
throws Exception {
BdfList invalidAuthor = BdfList.of(
"foo",
author.getName(),
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithUnknownFormatVersion() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion() + 1,
author.getName(),
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithTooShortName() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
"",
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithTooLongName() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1),
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithNullName() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
null,
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithNonStringName() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
getRandomBytes(5),
author.getPublicKey()
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithTooShortPublicKey() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName(),
new byte[0]
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithTooLongPublicKey() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1)
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithNullPublicKey() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName(),
null
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
@Test(expected = FormatException.class)
public void testRejectsAuthorWithNonRawPublicKey() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName(),
"foo"
);
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
private byte[] expectToByteArray(BdfList list) throws Exception {
BdfWriter bdfWriter = context.mock(BdfWriter.class);
@@ -352,5 +504,4 @@ public class ClientHelperImplTest extends BrambleTestCase {
will(returnValue(eof));
}});
}
}

View File

@@ -18,8 +18,9 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Random;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.junit.Assert.assertEquals;
@@ -32,9 +33,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
private final KeyManager keyManager = context.mock(KeyManager.class);
private final ContactManager contactManager;
private final ContactId contactId = new ContactId(42);
private final Author remote =
new Author(new AuthorId(getRandomId()), "remote",
getRandomBytes(42));
private final Author remote = getAuthor();
private final AuthorId local = new AuthorId(getRandomId());
private final boolean verified = false, active = true;
private final Contact contact =
@@ -47,8 +46,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
@Test
public void testAddContact() throws Exception {
SecretKey master = getSecretKey();
long timestamp = 42;
boolean alice = true;
long timestamp = System.currentTimeMillis();
boolean alice = new Random().nextBoolean();
Transaction txn = new Transaction(null, false);
context.checking(new Expectations() {{

View File

@@ -17,7 +17,6 @@ import org.briarproject.bramble.api.db.NoSuchTransportException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent;
import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent;
@@ -49,7 +48,6 @@ import org.briarproject.bramble.api.transport.OutgoingKeys;
import org.briarproject.bramble.api.transport.TransportKeys;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.jmock.Expectations;
import org.junit.Test;
@@ -59,7 +57,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@@ -68,6 +65,9 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERE
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -85,9 +85,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
private final ClientId clientId;
private final GroupId groupId;
private final Group group;
private final AuthorId authorId;
private final Author author;
private final AuthorId localAuthorId;
private final LocalAuthor localAuthor;
private final MessageId messageId, messageId1;
private final int size;
@@ -100,18 +98,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
private final Contact contact;
public DatabaseComponentImplTest() {
clientId = new ClientId(StringUtils.getRandomString(5));
clientId = new ClientId(getRandomString(123));
groupId = new GroupId(TestUtils.getRandomId());
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
group = new Group(groupId, clientId, descriptor);
authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId());
long timestamp = System.currentTimeMillis();
localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
author = getAuthor();
localAuthor = getLocalAuthor();
messageId = new MessageId(TestUtils.getRandomId());
messageId1 = new MessageId(TestUtils.getRandomId());
long timestamp = System.currentTimeMillis();
size = 1234;
raw = new byte[size];
message = new Message(messageId, groupId, timestamp, raw);
@@ -120,7 +115,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
transportId = new TransportId("id");
maxLatency = Integer.MAX_VALUE;
contactId = new ContactId(234);
contact = new Contact(contactId, author, localAuthorId, true, true);
contact = new Contact(contactId, author, localAuthor.getId(),
true, true);
}
private DatabaseComponent createDatabaseComponent(Database<Object> database,
@@ -142,18 +138,20 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
oneOf(database).startTransaction();
will(returnValue(txn));
// registerLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
// addContact()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).containsLocalAuthor(txn, authorId);
oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(false));
oneOf(database).containsContact(txn, authorId, localAuthorId);
oneOf(database).containsContact(txn, author.getId(),
localAuthor.getId());
will(returnValue(false));
oneOf(database).addContact(txn, author, localAuthorId, true, true);
oneOf(database).addContact(txn, author, localAuthor.getId(),
true, true);
will(returnValue(contactId));
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
oneOf(eventBus).broadcast(with(any(
@@ -187,9 +185,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
oneOf(database).removeContact(txn, contactId);
oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class)));
// removeLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).removeLocalAuthor(txn, localAuthorId);
oneOf(database).removeLocalAuthor(txn, localAuthor.getId());
oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class)));
// endTransaction()
oneOf(database).commitTransaction(txn);
@@ -203,9 +201,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false);
try {
db.addLocalAuthor(transaction, localAuthor);
assertEquals(contactId,
db.addContact(transaction, author, localAuthorId, true,
true));
assertEquals(contactId, db.addContact(transaction, author,
localAuthor.getId(), true, true));
assertEquals(Collections.singletonList(contact),
db.getContacts(transaction));
db.addGroup(transaction, group); // First time - listeners called
@@ -214,7 +211,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
db.getGroups(transaction, clientId));
db.removeGroup(transaction, group);
db.removeContact(transaction, contactId);
db.removeLocalAuthor(transaction, localAuthorId);
db.removeLocalAuthor(transaction, localAuthor.getId());
db.commitTransaction(transaction);
} finally {
db.endTransaction(transaction);
@@ -487,7 +484,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
// Check whether the pseudonym is in the DB (which it's not)
exactly(3).of(database).startTransaction();
will(returnValue(txn));
exactly(3).of(database).containsLocalAuthor(txn, localAuthorId);
exactly(3).of(database).containsLocalAuthor(txn,
localAuthor.getId());
will(returnValue(false));
exactly(3).of(database).abortTransaction(txn);
}});
@@ -496,7 +494,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false);
try {
db.addContact(transaction, author, localAuthorId, true, true);
db.addContact(transaction, author, localAuthor.getId(), true, true);
fail();
} catch (NoSuchLocalAuthorException expected) {
// Expected
@@ -506,7 +504,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
transaction = db.startTransaction(false);
try {
db.getLocalAuthor(transaction, localAuthorId);
db.getLocalAuthor(transaction, localAuthor.getId());
fail();
} catch (NoSuchLocalAuthorException expected) {
// Expected
@@ -516,7 +514,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
transaction = db.startTransaction(false);
try {
db.removeLocalAuthor(transaction, localAuthorId);
db.removeLocalAuthor(transaction, localAuthor.getId());
fail();
} catch (NoSuchLocalAuthorException expected) {
// Expected
@@ -759,18 +757,20 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
oneOf(database).startTransaction();
will(returnValue(txn));
// registerLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
// addContact()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).containsLocalAuthor(txn, authorId);
oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(false));
oneOf(database).containsContact(txn, authorId, localAuthorId);
oneOf(database).containsContact(txn, author.getId(),
localAuthor.getId());
will(returnValue(false));
oneOf(database).addContact(txn, author, localAuthorId, true, true);
oneOf(database).addContact(txn, author, localAuthor.getId(),
true, true);
will(returnValue(contactId));
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
oneOf(eventBus).broadcast(with(any(
@@ -792,9 +792,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false);
try {
db.addLocalAuthor(transaction, localAuthor);
assertEquals(contactId,
db.addContact(transaction, author, localAuthorId, true,
true));
assertEquals(contactId, db.addContact(transaction, author,
localAuthor.getId(), true, true));
db.commitTransaction(transaction);
} finally {
db.endTransaction(transaction);
@@ -1406,10 +1405,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
// Contact is a local identity
oneOf(database).containsLocalAuthor(txn, authorId);
oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(true));
oneOf(database).abortTransaction(txn);
}});
@@ -1419,7 +1418,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false);
try {
db.addContact(transaction, author, localAuthorId, true, true);
db.addContact(transaction, author, localAuthor.getId(), true, true);
fail();
} catch (ContactExistsException expected) {
// Expected
@@ -1433,12 +1432,13 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsLocalAuthor(txn, localAuthorId);
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).containsLocalAuthor(txn, authorId);
oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(false));
// Contact already exists for this local identity
oneOf(database).containsContact(txn, authorId, localAuthorId);
oneOf(database).containsContact(txn, author.getId(),
localAuthor.getId());
will(returnValue(true));
oneOf(database).abortTransaction(txn);
}});
@@ -1448,7 +1448,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false);
try {
db.addContact(transaction, author, localAuthorId, true, true);
db.addContact(transaction, author, localAuthor.getId(), true, true);
fail();
} catch (ContactExistsException expected) {
// Expected

View File

@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.settings.Settings;
@@ -26,7 +25,6 @@ import org.briarproject.bramble.system.SystemClock;
import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.TestDatabaseConfig;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -46,7 +44,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@@ -56,6 +53,11 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERE
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -75,7 +77,6 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
private final ClientId clientId;
private final Group group;
private final Author author;
private final AuthorId localAuthorId;
private final LocalAuthor localAuthor;
private final MessageId messageId;
private final long timestamp;
@@ -86,19 +87,16 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
private final ContactId contactId;
JdbcDatabaseTest() throws Exception {
groupId = new GroupId(TestUtils.getRandomId());
clientId = new ClientId(StringUtils.getRandomString(5));
groupId = new GroupId(getRandomId());
clientId = new ClientId(getRandomString(123));
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
group = new Group(groupId, clientId, descriptor);
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId());
author = getAuthor();
localAuthor = getLocalAuthor();
messageId = new MessageId(getRandomId());
timestamp = System.currentTimeMillis();
localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
messageId = new MessageId(TestUtils.getRandomId());
size = 1234;
raw = TestUtils.getRandomBytes(size);
raw = getRandomBytes(size);
message = new Message(messageId, groupId, timestamp, raw);
transportId = new TransportId("id");
contactId = new ContactId(1);
@@ -119,7 +117,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction();
assertFalse(db.containsContact(txn, contactId));
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
assertTrue(db.containsContact(txn, contactId));
assertFalse(db.containsGroup(txn, groupId));
@@ -182,7 +180,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -220,7 +218,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared but unvalidated message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -266,7 +264,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, an invisible group and a shared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addMessage(txn, message, DELIVERED, true);
@@ -318,7 +316,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and an unshared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -350,7 +348,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -377,13 +375,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact and a visible group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, false);
// Add some messages to ack
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId messageId1 = new MessageId(getRandomId());
Message message1 = new Message(messageId1, groupId, timestamp, raw);
db.addMessage(txn, message, DELIVERED, true);
db.addStatus(txn, contactId, messageId, false, true);
@@ -414,7 +412,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -572,7 +570,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact and a shared group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -592,7 +590,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
// The group is not in the database
@@ -610,7 +608,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addMessage(txn, message, DELIVERED, true);
@@ -630,7 +628,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact and a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
@@ -680,7 +678,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, the transport and the transport keys
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addTransport(txn, transportId, 123);
db.addTransportKeys(txn, contactId, keys);
@@ -742,7 +740,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, transport and transport keys
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addTransport(txn, transportId, 123);
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
@@ -778,7 +776,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the contact, transport and transport keys
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addTransport(txn, transportId, 123);
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
@@ -813,7 +811,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addLocalAuthor(txn, localAuthor);
// Add a contact associated with the local author
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
// Ensure contact is returned from database by Author ID
@@ -838,18 +836,19 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a local author - no contacts should be associated
db.addLocalAuthor(txn, localAuthor);
Collection<ContactId> contacts = db.getContacts(txn, localAuthorId);
Collection<ContactId> contacts =
db.getContacts(txn, localAuthor.getId());
assertEquals(Collections.emptyList(), contacts);
// Add a contact associated with the local author
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
contacts = db.getContacts(txn, localAuthorId);
contacts = db.getContacts(txn, localAuthor.getId());
assertEquals(Collections.singletonList(contactId), contacts);
// Remove the local author - the contact should be removed
db.removeLocalAuthor(txn, localAuthorId);
contacts = db.getContacts(txn, localAuthorId);
db.removeLocalAuthor(txn, localAuthor.getId());
contacts = db.getContacts(txn, localAuthor.getId());
assertEquals(Collections.emptyList(), contacts);
assertFalse(db.containsContact(txn, contactId));
@@ -864,14 +863,14 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact - initially there should be no offered messages
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
assertEquals(0, db.countOfferedMessages(txn, contactId));
// Add some offered messages and count them
List<MessageId> ids = new ArrayList<>();
for (int i = 0; i < 10; i++) {
MessageId m = new MessageId(TestUtils.getRandomId());
MessageId m = new MessageId(getRandomId());
db.addOfferedMessage(txn, contactId, m);
ids.add(m);
}
@@ -1056,7 +1055,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test
public void testMetadataQueries() throws Exception {
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId messageId1 = new MessageId(getRandomId());
Message message1 = new Message(messageId1, groupId, timestamp, raw);
Database<Connection> db = open(false);
@@ -1160,7 +1159,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test
public void testMetadataQueriesOnlyForDeliveredMessages() throws Exception {
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId messageId1 = new MessageId(getRandomId());
Message message1 = new Message(messageId1, groupId, timestamp, raw);
Database<Connection> db = open(false);
@@ -1231,10 +1230,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test
public void testMessageDependencies() throws Exception {
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
MessageId messageId4 = new MessageId(TestUtils.getRandomId());
MessageId messageId1 = new MessageId(getRandomId());
MessageId messageId2 = new MessageId(getRandomId());
MessageId messageId3 = new MessageId(getRandomId());
MessageId messageId4 = new MessageId(getRandomId());
Message message1 = new Message(messageId1, groupId, timestamp, raw);
Message message2 = new Message(messageId2, groupId, timestamp, raw);
@@ -1315,21 +1314,21 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addMessage(txn, message, PENDING, true);
// Add a second group
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
GroupId groupId1 = new GroupId(getRandomId());
Group group1 = new Group(groupId1, clientId,
TestUtils.getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH));
getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH));
db.addGroup(txn, group1);
// Add a message to the second group
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId messageId1 = new MessageId(getRandomId());
Message message1 = new Message(messageId1, groupId1, timestamp, raw);
db.addMessage(txn, message1, DELIVERED, true);
// Create an ID for a missing message
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
MessageId messageId2 = new MessageId(getRandomId());
// Add another message to the first group
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
MessageId messageId3 = new MessageId(getRandomId());
Message message3 = new Message(messageId3, groupId, timestamp, raw);
db.addMessage(txn, message3, DELIVERED, true);
@@ -1364,10 +1363,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test
public void testGetPendingMessagesForDelivery() throws Exception {
MessageId mId1 = new MessageId(TestUtils.getRandomId());
MessageId mId2 = new MessageId(TestUtils.getRandomId());
MessageId mId3 = new MessageId(TestUtils.getRandomId());
MessageId mId4 = new MessageId(TestUtils.getRandomId());
MessageId mId1 = new MessageId(getRandomId());
MessageId mId2 = new MessageId(getRandomId());
MessageId mId3 = new MessageId(getRandomId());
MessageId mId4 = new MessageId(getRandomId());
Message m1 = new Message(mId1, groupId, timestamp, raw);
Message m2 = new Message(mId2, groupId, timestamp, raw);
Message m3 = new Message(mId3, groupId, timestamp, raw);
@@ -1401,10 +1400,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test
public void testGetMessagesToShare() throws Exception {
MessageId mId1 = new MessageId(TestUtils.getRandomId());
MessageId mId2 = new MessageId(TestUtils.getRandomId());
MessageId mId3 = new MessageId(TestUtils.getRandomId());
MessageId mId4 = new MessageId(TestUtils.getRandomId());
MessageId mId1 = new MessageId(getRandomId());
MessageId mId2 = new MessageId(getRandomId());
MessageId mId3 = new MessageId(getRandomId());
MessageId mId4 = new MessageId(getRandomId());
Message m1 = new Message(mId1, groupId, timestamp, raw);
Message m2 = new Message(mId2, groupId, timestamp, raw);
Message m3 = new Message(mId3, groupId, timestamp, raw);
@@ -1443,7 +1442,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -1512,9 +1511,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test
public void testDifferentLocalAuthorsCanHaveTheSameContact()
throws Exception {
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
LocalAuthor localAuthor1 = new LocalAuthor(localAuthorId1, "Carol",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
LocalAuthor localAuthor1 = getLocalAuthor();
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
@@ -1525,15 +1522,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add the same contact for each local author
ContactId contactId =
db.addContact(txn, author, localAuthorId, true, true);
db.addContact(txn, author, localAuthor.getId(), true, true);
ContactId contactId1 =
db.addContact(txn, author, localAuthorId1, true, true);
db.addContact(txn, author, localAuthor1.getId(), true, true);
// The contacts should be distinct
assertNotEquals(contactId, contactId1);
assertEquals(2, db.getContacts(txn).size());
assertEquals(1, db.getContacts(txn, localAuthorId).size());
assertEquals(1, db.getContacts(txn, localAuthorId1).size());
assertEquals(1, db.getContacts(txn, localAuthor.getId()).size());
assertEquals(1, db.getContacts(txn, localAuthor1.getId()).size());
db.commitTransaction(txn);
db.close();
@@ -1546,7 +1543,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true);
@@ -1592,7 +1589,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Add a contact
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
true, true));
// The contact should be active

View File

@@ -10,8 +10,6 @@ import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.jmock.Expectations;
import org.junit.Test;
@@ -23,6 +21,8 @@ import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.Author.Status.UNKNOWN;
import static org.briarproject.bramble.api.identity.Author.Status.UNVERIFIED;
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.junit.Assert.assertEquals;
public class IdentityManagerImplTest extends BrambleMockTestCase {
@@ -30,11 +30,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
private final IdentityManager identityManager;
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final Transaction txn = new Transaction(null, false);
private final LocalAuthor localAuthor =
new LocalAuthor(new AuthorId(TestUtils.getRandomId()),
StringUtils.getRandomString(8),
TestUtils.getRandomBytes(42), TestUtils.getRandomBytes(42),
0);
private final LocalAuthor localAuthor = getLocalAuthor();
private final Collection<LocalAuthor> localAuthors =
Collections.singletonList(localAuthor);
@@ -80,7 +76,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
@Test
public void testGetAuthorStatus() throws DbException {
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
Author author = getAuthor();
AuthorId authorId = author.getId();
Collection<Contact> contacts = new ArrayList<>();
context.checking(new Expectations() {{
@@ -95,20 +92,16 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
assertEquals(UNKNOWN, identityManager.getAuthorStatus(authorId));
// add one unverified contact
Author author = new Author(authorId, StringUtils.getRandomString(8),
TestUtils.getRandomBytes(42));
Contact contact =
new Contact(new ContactId(1), author, localAuthor.getId(),
false, true);
Contact contact = new Contact(new ContactId(1), author,
localAuthor.getId(), false, true);
contacts.add(contact);
checkAuthorStatusContext(authorId, contacts);
assertEquals(UNVERIFIED, identityManager.getAuthorStatus(authorId));
// add one verified contact
Contact contact2 =
new Contact(new ContactId(1), author, localAuthor.getId(),
true, true);
Contact contact2 = new Contact(new ContactId(1), author,
localAuthor.getId(), true, true);
contacts.add(contact2);
checkAuthorStatusContext(authorId, contacts);

View File

@@ -11,8 +11,6 @@ import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties;
@@ -31,16 +29,15 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_VERSION;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -609,22 +606,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
return new Group(g, CLIENT_ID, descriptor);
}
private LocalAuthor getLocalAuthor() {
AuthorId id = new AuthorId(getRandomId());
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
long created = System.currentTimeMillis();
return new LocalAuthor(id, name, publicKey, privateKey, created);
}
private Contact getContact(boolean active) {
ContactId c = new ContactId(nextContactId++);
AuthorId a = new AuthorId(getRandomId());
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
return new Contact(c, new Author(a, name, publicKey),
localAuthor.getId(), true, active);
return new Contact(c, getAuthor(), localAuthor.getId(),
true, active);
}
private Message getMessage(GroupId g, long timestamp) {

View File

@@ -9,7 +9,10 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.StringUtils;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
public abstract class ValidatorTestCase extends BrambleMockTestCase {
@@ -21,16 +24,14 @@ public abstract class ValidatorTestCase extends BrambleMockTestCase {
protected final AuthorFactory authorFactory =
context.mock(AuthorFactory.class);
protected final MessageId messageId =
new MessageId(TestUtils.getRandomId());
protected final GroupId groupId = new GroupId(TestUtils.getRandomId());
protected final MessageId messageId = new MessageId(getRandomId());
protected final GroupId groupId = new GroupId(getRandomId());
protected final long timestamp = 1234567890 * 1000L;
protected final byte[] raw = TestUtils.getRandomBytes(123);
protected final byte[] raw = getRandomBytes(123);
protected final Message message =
new Message(messageId, groupId, timestamp, raw);
protected final ClientId clientId =
new ClientId(StringUtils.getRandomString(123));
protected final byte[] descriptor = TestUtils.getRandomBytes(123);
protected final ClientId clientId = new ClientId(getRandomString(123));
protected final byte[] descriptor = getRandomBytes(123);
protected final Group group = new Group(groupId, clientId, descriptor);
}

View File

@@ -23,8 +23,10 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Random;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
@@ -59,9 +61,7 @@ public class KeyManagerImplTest extends BrambleTestCase {
@Before
public void testStartService() throws Exception {
Transaction txn = new Transaction(null, false);
AuthorId remoteAuthorId = new AuthorId(getRandomId());
Author remoteAuthor = new Author(remoteAuthorId, "author",
getRandomBytes(42));
Author remoteAuthor = getAuthor();
AuthorId localAuthorId = new AuthorId(getRandomId());
Collection<Contact> contacts = new ArrayList<>();
contacts.add(new Contact(contactId, remoteAuthor, localAuthorId, true,
@@ -101,12 +101,12 @@ public class KeyManagerImplTest extends BrambleTestCase {
@Test
public void testAddContact() throws Exception {
SecretKey secretKey = getSecretKey();
long timestamp = 42L;
boolean alice = true;
long timestamp = System.currentTimeMillis();
boolean alice = new Random().nextBoolean();
context.checking(new Expectations() {{
oneOf(transportKeyManager)
.addContact(txn, contactId, secretKey, timestamp, alice);
oneOf(transportKeyManager).addContact(txn, contactId, secretKey,
timestamp, alice);
}});
keyManager.addContact(txn, contactId, secretKey, timestamp, alice);
@@ -121,8 +121,8 @@ public class KeyManagerImplTest extends BrambleTestCase {
@Test
public void testGetStreamContextForUnknownTransport() throws Exception {
assertEquals(null, keyManager
.getStreamContext(contactId, unknownTransportId));
assertEquals(null,
keyManager.getStreamContext(contactId, unknownTransportId));
}
@Test

View File

@@ -6,9 +6,7 @@ import junit.framework.Assert;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.briar.android.TestBriarApplication;
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.briar.android.threaded.ThreadItemAdapter;
@@ -29,7 +27,10 @@ import java.util.Arrays;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.briarproject.bramble.api.identity.Author.Status.UNKNOWN;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -38,30 +39,19 @@ import static org.mockito.Mockito.verify;
packageName = "org.briarproject.briar")
public class ForumActivityTest {
private final static String AUTHOR_1 = "Author 1";
private final static String AUTHOR_2 = "Author 2";
private final static String AUTHOR_3 = "Author 3";
private final static String AUTHOR_4 = "Author 4";
private final static String AUTHOR_5 = "Author 5";
private final static String AUTHOR_6 = "Author 6";
private final static String[] AUTHORS = {
AUTHOR_1, AUTHOR_2, AUTHOR_3, AUTHOR_4, AUTHOR_5, AUTHOR_6
};
private final static MessageId[] AUTHOR_IDS = new MessageId[AUTHORS.length];
private final static MessageId[] MESSAGE_IDS = new MessageId[6];
static {
for (int i = 0; i < AUTHOR_IDS.length; i++)
AUTHOR_IDS[i] = new MessageId(TestUtils.getRandomId());
for (int i = 0; i < MESSAGE_IDS.length; i++)
MESSAGE_IDS[i] = new MessageId(getRandomId());
}
private final static MessageId[] PARENT_AUTHOR_IDS = {
private final static MessageId[] PARENT_IDS = {
null,
AUTHOR_IDS[0],
AUTHOR_IDS[1],
AUTHOR_IDS[2],
AUTHOR_IDS[0],
MESSAGE_IDS[0],
MESSAGE_IDS[1],
MESSAGE_IDS[2],
MESSAGE_IDS[0],
null
};
@@ -86,7 +76,7 @@ public class ForumActivityTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
Intent intent = new Intent();
intent.putExtra("briar.GROUP_ID", TestUtils.getRandomId());
intent.putExtra("briar.GROUP_ID", getRandomId());
forumActivity = Robolectric.buildActivity(TestForumActivity.class,
intent).create().start().resume().get();
}
@@ -94,11 +84,10 @@ public class ForumActivityTest {
private ThreadItemList<ForumItem> getDummyData() {
ForumItem[] forumItems = new ForumItem[6];
for (int i = 0; i < forumItems.length; i++) {
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
Author author = new Author(authorId, AUTHORS[i], publicKey);
forumItems[i] = new ForumItem(AUTHOR_IDS[i], PARENT_AUTHOR_IDS[i],
AUTHORS[i], System.currentTimeMillis(), author, UNKNOWN);
Author author = getAuthor();
String content = getRandomString(MAX_FORUM_POST_BODY_LENGTH);
forumItems[i] = new ForumItem(MESSAGE_IDS[i], PARENT_IDS[i],
content, System.currentTimeMillis(), author, UNKNOWN);
forumItems[i].setLevel(LEVELS[i]);
}
ThreadItemList<ForumItem> list = new ThreadItemListImpl<>();

View File

@@ -25,6 +25,7 @@ public interface BlogConstants {
String KEY_TIMESTAMP = "timestamp";
String KEY_TIME_RECEIVED = "timeReceived";
String KEY_AUTHOR_ID = "id";
String KEY_FORMAT_VERSION = "formatVersion";
String KEY_AUTHOR_NAME = "name";
String KEY_PUBLIC_KEY = "publicKey";
String KEY_AUTHOR = "author";

View File

@@ -18,6 +18,7 @@ public interface FeedConstants {
// group metadata keys
String KEY_FEEDS = "feeds";
String KEY_FEED_URL = "feedURL";
String KEY_FORMAT_VERSION = "formatVersion";
String KEY_BLOG_TITLE = "blogTitle";
String KEY_PUBLIC_KEY = "publicKey";
String KEY_PRIVATE_KEY = "privateKey";

View File

@@ -14,27 +14,20 @@ public interface ForumConstants {
*/
int FORUM_SALT_LENGTH = 32;
/**
* The maximum length of a forum post's content type in UTF-8 bytes.
*/
int MAX_CONTENT_TYPE_LENGTH = 50;
/**
* The maximum length of a forum post's body in bytes.
*/
int MAX_FORUM_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
/* Forum Sharing Constants */
String FORUM_NAME = "forumName";
String FORUM_SALT = "forumSalt";
// Database keys
// Metadata keys
String KEY_TIMESTAMP = "timestamp";
String KEY_PARENT = "parent";
String KEY_ID = "id";
String KEY_NAME = "name";
String KEY_PUBLIC_NAME = "publicKey";
String KEY_AUTHOR = "author";
String KEY_ID = "id";
String KEY_FORMAT_VERSION = "formatVersion";
String KEY_NAME = "name";
String KEY_PUBLIC_KEY = "publicKey";
String KEY_LOCAL = "local";
String KEY_READ = "read";
}

View File

@@ -14,8 +14,7 @@ import org.briarproject.briar.api.blog.BlogFactory;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_VERSION;
@@ -48,11 +47,12 @@ class BlogFactoryImpl implements BlogFactory {
private Blog createBlog(Author a, boolean rssFeed) {
try {
BdfList blog = BdfList.of(
BdfList authorList = BdfList.of(
a.getFormatVersion(),
a.getName(),
a.getPublicKey(),
rssFeed
a.getPublicKey()
);
BdfList blog = BdfList.of(authorList, rssFeed);
byte[] descriptor = clientHelper.toByteArray(blog);
Group g = groupFactory.createGroup(CLIENT_ID, CLIENT_VERSION,
descriptor);
@@ -63,20 +63,15 @@ class BlogFactoryImpl implements BlogFactory {
}
@Override
public Blog parseBlog(Group group) throws FormatException {
byte[] descriptor = group.getDescriptor();
// Author name, public key, RSS feed
BdfList blog = clientHelper.toList(descriptor);
String name = blog.getString(0);
if (name.length() > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
byte[] publicKey = blog.getRaw(1);
if (publicKey.length > MAX_PUBLIC_KEY_LENGTH)
throw new IllegalArgumentException();
public Blog parseBlog(Group g) throws FormatException {
// Author, RSS feed
BdfList descriptor = clientHelper.toList(g.getDescriptor());
checkSize(descriptor, 2);
BdfList authorList = descriptor.getList(0);
boolean rssFeed = descriptor.getBoolean(1);
Author author = authorFactory.createAuthor(name, publicKey);
boolean rssFeed = blog.getBoolean(2);
return new Blog(group, author, rssFeed);
Author author = clientHelper.parseAndValidateAuthor(authorList);
return new Blog(g, author, rssFeed);
}
}

View File

@@ -49,10 +49,12 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.contact.ContactManager.RemoveContactHook;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
@@ -573,11 +575,13 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
long timestamp = meta.getLong(KEY_TIMESTAMP);
long timeReceived = meta.getLong(KEY_TIME_RECEIVED, timestamp);
BdfDictionary d = meta.getDictionary(KEY_AUTHOR);
AuthorId authorId = new AuthorId(d.getRaw(KEY_AUTHOR_ID));
String name = d.getString(KEY_AUTHOR_NAME);
byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY);
Author author = new Author(authorId, name, publicKey);
BdfDictionary authorDict = meta.getDictionary(KEY_AUTHOR);
AuthorId authorId = new AuthorId(authorDict.getRaw(KEY_AUTHOR_ID));
int formatVersion = authorDict.getLong(KEY_FORMAT_VERSION).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = authorDict.getString(KEY_AUTHOR_NAME);
byte[] publicKey = authorDict.getRaw(KEY_PUBLIC_KEY);
Author author = new Author(authorId, formatVersion, name, publicKey);
boolean isFeedPost = meta.getBoolean(KEY_RSS_FEED, false);
Status authorStatus;
if (isFeedPost) {

View File

@@ -34,6 +34,7 @@ import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
@@ -115,9 +116,8 @@ class BlogPostValidator extends BdfMessageValidator {
Blog b = blogFactory.parseBlog(g);
Author a = b.getAuthor();
try {
clientHelper
.verifySignature(SIGNING_LABEL_POST, sig, a.getPublicKey(),
signed);
clientHelper.verifySignature(SIGNING_LABEL_POST, sig,
a.getPublicKey(), signed);
} catch (GeneralSecurityException e) {
throw new InvalidMessageException(e);
}
@@ -156,10 +156,9 @@ class BlogPostValidator extends BdfMessageValidator {
// Signature
byte[] sig = body.getRaw(3);
checkLength(sig, 0, MAX_SIGNATURE_LENGTH);
BdfList signed =
BdfList.of(g.getId(), m.getTimestamp(), comment, pOriginalId,
currentId);
checkLength(sig, 1, MAX_SIGNATURE_LENGTH);
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), comment,
pOriginalId, currentId);
Blog b = blogFactory.parseBlog(g);
Author a = b.getAuthor();
try {
@@ -289,6 +288,7 @@ class BlogPostValidator extends BdfMessageValidator {
static BdfDictionary authorToBdfDictionary(Author a) {
return BdfDictionary.of(
new BdfEntry(KEY_AUTHOR_ID, a.getId()),
new BdfEntry(KEY_FORMAT_VERSION, a.getFormatVersion()),
new BdfEntry(KEY_AUTHOR_NAME, a.getName()),
new BdfEntry(KEY_PUBLIC_KEY, a.getPublicKey())
);

View File

@@ -17,7 +17,7 @@ import org.briarproject.briar.api.feed.Feed;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_NAME_LENGTH;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_BLOG_TITLE;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_ADDED;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_AUTHOR;
@@ -25,6 +25,7 @@ import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_DESC;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_LAST_ENTRY;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_UPDATED;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_PRIVATE_KEY;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_PUBLIC_KEY;
@@ -48,13 +49,12 @@ class FeedFactoryImpl implements FeedFactory {
public Feed createFeed(String url, SyndFeed syndFeed) {
String title = syndFeed.getTitle();
if (title == null) title = "RSS";
title = StringUtils.truncateUtf8(title, MAX_AUTHOR_NAME_LENGTH);
else title = StringUtils.truncateUtf8(title, MAX_BLOG_NAME_LENGTH);
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
LocalAuthor localAuthor = authorFactory
.createLocalAuthor(title,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
LocalAuthor localAuthor = authorFactory.createLocalAuthor(title,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
Blog blog = blogFactory.createFeedBlog(localAuthor);
long added = clock.currentTimeMillis();
@@ -73,11 +73,12 @@ class FeedFactoryImpl implements FeedFactory {
public Feed createFeed(BdfDictionary d) throws FormatException {
String url = d.getString(KEY_FEED_URL);
int formatVersion = d.getLong(KEY_FORMAT_VERSION).intValue();
String blogTitle = d.getString(KEY_BLOG_TITLE);
byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY);
byte[] privateKey = d.getRaw(KEY_PRIVATE_KEY);
LocalAuthor localAuthor = authorFactory
.createLocalAuthor(blogTitle, publicKey, privateKey);
LocalAuthor localAuthor = authorFactory.createLocalAuthor(
formatVersion, blogTitle, publicKey, privateKey);
Blog blog = blogFactory.createFeedBlog(localAuthor);
String desc = d.getOptionalString(KEY_FEED_DESC);
@@ -92,13 +93,14 @@ class FeedFactoryImpl implements FeedFactory {
@Override
public BdfDictionary feedToBdfDictionary(Feed feed) {
LocalAuthor localAuthor = feed.getLocalAuthor();
BdfDictionary d = BdfDictionary.of(
new BdfEntry(KEY_FEED_URL, feed.getUrl()),
new BdfEntry(KEY_BLOG_TITLE, feed.getLocalAuthor().getName()),
new BdfEntry(KEY_PUBLIC_KEY,
feed.getLocalAuthor().getPublicKey()),
new BdfEntry(KEY_PRIVATE_KEY,
feed.getLocalAuthor().getPrivateKey()),
new BdfEntry(KEY_FORMAT_VERSION,
localAuthor.getFormatVersion()),
new BdfEntry(KEY_BLOG_TITLE, localAuthor.getName()),
new BdfEntry(KEY_PUBLIC_KEY, localAuthor.getPublicKey()),
new BdfEntry(KEY_PRIVATE_KEY, localAuthor.getPrivateKey()),
new BdfEntry(KEY_FEED_ADDED, feed.getAdded()),
new BdfEntry(KEY_FEED_UPDATED, feed.getUpdated()),
new BdfEntry(KEY_FEED_LAST_ENTRY, feed.getLastEntryTime())

View File

@@ -31,7 +31,6 @@ class ForumFactoryImpl implements ForumFactory {
@Inject
ForumFactoryImpl(GroupFactory groupFactory, ClientHelper clientHelper,
SecureRandom random) {
this.groupFactory = groupFactory;
this.clientHelper = clientHelper;
this.random = random;

View File

@@ -45,13 +45,15 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_ID;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_LOCAL;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_NAME;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PUBLIC_NAME;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PUBLIC_KEY;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
@@ -149,8 +151,9 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
Author a = p.getAuthor();
BdfDictionary authorMeta = new BdfDictionary();
authorMeta.put(KEY_ID, a.getId());
authorMeta.put(KEY_FORMAT_VERSION, a.getFormatVersion());
authorMeta.put(KEY_NAME, a.getName());
authorMeta.put(KEY_PUBLIC_NAME, a.getPublicKey());
authorMeta.put(KEY_PUBLIC_KEY, a.getPublicKey());
meta.put(KEY_AUTHOR, authorMeta);
meta.put(KEY_LOCAL, true);
meta.put(MSG_KEY_READ, true);
@@ -300,9 +303,11 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
parentId = new MessageId(meta.getRaw(KEY_PARENT));
BdfDictionary authorDict = meta.getDictionary(KEY_AUTHOR);
AuthorId authorId = new AuthorId(authorDict.getRaw(KEY_ID));
int formatVersion = authorDict.getLong(KEY_FORMAT_VERSION).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = authorDict.getString(KEY_NAME);
byte[] publicKey = authorDict.getRaw(KEY_PUBLIC_NAME);
Author author = new Author(authorId, name, publicKey);
byte[] publicKey = authorDict.getRaw(KEY_PUBLIC_KEY);
Author author = new Author(authorId, formatVersion, name, publicKey);
Status status = statuses.get(authorId);
if (status == null)
status = identityManager.getAuthorStatus(txn, author.getId());

View File

@@ -2,16 +2,12 @@ package org.briarproject.briar.forum;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.sync.GroupFactory;
import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.forum.ForumFactory;
import org.briarproject.briar.api.forum.ForumManager;
import org.briarproject.briar.api.forum.ForumPostFactory;
import java.security.SecureRandom;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -34,10 +30,8 @@ public class ForumModule {
@Singleton
ForumManager provideForumManager(ForumManagerImpl forumManager,
ValidationManager validationManager) {
validationManager.registerIncomingMessageHook(CLIENT_ID,
forumManager);
return forumManager;
}
@@ -48,19 +42,17 @@ public class ForumModule {
}
@Provides
ForumFactory provideForumFactory(GroupFactory groupFactory,
ClientHelper clientHelper, SecureRandom random) {
return new ForumFactoryImpl(groupFactory, clientHelper, random);
ForumFactory provideForumFactory(ForumFactoryImpl forumFactory) {
return forumFactory;
}
@Provides
@Singleton
ForumPostValidator provideForumPostValidator(
ValidationManager validationManager, AuthorFactory authorFactory,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock) {
ForumPostValidator validator = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
ValidationManager validationManager, ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) {
ForumPostValidator validator = new ForumPostValidator(clientHelper,
metadataEncoder, clock);
validationManager.registerMessageValidator(CLIENT_ID, validator);
return validator;
}

View File

@@ -39,8 +39,11 @@ class ForumPostFactoryImpl implements ForumPostFactory {
if (StringUtils.utf8IsTooLong(body, MAX_FORUM_POST_BODY_LENGTH))
throw new IllegalArgumentException();
// Serialise the data to be signed
BdfList authorList =
BdfList.of(author.getName(), author.getPublicKey());
BdfList authorList = BdfList.of(
author.getFormatVersion(),
author.getName(),
author.getPublicKey()
);
BdfList signed = BdfList.of(groupId, timestamp, parent, authorList,
body);
// Sign the data

View File

@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.InvalidMessageException;
@@ -23,11 +22,17 @@ import java.util.Collections;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_ID;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_NAME;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PUBLIC_KEY;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_READ;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
import static org.briarproject.briar.api.forum.ForumPostFactory.SIGNING_LABEL_POST;
@@ -35,12 +40,9 @@ import static org.briarproject.briar.api.forum.ForumPostFactory.SIGNING_LABEL_PO
@NotNullByDefault
class ForumPostValidator extends BdfMessageValidator {
private final AuthorFactory authorFactory;
ForumPostValidator(AuthorFactory authorFactory, ClientHelper clientHelper,
ForumPostValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) {
super(clientHelper, metadataEncoder, clock);
this.authorFactory = authorFactory;
}
@Override
@@ -55,24 +57,18 @@ class ForumPostValidator extends BdfMessageValidator {
// Author
BdfList authorList = body.getList(1);
// Name, public key
checkSize(authorList, 2);
String name = authorList.getString(0);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = authorList.getRaw(1);
checkLength(publicKey, 0, MAX_PUBLIC_KEY_LENGTH);
Author author = authorFactory.createAuthor(name, publicKey);
Author author = clientHelper.parseAndValidateAuthor(authorList);
// Forum post body
String forumPostBody = body.getString(2);
checkLength(forumPostBody, 0, MAX_FORUM_POST_BODY_LENGTH);
String content = body.getString(2);
checkLength(content, 0, MAX_FORUM_POST_BODY_LENGTH);
// Signature
byte[] sig = body.getRaw(3);
checkLength(sig, 0, MAX_SIGNATURE_LENGTH);
checkLength(sig, 1, MAX_SIGNATURE_LENGTH);
// Verify the signature
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), parent,
authorList, forumPostBody);
authorList, content);
try {
clientHelper.verifySignature(SIGNING_LABEL_POST, sig,
author.getPublicKey(), signed);
@@ -83,17 +79,18 @@ class ForumPostValidator extends BdfMessageValidator {
// Return the metadata and dependencies
BdfDictionary meta = new BdfDictionary();
Collection<MessageId> dependencies = Collections.emptyList();
meta.put("timestamp", m.getTimestamp());
meta.put(KEY_TIMESTAMP, m.getTimestamp());
if (parent != null) {
meta.put("parent", parent);
meta.put(KEY_PARENT, parent);
dependencies = Collections.singletonList(new MessageId(parent));
}
BdfDictionary authorMeta = new BdfDictionary();
authorMeta.put("id", author.getId());
authorMeta.put("name", author.getName());
authorMeta.put("publicKey", author.getPublicKey());
meta.put("author", authorMeta);
meta.put("read", false);
authorMeta.put(KEY_ID, author.getId());
authorMeta.put(KEY_FORMAT_VERSION, author.getFormatVersion());
authorMeta.put(KEY_NAME, author.getName());
authorMeta.put(KEY_PUBLIC_KEY, author.getPublicKey());
meta.put(KEY_AUTHOR, authorMeta);
meta.put(KEY_READ, false);
return new BdfMessageContext(meta, dependencies);
}
}

View File

@@ -169,6 +169,7 @@ class IntroduceeManager {
d.put(ANSWERED, false);
// check if the contact we are introduced to does already exist
// TODO: Exchange author format version
AuthorId remoteAuthorId = authorFactory
.createAuthor(message.getString(NAME),
message.getRaw(PUBLIC_KEY)).getId();
@@ -339,6 +340,7 @@ class IntroduceeManager {
long timestamp = Math.min(ourTime, theirTime);
// Add the contact to the database as inactive
// TODO: Exchange author format version
Author remoteAuthor = authorFactory
.createAuthor(localState.getString(NAME),
localState.getRaw(PUBLIC_KEY));

View File

@@ -87,6 +87,8 @@ class IntroductionValidator extends BdfQueueMessageValidator {
checkSize(message, 4, 5);
// TODO: Exchange author format version
// parse contact name
String name = message.getString(2);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
@@ -131,7 +133,7 @@ class IntroductionValidator extends BdfQueueMessageValidator {
// parse ephemeral public key
pubkey = message.getRaw(4);
checkLength(pubkey, 0, MAX_PUBLIC_KEY_LENGTH);
checkLength(pubkey, 1, MAX_PUBLIC_KEY_LENGTH);
// parse transport properties
tp = message.getDictionary(5);

View File

@@ -4,13 +4,14 @@ import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ
interface GroupConstants {
// Database keys
// Metadata keys
String KEY_TYPE = "type";
String KEY_TIMESTAMP = "timestamp";
String KEY_READ = MSG_KEY_READ;
String KEY_PARENT_MSG_ID = "parentMsgId";
String KEY_PREVIOUS_MSG_ID = "previousMsgId";
String KEY_MEMBER_ID = "memberId";
String KEY_MEMBER_FORMAT_VERSION = "formatVersion";
String KEY_MEMBER_NAME = "memberName";
String KEY_MEMBER_PUBLIC_KEY = "memberPublicKey";
String KEY_INITIAL_JOIN_MSG = "initialJoinMsg";

View File

@@ -50,47 +50,73 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
LocalAuthor member, @Nullable BdfList invite) {
try {
// Generate the signature
int type = JOIN.getInt();
BdfList toSign = BdfList.of(groupId, timestamp, type,
member.getName(), member.getPublicKey(), invite);
byte[] memberSignature = clientHelper
.sign(SIGNING_LABEL_JOIN, toSign, member.getPrivateKey());
BdfList memberList = BdfList.of(
member.getFormatVersion(),
member.getName(),
member.getPublicKey()
);
BdfList toSign = BdfList.of(
groupId,
timestamp,
memberList,
invite
);
byte[] memberSignature = clientHelper.sign(SIGNING_LABEL_JOIN,
toSign, member.getPrivateKey());
// Compose the message
BdfList body =
BdfList.of(type, member.getName(),
member.getPublicKey(), invite, memberSignature);
BdfList body = BdfList.of(
JOIN.getInt(),
memberList,
invite,
memberSignature
);
Message m = clientHelper.createMessage(groupId, timestamp, body);
return new GroupMessage(m, null, member);
} catch (GeneralSecurityException | FormatException e) {
throw new RuntimeException(e);
} catch (GeneralSecurityException e) {
throw new IllegalArgumentException(e);
} catch (FormatException e) {
throw new AssertionError(e);
}
}
@Override
public GroupMessage createGroupMessage(GroupId groupId, long timestamp,
@Nullable MessageId parentId, LocalAuthor author, String content,
@Nullable MessageId parentId, LocalAuthor member, String content,
MessageId previousMsgId) {
try {
// Generate the signature
int type = POST.getInt();
BdfList toSign = BdfList.of(groupId, timestamp, type,
author.getName(), author.getPublicKey(), parentId,
previousMsgId, content);
byte[] signature = clientHelper
.sign(SIGNING_LABEL_POST, toSign, author.getPrivateKey());
BdfList memberList = BdfList.of(
member.getFormatVersion(),
member.getName(),
member.getPublicKey()
);
BdfList toSign = BdfList.of(
groupId,
timestamp,
memberList,
parentId,
previousMsgId,
content
);
byte[] signature = clientHelper.sign(SIGNING_LABEL_POST, toSign,
member.getPrivateKey());
// Compose the message
BdfList body =
BdfList.of(type, author.getName(),
author.getPublicKey(), parentId, previousMsgId,
content, signature);
BdfList body = BdfList.of(
POST.getInt(),
memberList,
parentId,
previousMsgId,
content,
signature
);
Message m = clientHelper.createMessage(groupId, timestamp, body);
return new GroupMessage(m, parentId, author);
} catch (GeneralSecurityException | FormatException e) {
throw new RuntimeException(e);
return new GroupMessage(m, parentId, member);
} catch (GeneralSecurityException e) {
throw new IllegalArgumentException(e);
} catch (FormatException e) {
throw new AssertionError(e);
}
}

View File

@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.InvalidMessageException;
@@ -25,8 +24,6 @@ import java.util.Collection;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
@@ -37,6 +34,7 @@ import static org.briarproject.briar.api.privategroup.MessageType.POST;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_FORMAT_VERSION;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_ID;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_NAME;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
@@ -51,16 +49,13 @@ import static org.briarproject.briar.privategroup.GroupConstants.KEY_TYPE;
class GroupMessageValidator extends BdfMessageValidator {
private final PrivateGroupFactory privateGroupFactory;
private final AuthorFactory authorFactory;
private final GroupInvitationFactory groupInvitationFactory;
GroupMessageValidator(PrivateGroupFactory privateGroupFactory,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock, AuthorFactory authorFactory,
GroupInvitationFactory groupInvitationFactory) {
Clock clock, GroupInvitationFactory groupInvitationFactory) {
super(clientHelper, metadataEncoder, clock);
this.privateGroupFactory = privateGroupFactory;
this.authorFactory = authorFactory;
this.groupInvitationFactory = groupInvitationFactory;
}
@@ -68,20 +63,15 @@ class GroupMessageValidator extends BdfMessageValidator {
protected BdfMessageContext validateMessage(Message m, Group g,
BdfList body) throws InvalidMessageException, FormatException {
checkSize(body, 5, 7);
checkSize(body, 4, 6);
// message type (int)
// Message type (int)
int type = body.getLong(0).intValue();
// member_name (string)
String memberName = body.getString(1);
checkLength(memberName, 1, MAX_AUTHOR_NAME_LENGTH);
// Member (list of int, string, raw)
BdfList memberList = body.getList(1);
Author member = clientHelper.parseAndValidateAuthor(memberList);
// member_public_key (raw)
byte[] memberPublicKey = body.getRaw(2);
checkLength(memberPublicKey, 1, MAX_PUBLIC_KEY_LENGTH);
Author member = authorFactory.createAuthor(memberName, memberPublicKey);
BdfMessageContext c;
if (type == JOIN.getInt()) {
c = validateJoin(m, g, body, member);
@@ -97,64 +87,54 @@ class GroupMessageValidator extends BdfMessageValidator {
}
private BdfMessageContext validateJoin(Message m, Group g, BdfList body,
Author member)
throws InvalidMessageException, FormatException {
Author member) throws FormatException {
// Message type, member, optional invite, member's signature
checkSize(body, 4);
BdfList inviteList = body.getOptionalList(2);
byte[] memberSignature = body.getRaw(3);
checkLength(memberSignature, 1, MAX_SIGNATURE_LENGTH);
// The content is a BDF list with five elements
checkSize(body, 5);
// Invite is null if the member is the creator of the private group
PrivateGroup pg = privateGroupFactory.parsePrivateGroup(g);
// invite is null if the member is the creator of the private group
Author creator = pg.getCreator();
boolean isCreator = false;
BdfList invite = body.getOptionalList(3);
if (invite == null) {
if (!member.equals(creator))
throw new InvalidMessageException();
isCreator = true;
boolean isCreator = member.equals(creator);
if (isCreator) {
if (inviteList != null) throw new FormatException();
} else {
if (member.equals(creator))
throw new InvalidMessageException();
// Otherwise invite is a list with two elements
checkSize(invite, 2);
// invite_timestamp (int)
// join_timestamp must be greater than invite_timestamp
long inviteTimestamp = invite.getLong(0);
if (inviteList == null) throw new FormatException();
// Timestamp, creator's signature
checkSize(inviteList, 2);
// Join timestamp must be greater than invite timestamp
long inviteTimestamp = inviteList.getLong(0);
if (m.getTimestamp() <= inviteTimestamp)
throw new InvalidMessageException();
// creator_signature (raw)
byte[] creatorSignature = invite.getRaw(1);
throw new FormatException();
byte[] creatorSignature = inviteList.getRaw(1);
checkLength(creatorSignature, 1, MAX_SIGNATURE_LENGTH);
// the invite token is signed by the creator of the private group
BdfList token = groupInvitationFactory
.createInviteToken(creator.getId(), member.getId(),
pg.getId(), inviteTimestamp);
// The invite token is signed by the creator of the private group
BdfList token = groupInvitationFactory.createInviteToken(
creator.getId(), member.getId(), g.getId(),
inviteTimestamp);
try {
clientHelper
.verifySignature(SIGNING_LABEL_INVITE, creatorSignature,
creator.getPublicKey(), token);
clientHelper.verifySignature(SIGNING_LABEL_INVITE,
creatorSignature, creator.getPublicKey(), token);
} catch (GeneralSecurityException e) {
throw new InvalidMessageException(e);
throw new FormatException();
}
}
// member_signature (raw)
// a signature with the member's private key over a list with 6 elements
byte[] memberSignature = body.getRaw(4);
checkLength(memberSignature, 1, MAX_SIGNATURE_LENGTH);
// Verify Signature
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), JOIN.getInt(),
member.getName(), member.getPublicKey(), invite);
// Verify the member's signature
BdfList memberList = body.getList(1); // Already validated
BdfList signed = BdfList.of(
g.getId(),
m.getTimestamp(),
memberList,
inviteList
);
try {
clientHelper.verifySignature(SIGNING_LABEL_JOIN, memberSignature,
member.getPublicKey(), signed);
} catch (GeneralSecurityException e) {
throw new InvalidMessageException(e);
throw new FormatException();
}
// Return the metadata and no dependencies
@@ -164,44 +144,38 @@ class GroupMessageValidator extends BdfMessageValidator {
}
private BdfMessageContext validatePost(Message m, Group g, BdfList body,
Author member)
throws InvalidMessageException, FormatException {
// The content is a BDF list with seven elements
checkSize(body, 7);
// parent_id (raw or null)
// the identifier of the post to which this is a reply, if any
byte[] parentId = body.getOptionalRaw(3);
Author member) throws FormatException {
// Message type, member, optional parent ID, previous message ID,
// content, signature
checkSize(body, 6);
byte[] parentId = body.getOptionalRaw(2);
checkLength(parentId, MessageId.LENGTH);
// previous_message_id (raw)
// the identifier of the member's previous post or join message
byte[] previousMessageId = body.getRaw(4);
byte[] previousMessageId = body.getRaw(3);
checkLength(previousMessageId, MessageId.LENGTH);
// content (string)
String content = body.getString(5);
String content = body.getString(4);
checkLength(content, 1, MAX_GROUP_POST_BODY_LENGTH);
// signature (raw)
// a signature with the member's private key over a list with 7 elements
byte[] signature = body.getRaw(6);
byte[] signature = body.getRaw(5);
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
// Verify Signature
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), POST.getInt(),
member.getName(), member.getPublicKey(), parentId,
previousMessageId, content);
// Verify the member's signature
BdfList memberList = body.getList(1); // Already validated
BdfList signed = BdfList.of(
g.getId(),
m.getTimestamp(),
memberList,
parentId,
previousMessageId,
content
);
try {
clientHelper.verifySignature(SIGNING_LABEL_POST, signature,
member.getPublicKey(), signed);
} catch (GeneralSecurityException e) {
throw new InvalidMessageException(e);
throw new FormatException();
}
// The parent post, if any,
// and the member's previous message are dependencies
// The parent post, if any, and the member's previous message are
// dependencies
Collection<MessageId> dependencies = new ArrayList<>();
if (parentId != null) dependencies.add(new MessageId(parentId));
dependencies.add(new MessageId(previousMessageId));
@@ -214,10 +188,12 @@ class GroupMessageValidator extends BdfMessageValidator {
}
private void addMessageMetadata(BdfMessageContext c, Author member,
long time) {
c.getDictionary().put(KEY_TIMESTAMP, time);
long timestamp) {
c.getDictionary().put(KEY_TIMESTAMP, timestamp);
c.getDictionary().put(KEY_READ, false);
c.getDictionary().put(KEY_MEMBER_ID, member.getId());
c.getDictionary().put(KEY_MEMBER_FORMAT_VERSION,
member.getFormatVersion());
c.getDictionary().put(KEY_MEMBER_NAME, member.getName());
c.getDictionary().put(KEY_MEMBER_PUBLIC_KEY, member.getPublicKey());
}

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupFactory;
@@ -17,6 +16,8 @@ import java.security.SecureRandom;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
@@ -28,27 +29,22 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
private final GroupFactory groupFactory;
private final ClientHelper clientHelper;
private final AuthorFactory authorFactory;
private final SecureRandom random;
@Inject
PrivateGroupFactoryImpl(GroupFactory groupFactory,
ClientHelper clientHelper, AuthorFactory authorFactory,
SecureRandom random) {
ClientHelper clientHelper, SecureRandom random) {
this.groupFactory = groupFactory;
this.clientHelper = clientHelper;
this.authorFactory = authorFactory;
this.random = random;
}
@Override
public PrivateGroup createPrivateGroup(String name, Author author) {
int length = StringUtils.toUtf8(name).length;
if (length == 0) throw new IllegalArgumentException("Group name empty");
if (length > MAX_GROUP_NAME_LENGTH)
throw new IllegalArgumentException(
"Group name exceeds maximum length");
if (length == 0 || length > MAX_GROUP_NAME_LENGTH)
throw new IllegalArgumentException();
byte[] salt = new byte[GROUP_SALT_LENGTH];
random.nextBytes(salt);
return createPrivateGroup(name, author, salt);
@@ -58,12 +54,12 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
public PrivateGroup createPrivateGroup(String name, Author author,
byte[] salt) {
try {
BdfList group = BdfList.of(
name,
BdfList creatorList = BdfList.of(
author.getFormatVersion(),
author.getName(),
author.getPublicKey(),
salt
author.getPublicKey()
);
BdfList group = BdfList.of(creatorList, name, salt);
byte[] descriptor = clientHelper.toByteArray(group);
Group g = groupFactory.createGroup(CLIENT_ID, CLIENT_VERSION,
descriptor);
@@ -74,12 +70,18 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
}
@Override
public PrivateGroup parsePrivateGroup(Group group) throws FormatException {
byte[] descriptor = group.getDescriptor();
BdfList list = clientHelper.toList(descriptor);
Author a =
authorFactory.createAuthor(list.getString(1), list.getRaw(2));
return new PrivateGroup(group, list.getString(0), a, list.getRaw(3));
public PrivateGroup parsePrivateGroup(Group g) throws FormatException {
// Creator, group name, salt
BdfList descriptor = clientHelper.toList(g.getDescriptor());
checkSize(descriptor, 3);
BdfList creatorList = descriptor.getList(0);
String groupName = descriptor.getString(1);
checkLength(groupName, 1, MAX_GROUP_NAME_LENGTH);
byte[] salt = descriptor.getRaw(2);
checkLength(salt, GROUP_SALT_LENGTH);
Author creator = clientHelper.parseAndValidateAuthor(creatorList);
return new PrivateGroup(g, groupName, creator, salt);
}
}

View File

@@ -54,6 +54,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.Author.Status.UNVERIFIED;
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
@@ -69,6 +70,7 @@ import static org.briarproject.briar.privategroup.GroupConstants.GROUP_KEY_MEMBE
import static org.briarproject.briar.privategroup.GroupConstants.GROUP_KEY_OUR_GROUP;
import static org.briarproject.briar.privategroup.GroupConstants.GROUP_KEY_VISIBILITY;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_FORMAT_VERSION;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_ID;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_NAME;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
@@ -139,7 +141,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TYPE, JOIN.getInt());
meta.put(KEY_INITIAL_JOIN_MSG, creator);
addMessageMetadata(meta, m, true);
addMessageMetadata(meta, m);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
messageTracker.trackOutgoingMessage(txn, m.getMessage());
addMember(txn, m.getMessage().getGroupId(), m.getMember(), VISIBLE);
@@ -217,7 +219,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
meta.put(KEY_TYPE, POST.getInt());
if (m.getParent() != null)
meta.put(KEY_PARENT_MSG_ID, m.getParent());
addMessageMetadata(meta, m, true);
addMessageMetadata(meta, m);
GroupId g = m.getMessage().getGroupId();
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
@@ -239,11 +241,11 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
m.getMessage().getTimestamp(), m.getMember(), OURSELVES, true);
}
private void addMessageMetadata(BdfDictionary meta, GroupMessage m,
boolean read) {
private void addMessageMetadata(BdfDictionary meta, GroupMessage m) {
meta.put(KEY_TIMESTAMP, m.getMessage().getTimestamp());
meta.put(KEY_READ, read);
meta.put(KEY_READ, true);
meta.put(KEY_MEMBER_ID, m.getMember().getId());
meta.put(KEY_MEMBER_FORMAT_VERSION, m.getMember().getFormatVersion());
meta.put(KEY_MEMBER_NAME, m.getMember().getName());
meta.put(KEY_MEMBER_PUBLIC_KEY, m.getMember().getPublicKey());
}
@@ -316,9 +318,9 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
}
private String getMessageBody(BdfList body) throws FormatException {
// type(0), member_name(1), member_public_key(2), parent_id(3),
// previous_message_id(4), content(5), signature(6)
return body.getString(5);
// Message type (0), member (1), parent ID (2), previous message ID (3),
// content (4), signature (5)
return body.getString(4);
}
@Override
@@ -604,6 +606,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
BdfList members = meta.getList(GROUP_KEY_MEMBERS);
members.add(BdfDictionary.of(
new BdfEntry(KEY_MEMBER_ID, a.getId()),
new BdfEntry(KEY_MEMBER_FORMAT_VERSION, a.getFormatVersion()),
new BdfEntry(KEY_MEMBER_NAME, a.getName()),
new BdfEntry(KEY_MEMBER_PUBLIC_KEY, a.getPublicKey()),
new BdfEntry(GROUP_KEY_VISIBILITY, v.getInt())
@@ -616,9 +619,11 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
private Author getAuthor(BdfDictionary meta) throws FormatException {
AuthorId authorId = new AuthorId(meta.getRaw(KEY_MEMBER_ID));
int formatVersion = meta.getLong(KEY_MEMBER_FORMAT_VERSION).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = meta.getString(KEY_MEMBER_NAME);
byte[] publicKey = meta.getRaw(KEY_MEMBER_PUBLIC_KEY);
return new Author(authorId, name, publicKey);
return new Author(authorId, formatVersion, name, publicKey);
}
private Visibility getVisibility(BdfDictionary meta)

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.privategroup;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
@@ -54,12 +53,11 @@ public class PrivateGroupModule {
GroupMessageValidator provideGroupMessageValidator(
PrivateGroupFactory privateGroupFactory,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock, AuthorFactory authorFactory,
GroupInvitationFactory groupInvitationFactory,
Clock clock, GroupInvitationFactory groupInvitationFactory,
ValidationManager validationManager) {
GroupMessageValidator validator = new GroupMessageValidator(
privateGroupFactory, clientHelper, metadataEncoder, clock,
authorFactory, groupInvitationFactory);
groupInvitationFactory);
validationManager.registerMessageValidator(CLIENT_ID, validator);
return validator;
}

View File

@@ -140,10 +140,10 @@ abstract class AbstractProtocolEngine<S extends Session>
return m;
}
void markMessageVisibleInUi(Transaction txn, MessageId m, boolean visible)
void markMessageVisibleInUi(Transaction txn, MessageId m)
throws DbException {
BdfDictionary meta = new BdfDictionary();
messageEncoder.setVisibleInUi(meta, visible);
messageEncoder.setVisibleInUi(meta, true);
try {
clientHelper.mergeMessageMetadata(txn, m, meta);
} catch (FormatException e) {
@@ -174,10 +174,9 @@ abstract class AbstractProtocolEngine<S extends Session>
markMessageAvailableToAnswer(txn, m, false);
}
void markInviteAccepted(Transaction txn, MessageId m, boolean accepted)
throws DbException {
void markInviteAccepted(Transaction txn, MessageId m) throws DbException {
BdfDictionary meta = new BdfDictionary();
messageEncoder.setInvitationAccepted(meta, accepted);
messageEncoder.setInvitationAccepted(meta, true);
try {
clientHelper.mergeMessageMetadata(txn, m, meta);
} catch (FormatException e) {

View File

@@ -183,7 +183,7 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
// Send a JOIN message
Message sent = sendJoinMessage(txn, s, false);
// Mark the response visible in the UI
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),
m.getTimestamp(), false);
@@ -207,7 +207,7 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
if (!isValidDependency(s, m.getPreviousMessageId()))
return abort(txn, s);
// Mark the response visible in the UI
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),
m.getTimestamp(), false);

View File

@@ -3,7 +3,6 @@ package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.system.Clock;
@@ -53,13 +52,12 @@ public class GroupInvitationModule {
@Singleton
GroupInvitationValidator provideGroupInvitationValidator(
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock, AuthorFactory authorFactory,
PrivateGroupFactory privateGroupFactory,
Clock clock, PrivateGroupFactory privateGroupFactory,
MessageEncoder messageEncoder,
ValidationManager validationManager) {
GroupInvitationValidator validator = new GroupInvitationValidator(
clientHelper, metadataEncoder, clock, authorFactory,
privateGroupFactory, messageEncoder);
clientHelper, metadataEncoder, clock, privateGroupFactory,
messageEncoder);
validationManager.registerMessageValidator(CLIENT_ID, validator);
return validator;
}

View File

@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
@@ -23,10 +22,7 @@ import java.security.GeneralSecurityException;
import java.util.Collections;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
@@ -43,18 +39,14 @@ import static org.briarproject.briar.privategroup.invitation.MessageType.LEAVE;
@NotNullByDefault
class GroupInvitationValidator extends BdfMessageValidator {
private final AuthorFactory authorFactory;
private final PrivateGroupFactory privateGroupFactory;
private final MessageEncoder messageEncoder;
@Inject
GroupInvitationValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock,
AuthorFactory authorFactory,
PrivateGroupFactory privateGroupFactory,
MessageEncoder messageEncoder) {
super(clientHelper, metadataEncoder, clock);
this.authorFactory = authorFactory;
this.privateGroupFactory = privateGroupFactory;
this.messageEncoder = messageEncoder;
}
@@ -79,22 +71,20 @@ class GroupInvitationValidator extends BdfMessageValidator {
private BdfMessageContext validateInviteMessage(Message m, BdfList body)
throws FormatException {
checkSize(body, 7);
String groupName = body.getString(1);
// Message type, creator, group name, salt, optional message, signature
checkSize(body, 6);
BdfList creatorList = body.getList(1);
String groupName = body.getString(2);
checkLength(groupName, 1, MAX_GROUP_NAME_LENGTH);
String creatorName = body.getString(2);
checkLength(creatorName, 1, MAX_AUTHOR_NAME_LENGTH);
byte[] creatorPublicKey = body.getRaw(3);
checkLength(creatorPublicKey, 1, MAX_PUBLIC_KEY_LENGTH);
byte[] salt = body.getRaw(4);
byte[] salt = body.getRaw(3);
checkLength(salt, GROUP_SALT_LENGTH);
String message = body.getOptionalString(5);
String message = body.getOptionalString(4);
checkLength(message, 1, MAX_GROUP_INVITATION_MSG_LENGTH);
byte[] signature = body.getRaw(6);
byte[] signature = body.getRaw(5);
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
// Create the private group
Author creator = authorFactory.createAuthor(creatorName,
creatorPublicKey);
// Validate the creator and create the private group
Author creator = clientHelper.parseAndValidateAuthor(creatorList);
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
groupName, creator, salt);
// Verify the signature
@@ -105,7 +95,7 @@ class GroupInvitationValidator extends BdfMessageValidator {
);
try {
clientHelper.verifySignature(SIGNING_LABEL_INVITE, signature,
creatorPublicKey, signed);
creator.getPublicKey(), signed);
} catch (GeneralSecurityException e) {
throw new FormatException();
}

View File

@@ -173,7 +173,7 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
if (inviteId == null) throw new IllegalStateException();
markMessageAvailableToAnswer(txn, inviteId, false);
// Record the response
markInviteAccepted(txn, inviteId, true);
markInviteAccepted(txn, inviteId);
// Send a JOIN message
Message sent = sendJoinMessage(txn, s, true);
// Track the message
@@ -228,7 +228,7 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
if (!contact.getId().equals(m.getCreator().getId()))
return abort(txn, s);
// Mark the invite message visible in the UI and available to answer
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
markMessageAvailableToAnswer(txn, m.getId(), true);
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),

View File

@@ -78,11 +78,15 @@ class MessageEncoderImpl implements MessageEncoder {
GroupId privateGroupId, long timestamp, String groupName,
Author creator, byte[] salt, @Nullable String message,
byte[] signature) {
BdfList creatorList = BdfList.of(
creator.getFormatVersion(),
creator.getName(),
creator.getPublicKey()
);
BdfList body = BdfList.of(
INVITE.getValue(),
creatorList,
groupName,
creator.getName(),
creator.getPublicKey(),
salt,
message,
signature

View File

@@ -19,6 +19,7 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_INVITATION_ACCEPTED;
@@ -39,7 +40,8 @@ class MessageParserImpl implements MessageParser {
@Inject
MessageParserImpl(AuthorFactory authorFactory,
PrivateGroupFactory privateGroupFactory, ClientHelper clientHelper) {
PrivateGroupFactory privateGroupFactory,
ClientHelper clientHelper) {
this.authorFactory = authorFactory;
this.privateGroupFactory = privateGroupFactory;
this.clientHelper = clientHelper;
@@ -97,13 +99,20 @@ class MessageParserImpl implements MessageParser {
@Override
public InviteMessage parseInviteMessage(Message m, BdfList body)
throws FormatException {
String groupName = body.getString(1);
String creatorName = body.getString(2);
byte[] creatorPublicKey = body.getRaw(3);
byte[] salt = body.getRaw(4);
String message = body.getOptionalString(5);
byte[] signature = body.getRaw(6);
Author creator = authorFactory.createAuthor(creatorName,
// Message type, creator, group name, salt, optional message, signature
BdfList creatorList = body.getList(1);
String groupName = body.getString(2);
byte[] salt = body.getRaw(3);
String message = body.getOptionalString(4);
byte[] signature = body.getRaw(5);
// Format version, name, public key
int formatVersion = creatorList.getLong(0).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String creatorName = creatorList.getString(1);
byte[] creatorPublicKey = creatorList.getRaw(2);
Author creator = authorFactory.createAuthor(formatVersion, creatorName,
creatorPublicKey);
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
groupName, creator, salt);

View File

@@ -12,6 +12,8 @@ import org.briarproject.briar.api.blog.BlogFactory;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
@Immutable
@NotNullByDefault
class BlogMessageParserImpl extends MessageParserImpl<Blog> {
@@ -28,12 +30,19 @@ class BlogMessageParserImpl extends MessageParserImpl<Blog> {
}
@Override
protected Blog createShareable(BdfList descriptor)
throws FormatException {
String name = descriptor.getString(0);
byte[] publicKey = descriptor.getRaw(1);
boolean rssFeed = descriptor.getBoolean(2);
Author author = authorFactory.createAuthor(name, publicKey);
protected Blog createShareable(BdfList descriptor) throws FormatException {
// Author, RSS
BdfList authorList = descriptor.getList(0);
boolean rssFeed = descriptor.getBoolean(1);
// Format version, name, public key
int formatVersion = authorList.getLong(0).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = authorList.getString(1);
byte[] publicKey = authorList.getRaw(2);
Author author = authorFactory.createAuthor(formatVersion, name,
publicKey);
if (rssFeed) return blogFactory.createFeedBlog(author);
else return blogFactory.createBlog(author);
}

View File

@@ -5,19 +5,13 @@ import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogFactory;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
@Immutable
@@ -25,35 +19,24 @@ import static org.briarproject.bramble.util.ValidationUtils.checkSize;
class BlogSharingValidator extends SharingValidator {
private final BlogFactory blogFactory;
private final AuthorFactory authorFactory;
@Inject
BlogSharingValidator(MessageEncoder messageEncoder,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock, BlogFactory blogFactory, AuthorFactory authorFactory) {
Clock clock, BlogFactory blogFactory) {
super(messageEncoder, clientHelper, metadataEncoder, clock);
this.blogFactory = blogFactory;
this.authorFactory = authorFactory;
}
@Override
protected GroupId validateDescriptor(BdfList descriptor)
throws FormatException {
checkSize(descriptor, 3);
String name = descriptor.getString(0);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = descriptor.getRaw(1);
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
boolean rssFeed = descriptor.getBoolean(2);
Author author = authorFactory.createAuthor(name, publicKey);
Blog blog;
if (rssFeed) {
blog = blogFactory.createFeedBlog(author);
} else {
blog = blogFactory.createBlog(author);
}
return blog.getId();
// Author, RSS
checkSize(descriptor, 2);
BdfList authorList = descriptor.getList(0);
boolean rssFeed = descriptor.getBoolean(1);
Author author = clientHelper.parseAndValidateAuthor(authorList);
if (rssFeed) return blogFactory.createFeedBlog(author).getId();
else return blogFactory.createBlog(author).getId();
}
}

View File

@@ -24,8 +24,8 @@ class ForumMessageParserImpl extends MessageParserImpl<Forum> {
}
@Override
protected Forum createShareable(BdfList descriptor)
throws FormatException {
protected Forum createShareable(BdfList descriptor) throws FormatException {
// Name, salt
String name = descriptor.getString(0);
byte[] salt = descriptor.getRaw(1);
return forumFactory.createForum(name, salt);

View File

@@ -35,6 +35,7 @@ class ForumSharingValidator extends SharingValidator {
@Override
protected GroupId validateDescriptor(BdfList descriptor)
throws FormatException {
// Name, salt
checkSize(descriptor, 2);
String name = descriptor.getString(0);
checkLength(name, 1, MAX_FORUM_NAME_LENGTH);

View File

@@ -112,9 +112,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
throw new DbException(e); // Invalid group descriptor
}
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
Message m = messageEncoder
.encodeInviteMessage(s.getContactGroupId(), localTimestamp,
s.getLastLocalMessageId(), descriptor, message);
Message m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
localTimestamp, s.getLastLocalMessageId(), descriptor, message);
sendMessage(txn, m, INVITE, s.getShareableId(), true);
return m;
}
@@ -143,7 +142,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (inviteId == null) throw new IllegalStateException();
markMessageAvailableToAnswer(txn, inviteId, false);
// Mark the invite message as accepted
markInvitationAccepted(txn, inviteId, true);
markInvitationAccepted(txn, inviteId);
// Send a ACCEPT message
Message sent = sendAcceptMessage(txn, s);
// Track the message
@@ -288,7 +287,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (!isValidDependency(s, m.getPreviousMessageId()))
return abortWithMessage(txn, s);
// Mark the invite message visible in the UI and (un)available to answer
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
markMessageAvailableToAnswer(txn, m.getId(), available);
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),
@@ -312,7 +311,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (!isValidDependency(s, m.getPreviousMessageId()))
return abortWithMessage(txn, s);
// Mark the invite message visible in the UI and unavailable to answer
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
markMessageAvailableToAnswer(txn, m.getId(), false);
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),
@@ -359,7 +358,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (!isValidDependency(s, m.getPreviousMessageId()))
return abortWithMessage(txn, s);
// Mark the response visible in the UI
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),
m.getTimestamp(), false);
@@ -411,7 +410,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (!isValidDependency(s, m.getPreviousMessageId()))
return abortWithMessage(txn, s);
// Mark the response visible in the UI
markMessageVisibleInUi(txn, m.getId(), true);
markMessageVisibleInUi(txn, m.getId());
// Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(),
m.getTimestamp(), false);
@@ -576,10 +575,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
}
}
private void markMessageVisibleInUi(Transaction txn, MessageId m,
boolean visible) throws DbException {
private void markMessageVisibleInUi(Transaction txn, MessageId m)
throws DbException {
BdfDictionary meta = new BdfDictionary();
messageEncoder.setVisibleInUi(meta, visible);
messageEncoder.setVisibleInUi(meta, true);
try {
clientHelper.mergeMessageMetadata(txn, m, meta);
} catch (FormatException e) {
@@ -587,10 +586,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
}
}
private void markInvitationAccepted(Transaction txn, MessageId m,
boolean accepted) throws DbException {
private void markInvitationAccepted(Transaction txn, MessageId m)
throws DbException {
BdfDictionary meta = new BdfDictionary();
messageEncoder.setInvitationAccepted(meta, accepted);
messageEncoder.setInvitationAccepted(meta, true);
try {
clientHelper.mergeMessageMetadata(txn, m, meta);
} catch (FormatException e) {

View File

@@ -3,7 +3,6 @@ package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.system.Clock;
@@ -59,10 +58,10 @@ public class SharingModule {
BlogSharingValidator provideBlogSharingValidator(
ValidationManager validationManager, MessageEncoder messageEncoder,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock, BlogFactory blogFactory, AuthorFactory authorFactory) {
Clock clock, BlogFactory blogFactory) {
BlogSharingValidator validator =
new BlogSharingValidator(messageEncoder, clientHelper,
metadataEncoder, clock, blogFactory, authorFactory);
metadataEncoder, clock, blogFactory);
validationManager.registerMessageValidator(BlogSharingManager.CLIENT_ID,
validator);
return validator;

View File

@@ -190,8 +190,8 @@ public class TestDataCreatorImpl implements TestDataCreator {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();
return authorFactory
.createLocalAuthor(authorName, publicKey, privateKey);
return authorFactory.createLocalAuthor(authorName, publicKey,
privateKey);
}
private SecretKey getSecretKey() {

View File

@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.Group;
@@ -34,9 +33,8 @@ import org.junit.Test;
import static org.briarproject.bramble.api.identity.Author.Status.NONE;
import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -44,6 +42,7 @@ import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
@@ -89,9 +88,9 @@ public class BlogManagerImplTest extends BriarTestCase {
blogManager = new BlogManagerImpl(db, identityManager, clientHelper,
metadataParser, blogFactory, blogPostFactory);
localAuthor1 = createLocalAuthor();
localAuthor2 = createLocalAuthor();
rssLocalAuthor = createLocalAuthor();
localAuthor1 = getLocalAuthor();
localAuthor2 = getLocalAuthor();
rssLocalAuthor = getLocalAuthor();
authorDict1 = authorToBdfDictionary(localAuthor1);
authorDict2 = authorToBdfDictionary(localAuthor2);
rssAuthorDict = authorToBdfDictionary(rssLocalAuthor);
@@ -822,13 +821,6 @@ public class BlogManagerImplTest extends BriarTestCase {
context.assertIsSatisfied();
}
private LocalAuthor createLocalAuthor() {
return new LocalAuthor(new AuthorId(getRandomId()),
getRandomString(MAX_AUTHOR_NAME_LENGTH),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
getRandomBytes(123), System.currentTimeMillis());
}
private Blog createBlog(LocalAuthor localAuthor, boolean rssFeed) {
GroupId groupId = new GroupId(getRandomId());
Group group = new Group(groupId, CLIENT_ID, getRandomBytes(42));
@@ -838,6 +830,7 @@ public class BlogManagerImplTest extends BriarTestCase {
private BdfDictionary authorToBdfDictionary(Author a) {
return BdfDictionary.of(
new BdfEntry(KEY_AUTHOR_ID, a.getId()),
new BdfEntry(KEY_FORMAT_VERSION, a.getFormatVersion()),
new BdfEntry(KEY_AUTHOR_NAME, a.getName()),
new BdfEntry(KEY_PUBLIC_KEY, a.getPublicKey())
);

View File

@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupFactory;
import org.briarproject.bramble.api.sync.GroupId;
@@ -16,8 +15,6 @@ import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.system.SystemClock;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogFactory;
import org.briarproject.briar.test.BriarTestCase;
@@ -28,11 +25,15 @@ import org.junit.Test;
import java.io.IOException;
import java.security.GeneralSecurityException;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
@@ -65,27 +66,25 @@ public class BlogPostValidatorTest extends BriarTestCase {
private final BlogFactory blogFactory = context.mock(BlogFactory.class);
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final Author author;
private final String body = StringUtils.getRandomString(42);
private final String body = getRandomString(42);
public BlogPostValidatorTest() {
GroupId groupId = new GroupId(TestUtils.getRandomId());
descriptor = TestUtils.getRandomBytes(42);
GroupId groupId = new GroupId(getRandomId());
descriptor = getRandomBytes(42);
group = new Group(groupId, CLIENT_ID, descriptor);
AuthorId authorId =
new AuthorId(TestUtils.getRandomBytes(AuthorId.LENGTH));
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
author = new Author(authorId, "Author", publicKey);
author = getAuthor();
authorDict = BdfDictionary.of(
new BdfEntry(KEY_AUTHOR_ID, author.getId()),
new BdfEntry(KEY_FORMAT_VERSION, author.getFormatVersion()),
new BdfEntry(KEY_AUTHOR_NAME, author.getName()),
new BdfEntry(KEY_PUBLIC_KEY, author.getPublicKey())
);
blog = new Blog(group, author, false);
rssBlog = new Blog(group, author, true);
MessageId messageId = new MessageId(TestUtils.getRandomId());
MessageId messageId = new MessageId(getRandomId());
long timestamp = System.currentTimeMillis();
byte[] raw = TestUtils.getRandomBytes(123);
byte[] raw = getRandomBytes(123);
message = new Message(messageId, group.getId(), timestamp, raw);
MetadataEncoder metadataEncoder = context.mock(MetadataEncoder.class);
@@ -110,7 +109,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
private void testValidateProperBlogPost(Blog b, boolean rssFeed)
throws IOException, GeneralSecurityException {
byte[] sigBytes = TestUtils.getRandomBytes(42);
byte[] sigBytes = getRandomBytes(42);
BdfList m = BdfList.of(POST.getInt(), body, sigBytes);
BdfList signed = BdfList.of(b.getId(), message.getTimestamp(), body);
@@ -147,9 +146,9 @@ public class BlogPostValidatorTest extends BriarTestCase {
throws IOException, GeneralSecurityException {
// comment, parent_original_id, parent_id, signature
String comment = "This is a blog comment";
MessageId pOriginalId = new MessageId(TestUtils.getRandomId());
MessageId currentId = new MessageId(TestUtils.getRandomId());
byte[] sigBytes = TestUtils.getRandomBytes(42);
MessageId pOriginalId = new MessageId(getRandomId());
MessageId currentId = new MessageId(getRandomId());
byte[] sigBytes = getRandomBytes(42);
BdfList m = BdfList.of(COMMENT.getInt(), comment, pOriginalId,
currentId, sigBytes);
@@ -172,9 +171,9 @@ public class BlogPostValidatorTest extends BriarTestCase {
public void testValidateProperEmptyBlogComment()
throws IOException, GeneralSecurityException {
// comment, parent_original_id, signature, parent_current_id
MessageId originalId = new MessageId(TestUtils.getRandomId());
MessageId currentId = new MessageId(TestUtils.getRandomId());
byte[] sigBytes = TestUtils.getRandomBytes(42);
MessageId originalId = new MessageId(getRandomId());
MessageId currentId = new MessageId(getRandomId());
byte[] sigBytes = getRandomBytes(42);
BdfList m = BdfList.of(COMMENT.getInt(), null, originalId, currentId,
sigBytes);
@@ -203,7 +202,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
private void testValidateProperWrappedPost(Blog b, boolean rssFeed)
throws IOException, GeneralSecurityException {
// group descriptor, timestamp, content, signature
byte[] sigBytes = TestUtils.getRandomBytes(42);
byte[] sigBytes = getRandomBytes(42);
BdfList m = BdfList.of(WRAPPED_POST.getInt(), descriptor,
message.getTimestamp(), body, sigBytes);
@@ -211,7 +210,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
expectCrypto(b, SIGNING_LABEL_POST, signed, sigBytes);
BdfList originalList = BdfList.of(POST.getInt(), body, sigBytes);
byte[] originalBody = TestUtils.getRandomBytes(42);
byte[] originalBody = getRandomBytes(42);
context.checking(new Expectations() {{
oneOf(groupFactory).createGroup(CLIENT_ID, CLIENT_VERSION,
@@ -241,10 +240,10 @@ public class BlogPostValidatorTest extends BriarTestCase {
// group descriptor, timestamp, comment, parent_original_id, signature,
// parent_current_id
String comment = "This is another comment";
MessageId originalId = new MessageId(TestUtils.getRandomId());
MessageId oldId = new MessageId(TestUtils.getRandomId());
byte[] sigBytes = TestUtils.getRandomBytes(42);
MessageId currentId = new MessageId(TestUtils.getRandomId());
MessageId originalId = new MessageId(getRandomId());
MessageId oldId = new MessageId(getRandomId());
byte[] sigBytes = getRandomBytes(42);
MessageId currentId = new MessageId(getRandomId());
BdfList m = BdfList.of(WRAPPED_COMMENT.getInt(), descriptor,
message.getTimestamp(), comment, originalId, oldId, sigBytes,
currentId);
@@ -255,7 +254,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
BdfList originalList = BdfList.of(COMMENT.getInt(), comment,
originalId, oldId, sigBytes);
byte[] originalBody = TestUtils.getRandomBytes(42);
byte[] originalBody = getRandomBytes(42);
context.checking(new Expectations() {{
oneOf(groupFactory).createGroup(CLIENT_ID, CLIENT_VERSION,

View File

@@ -10,7 +10,6 @@ import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
@@ -38,6 +37,7 @@ import javax.net.SocketFactory;
import okhttp3.Dns;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEEDS;
@@ -66,10 +66,7 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
private final GroupId blogGroupId = new GroupId(getRandomId());
private final Group blogGroup =
new Group(blogGroupId, BlogManager.CLIENT_ID, getRandomBytes(42));
private final AuthorId authorId = new AuthorId(getRandomId());
private final LocalAuthor localAuthor =
new LocalAuthor(authorId, "author", getRandomBytes(2),
getRandomBytes(2), 0);
private final LocalAuthor localAuthor = getLocalAuthor();
private final Blog blog = new Blog(blogGroup, localAuthor, true);
private final Feed feed =
new Feed("http://example.org", blog, localAuthor, 0);

View File

@@ -6,21 +6,28 @@ import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.test.ValidatorTestCase;
import org.briarproject.bramble.util.StringUtils;
import org.jmock.Expectations;
import org.junit.Test;
import java.security.GeneralSecurityException;
import java.util.Collection;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.blog.BlogConstants.KEY_READ;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_FORMAT_VERSION;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_ID;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_NAME;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PUBLIC_KEY;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
import static org.briarproject.briar.api.forum.ForumPostFactory.SIGNING_LABEL_POST;
import static org.junit.Assert.assertArrayEquals;
@@ -29,51 +36,42 @@ import static org.junit.Assert.assertFalse;
public class ForumPostValidatorTest extends ValidatorTestCase {
private final MessageId parentId = new MessageId(TestUtils.getRandomId());
private final String authorName =
StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final byte[] authorPublicKey =
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final BdfList authorList = BdfList.of(authorName, authorPublicKey);
private final String content =
StringUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
private final byte[] signature =
TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
private final AuthorId authorId = new AuthorId(TestUtils.getRandomId());
private final Author author =
new Author(authorId, authorName, authorPublicKey);
private final MessageId parentId = new MessageId(getRandomId());
private final String content = getRandomString(MAX_FORUM_POST_BODY_LENGTH);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final Author author = getAuthor();
private final String authorName = author.getName();
private final byte[] authorPublicKey = author.getPublicKey();
private final BdfList authorList = BdfList.of(author.getFormatVersion(),
authorName, authorPublicKey);
private final BdfList signedWithParent = BdfList.of(groupId, timestamp,
parentId.getBytes(), authorList, content);
private final BdfList signedWithoutParent = BdfList.of(groupId, timestamp,
null, authorList, content);
private final ForumPostValidator v = new ForumPostValidator(clientHelper,
metadataEncoder, clock);
@Test(expected = FormatException.class)
public void testRejectsTooShortBody() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongBody() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content, signature, 123));
}
@Test
public void testAcceptsNullParentId() throws Exception {
expectCreateAuthor();
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
authorPublicKey, signedWithoutParent);
}});
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(null, authorList, content, signature));
assertExpectedContext(messageContext, false, authorName);
@@ -81,177 +79,58 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class)
public void testRejectsNonRawParentId() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(123, authorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortParentId() throws Exception {
byte[] invalidParentId = TestUtils.getRandomBytes(UniqueId.LENGTH - 1);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
byte[] invalidParentId = getRandomBytes(UniqueId.LENGTH - 1);
v.validateMessage(message, group,
BdfList.of(invalidParentId, authorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongParentId() throws Exception {
byte[] invalidParentId = TestUtils.getRandomBytes(UniqueId.LENGTH + 1);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
byte[] invalidParentId = getRandomBytes(UniqueId.LENGTH + 1);
v.validateMessage(message, group,
BdfList.of(invalidParentId, authorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNullAuthorList() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, null, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNonListAuthorList() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, 123, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortAuthorList() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, new BdfList(), content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongAuthorList() throws Exception {
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, BdfList.of(1, 2, 3), content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNullAuthorName() throws Exception {
BdfList invalidAuthorList = BdfList.of(null, authorPublicKey);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNonStringAuthorName() throws Exception {
BdfList invalidAuthorList = BdfList.of(123, authorPublicKey);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortAuthorName() throws Exception {
BdfList invalidAuthorList = BdfList.of("", authorPublicKey);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
}
@Test
public void testAcceptsMinLengthAuthorName() throws Exception {
String shortAuthorName = StringUtils.getRandomString(1);
BdfList shortNameAuthorList =
BdfList.of(shortAuthorName, authorPublicKey);
Author shortNameAuthor =
new Author(authorId, shortAuthorName, authorPublicKey);
BdfList signedWithShortNameAuthor = BdfList.of(groupId, timestamp,
parentId.getBytes(), shortNameAuthorList, content);
public void testRejectsInvalidAuthor() throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(shortAuthorName, authorPublicKey);
will(returnValue(shortNameAuthor));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
authorPublicKey, signedWithShortNameAuthor);
oneOf(clientHelper).parseAndValidateAuthor(authorList);
will(throwException(new FormatException()));
}});
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(parentId, shortNameAuthorList, content, signature));
assertExpectedContext(messageContext, true, shortAuthorName);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongAuthorName() throws Exception {
String invalidAuthorName =
StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH + 1);
BdfList invalidAuthorList =
BdfList.of(invalidAuthorName, authorPublicKey);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNullAuthorPublicKey() throws Exception {
BdfList invalidAuthorList = BdfList.of(authorName, null);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNonRawAuthorPublicKey() throws Exception {
BdfList invalidAuthorList = BdfList.of(authorName, 123);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongAuthorPublicKey() throws Exception {
byte[] invalidAuthorPublicKey =
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1);
BdfList invalidAuthorList =
BdfList.of(authorName, invalidAuthorPublicKey);
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, invalidAuthorList, content, signature));
BdfList.of(parentId, authorList, content, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNullContent() throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
}});
expectCreateAuthor();
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, null, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNonStringContent() throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
}});
expectCreateAuthor();
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, 123, signature));
}
@@ -262,15 +141,12 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
BdfList signedWithShortContent = BdfList.of(groupId, timestamp,
parentId.getBytes(), authorList, shortContent);
expectCreateAuthor();
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
authorPublicKey, signedWithShortContent);
}});
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(parentId, authorList, shortContent, signature));
assertExpectedContext(messageContext, true, authorName);
@@ -278,58 +154,36 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class)
public void testRejectsTooLongContent() throws Exception {
String invalidContent =
StringUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH + 1);
String invalidContent = getRandomString(MAX_FORUM_POST_BODY_LENGTH + 1);
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
}});
expectCreateAuthor();
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, invalidContent, signature));
}
@Test(expected = FormatException.class)
public void testRejectsNullSignature() throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
}});
expectCreateAuthor();
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content, null));
}
@Test(expected = FormatException.class)
public void testRejectsNonRawSignature() throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
}});
expectCreateAuthor();
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content, 123));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongSignature() throws Exception {
byte[] invalidSignature =
TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH + 1);
byte[] invalidSignature = getRandomBytes(MAX_SIGNATURE_LENGTH + 1);
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
}});
expectCreateAuthor();
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content, invalidSignature));
}
@@ -337,16 +191,13 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class)
public void testRejectsIfVerifyingSignatureThrowsFormatException()
throws Exception {
expectCreateAuthor();
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
authorPublicKey, signedWithParent);
will(throwException(new FormatException()));
}});
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content, signature));
}
@@ -354,39 +205,45 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
@Test(expected = InvalidMessageException.class)
public void testRejectsIfVerifyingSignatureThrowsGeneralSecurityException()
throws Exception {
expectCreateAuthor();
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
will(returnValue(author));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
authorPublicKey, signedWithParent);
will(throwException(new GeneralSecurityException()));
}});
ForumPostValidator v = new ForumPostValidator(authorFactory,
clientHelper, metadataEncoder, clock);
v.validateMessage(message, group,
BdfList.of(parentId, authorList, content, signature));
}
private void expectCreateAuthor() throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateAuthor(authorList);
will(returnValue(author));
}});
}
private void assertExpectedContext(BdfMessageContext messageContext,
boolean hasParent, String authorName) throws FormatException {
BdfDictionary meta = messageContext.getDictionary();
Collection<MessageId> dependencies = messageContext.getDependencies();
if (hasParent) {
assertEquals(4, meta.size());
assertArrayEquals(parentId.getBytes(), meta.getRaw("parent"));
assertArrayEquals(parentId.getBytes(), meta.getRaw(KEY_PARENT));
assertEquals(1, dependencies.size());
assertEquals(parentId, dependencies.iterator().next());
} else {
assertEquals(3, meta.size());
assertEquals(0, dependencies.size());
}
assertEquals(timestamp, meta.getLong("timestamp").longValue());
assertFalse(meta.getBoolean("read"));
BdfDictionary authorMeta = meta.getDictionary("author");
assertEquals(3, authorMeta.size());
assertArrayEquals(authorId.getBytes(), authorMeta.getRaw("id"));
assertEquals(authorName, authorMeta.getString("name"));
assertArrayEquals(authorPublicKey, authorMeta.getRaw("publicKey"));
assertEquals(timestamp, meta.getLong(KEY_TIMESTAMP).longValue());
assertFalse(meta.getBoolean(KEY_READ));
BdfDictionary authorMeta = meta.getDictionary(KEY_AUTHOR);
assertEquals(4, authorMeta.size());
assertArrayEquals(author.getId().getBytes(), authorMeta.getRaw(KEY_ID));
assertEquals(author.getFormatVersion(),
authorMeta.getLong(KEY_FORMAT_VERSION).intValue());
assertEquals(authorName, authorMeta.getString(KEY_NAME));
assertArrayEquals(authorPublicKey, authorMeta.getRaw(KEY_PUBLIC_KEY));
}
}

View File

@@ -25,7 +25,6 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.introduction.IntroduceeProtocolState;
import org.briarproject.briar.test.BriarTestCase;
@@ -40,6 +39,10 @@ import java.security.SecureRandom;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.briar.api.introduction.IntroduceeProtocolState.AWAIT_REQUEST;
import static org.briarproject.briar.api.introduction.IntroductionConstants.ACCEPT;
import static org.briarproject.briar.api.introduction.IntroductionConstants.ADDED_CONTACT_ID;
@@ -125,47 +128,41 @@ public class IntroduceeManagerTest extends BriarTestCase {
authorFactory, contactManager, identityManager,
introductionGroupFactory);
AuthorId authorId0 = new AuthorId(TestUtils.getRandomId());
Author author0 = new Author(authorId0, "Introducer",
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
AuthorId localAuthorId = new AuthorId(TestUtils.getRandomId());
Author author0 = getAuthor();
AuthorId localAuthorId = new AuthorId(getRandomId());
ContactId contactId0 = new ContactId(234);
introducer =
new Contact(contactId0, author0, localAuthorId, true, true);
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
Author author1 = new Author(authorId1, "Introducee1",
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
Author author1 = getAuthor();
AuthorId localAuthorId1 = new AuthorId(getRandomId());
ContactId contactId1 = new ContactId(234);
introducee1 =
new Contact(contactId1, author1, localAuthorId1, true, true);
AuthorId authorId2 = new AuthorId(TestUtils.getRandomId());
Author author2 = new Author(authorId2, "Introducee2",
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
Author author2 = getAuthor();
ContactId contactId2 = new ContactId(235);
introducee2 =
new Contact(contactId2, author2, localAuthorId, true, true);
ClientId clientId = IntroductionManagerImpl.CLIENT_ID;
localGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
localGroup1 = new Group(new GroupId(getRandomId()),
clientId, new byte[0]);
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
introductionGroup1 = new Group(new GroupId(getRandomId()),
clientId, new byte[0]);
sessionId = new SessionId(TestUtils.getRandomId());
sessionId = new SessionId(getRandomId());
localStateMessage = new Message(
new MessageId(TestUtils.getRandomId()),
new MessageId(getRandomId()),
localGroup1.getId(),
time,
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
);
message1 = new Message(
new MessageId(TestUtils.getRandomId()),
new MessageId(getRandomId()),
introductionGroup1.getId(),
time,
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
);
txn = new Transaction(null, false);
@@ -218,7 +215,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
// turn request message into a response
msg.put(ACCEPT, true);
msg.put(TIME, time);
msg.put(E_PUBLIC_KEY, TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
msg.put(E_PUBLIC_KEY, getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
msg.put(TRANSPORT, new BdfDictionary());
context.checking(new Expectations() {{
@@ -251,13 +248,13 @@ public class IntroduceeManagerTest extends BriarTestCase {
// prepare state for incoming ACK
state.put(STATE, IntroduceeProtocolState.AWAIT_ACK.ordinal());
state.put(ADDED_CONTACT_ID, 2);
byte[] nonce = TestUtils.getRandomBytes(42);
byte[] nonce = getRandomBytes(42);
state.put(NONCE, nonce);
state.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
// create incoming ACK message
byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
byte[] mac = getRandomBytes(MAC_LENGTH);
byte[] sig = getRandomBytes(MAX_SIGNATURE_LENGTH);
BdfDictionary ack = BdfDictionary.of(
new BdfEntry(TYPE, TYPE_ACK),
new BdfEntry(SESSION_ID, sessionId),
@@ -288,8 +285,8 @@ public class IntroduceeManagerTest extends BriarTestCase {
throws FormatException, DbException, GeneralSecurityException {
byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
byte[] nonce = TestUtils.getRandomBytes(MAC_LENGTH);
byte[] sig = TestUtils.getRandomBytes(MAC_LENGTH);
byte[] nonce = getRandomBytes(MAC_LENGTH);
byte[] sig = getRandomBytes(MAC_LENGTH);
BdfDictionary state = new BdfDictionary();
state.put(PUBLIC_KEY, publicKeyBytes);
@@ -311,10 +308,9 @@ public class IntroduceeManagerTest extends BriarTestCase {
byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
BdfDictionary tp = BdfDictionary.of(new BdfEntry("fake", "fake"));
byte[] ePublicKeyBytes =
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
SecretKey macKey = TestUtils.getSecretKey();
byte[] ePublicKeyBytes = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
byte[] mac = getRandomBytes(MAC_LENGTH);
SecretKey macKey = getSecretKey();
// move state to where it would be after an ACK arrived
BdfDictionary state = new BdfDictionary();
@@ -325,7 +321,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
state.put(MAC, mac);
state.put(MAC_KEY, macKey.getBytes());
byte[] signBytes = TestUtils.getRandomBytes(42);
byte[] signBytes = getRandomBytes(42);
context.checking(new Expectations() {{
oneOf(clientHelper).toByteArray(
BdfList.of(publicKeyBytes, ePublicKeyBytes, tp, time));
@@ -348,7 +344,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
oneOf(cryptoComponent).mac(with(MAC_LABEL),
with(samePropertyValuesAs(macKey)),
with(array(equal(signBytes))));
will(returnValue(TestUtils.getRandomBytes(MAC_LENGTH)));
will(returnValue(getRandomBytes(MAC_LENGTH)));
}});
try {
introduceeManager.verifyMac(state);

View File

@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.briar.test.BriarTestCase;
import org.jmock.Expectations;
import org.jmock.Mockery;
@@ -27,7 +26,9 @@ import org.junit.Test;
import java.security.SecureRandom;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.api.introduction.IntroducerProtocolState.AWAIT_RESPONSES;
import static org.briarproject.briar.api.introduction.IntroducerProtocolState.PREPARE_REQUESTS;
import static org.briarproject.briar.api.introduction.IntroductionConstants.AUTHOR_ID_1;
@@ -80,27 +81,23 @@ public class IntroducerManagerTest extends BriarTestCase {
new IntroducerManager(messageSender, clientHelper, clock,
cryptoComponent, introductionGroupFactory);
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
Author author1 = new Author(authorId1, "Introducee1",
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
Author author1 = getAuthor();
AuthorId localAuthorId1 = new AuthorId(getRandomId());
ContactId contactId1 = new ContactId(234);
introducee1 =
new Contact(contactId1, author1, localAuthorId1, true, true);
AuthorId authorId2 = new AuthorId(TestUtils.getRandomId());
Author author2 = new Author(authorId2, "Introducee2",
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
AuthorId localAuthorId2 = new AuthorId(TestUtils.getRandomId());
Author author2 = getAuthor();
AuthorId localAuthorId2 = new AuthorId(getRandomId());
ContactId contactId2 = new ContactId(235);
introducee2 =
new Contact(contactId2, author2, localAuthorId2, true, true);
localGroup0 = new Group(new GroupId(TestUtils.getRandomId()),
localGroup0 = new Group(new GroupId(getRandomId()),
getClientId(), new byte[0]);
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
introductionGroup1 = new Group(new GroupId(getRandomId()),
getClientId(), new byte[0]);
introductionGroup2 = new Group(new GroupId(TestUtils.getRandomId()),
introductionGroup2 = new Group(new GroupId(getRandomId()),
getClientId(), new byte[0]);
context.assertIsSatisfied();
@@ -113,8 +110,8 @@ public class IntroducerManagerTest extends BriarTestCase {
context.setImposteriser(ClassImposteriser.INSTANCE);
SecureRandom secureRandom = context.mock(SecureRandom.class);
Bytes salt = new Bytes(new byte[64]);
Message msg = new Message(new MessageId(TestUtils.getRandomId()),
localGroup0.getId(), time, TestUtils.getRandomBytes(64));
Message msg = new Message(new MessageId(getRandomId()),
localGroup0.getId(), time, getRandomBytes(64));
BdfDictionary state = new BdfDictionary();
state.put(SESSION_ID, msg.getId());
state.put(STORAGE_ID, msg.getId());

View File

@@ -26,8 +26,6 @@ import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestDatabaseModule;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.introduction.IntroductionManager;
import org.briarproject.briar.api.introduction.IntroductionMessage;
@@ -55,6 +53,8 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.client.MessageQueueManager.QUEUE_STATE_KEY;
import static org.briarproject.briar.api.introduction.IntroductionConstants.ALICE_MAC_KEY_LABEL;
import static org.briarproject.briar.api.introduction.IntroductionConstants.ALICE_NONCE_LABEL;
@@ -485,9 +485,8 @@ public class IntroductionIntegrationTest
new BdfEntry(TYPE, TYPE_REQUEST),
new BdfEntry(SESSION_ID, sessionId),
new BdfEntry(GROUP_ID, group.getId()),
new BdfEntry(NAME, StringUtils.getRandomString(42)),
new BdfEntry(PUBLIC_KEY,
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH))
new BdfEntry(NAME, getRandomString(42)),
new BdfEntry(PUBLIC_KEY, getRandomBytes(MAX_PUBLIC_KEY_LENGTH))
);
// reset request received state

View File

@@ -19,8 +19,6 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.MessageStatus;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.test.BriarTestCase;
@@ -33,8 +31,11 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID_1;
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID_2;
import static org.briarproject.briar.api.introduction.IntroductionConstants.ROLE;
@@ -55,7 +56,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
private final ClientHelper clientHelper;
private final MessageTracker messageTracker;
private final IntroductionGroupFactory introductionGroupFactory;
private final SessionId sessionId = new SessionId(TestUtils.getRandomId());
private final SessionId sessionId = new SessionId(getRandomId());
private final MessageId storageId = new MessageId(sessionId.getBytes());
private final long time = 42L;
private final Contact introducee1;
@@ -66,33 +67,29 @@ public class IntroductionManagerImplTest extends BriarTestCase {
private Transaction txn;
public IntroductionManagerImplTest() {
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
Author author1 = new Author(authorId1, "Introducee1",
new byte[MAX_PUBLIC_KEY_LENGTH]);
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
Author author1 = getAuthor();
AuthorId localAuthorId1 = new AuthorId(getRandomId());
ContactId contactId1 = new ContactId(234);
introducee1 =
new Contact(contactId1, author1, localAuthorId1, true, true);
AuthorId authorId2 = new AuthorId(TestUtils.getRandomId());
Author author2 = new Author(authorId2, "Introducee2",
new byte[MAX_PUBLIC_KEY_LENGTH]);
AuthorId localAuthorId2 = new AuthorId(TestUtils.getRandomId());
Author author2 = getAuthor();
AuthorId localAuthorId2 = new AuthorId(getRandomId());
ContactId contactId2 = new ContactId(235);
introducee2 =
new Contact(contactId2, author2, localAuthorId2, true, true);
ClientId clientId = new ClientId(StringUtils.getRandomString(5));
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
ClientId clientId = new ClientId(getRandomString(5));
introductionGroup1 = new Group(new GroupId(getRandomId()),
clientId, new byte[0]);
introductionGroup2 = new Group(new GroupId(TestUtils.getRandomId()),
introductionGroup2 = new Group(new GroupId(getRandomId()),
clientId, new byte[0]);
message1 = new Message(
new MessageId(TestUtils.getRandomId()),
new MessageId(getRandomId()),
introductionGroup1.getId(),
time,
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
);
// mock ALL THE THINGS!!!

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group;
@@ -14,20 +15,20 @@ import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.system.SystemClock;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.test.BriarTestCase;
import org.jmock.Mockery;
import org.junit.Test;
import java.io.IOException;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.introduction.IntroductionConstants.ACCEPT;
import static org.briarproject.briar.api.introduction.IntroductionConstants.E_PUBLIC_KEY;
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID;
@@ -59,14 +60,14 @@ public class IntroductionValidatorTest extends BriarTestCase {
private final Clock clock = new SystemClock();
public IntroductionValidatorTest() {
GroupId groupId = new GroupId(TestUtils.getRandomId());
ClientId clientId = new ClientId(StringUtils.getRandomString(5));
byte[] descriptor = TestUtils.getRandomBytes(12);
GroupId groupId = new GroupId(getRandomId());
ClientId clientId = new ClientId(getRandomString(5));
byte[] descriptor = getRandomBytes(12);
group = new Group(groupId, clientId, descriptor);
MessageId messageId = new MessageId(TestUtils.getRandomId());
MessageId messageId = new MessageId(getRandomId());
long timestamp = System.currentTimeMillis();
byte[] raw = TestUtils.getRandomBytes(123);
byte[] raw = getRandomBytes(123);
message = new Message(messageId, group.getId(), timestamp, raw);
@@ -82,20 +83,17 @@ public class IntroductionValidatorTest extends BriarTestCase {
//
@Test
public void testValidateProperIntroductionRequest() throws IOException {
byte[] sessionId = TestUtils.getRandomId();
String name = StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey =
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String text =
StringUtils.getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
public void testValidateProperIntroductionRequest() throws Exception {
byte[] sessionId = getRandomId();
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String text = getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
BdfList body = BdfList.of(TYPE_REQUEST, sessionId,
name, publicKey, text);
BdfDictionary result =
validator.validateMessage(message, group, body)
.getDictionary();
validator.validateMessage(message, group, body).getDictionary();
assertEquals(Long.valueOf(TYPE_REQUEST), result.getLong(TYPE));
assertEquals(sessionId, result.getRaw(SESSION_ID));
@@ -106,7 +104,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
}
@Test(expected = FormatException.class)
public void testValidateIntroductionRequestWithNoName() throws IOException {
public void testValidateIntroductionRequestWithNoName() throws Exception {
BdfDictionary msg = getValidIntroductionRequest();
// no NAME is message
@@ -118,8 +116,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
}
@Test(expected = FormatException.class)
public void testValidateIntroductionRequestWithLongName()
throws IOException {
public void testValidateIntroductionRequestWithLongName() throws Exception {
// too long NAME in message
BdfDictionary msg = getValidIntroductionRequest();
msg.put(NAME, msg.get(NAME) + "x");
@@ -132,7 +129,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
@Test(expected = FormatException.class)
public void testValidateIntroductionRequestWithWrongType()
throws IOException {
throws Exception {
// wrong message type
BdfDictionary msg = getValidIntroductionRequest();
msg.put(TYPE, 324234);
@@ -143,17 +140,16 @@ public class IntroductionValidatorTest extends BriarTestCase {
validator.validateMessage(message, group, body);
}
private BdfDictionary getValidIntroductionRequest() throws FormatException {
byte[] sessionId = TestUtils.getRandomId();
String name = StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String text = StringUtils.getRandomString(MAX_MESSAGE_BODY_LENGTH);
private BdfDictionary getValidIntroductionRequest() throws Exception {
byte[] sessionId = getRandomId();
Author author = getAuthor();
String text = getRandomString(MAX_MESSAGE_BODY_LENGTH);
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, TYPE_REQUEST);
msg.put(SESSION_ID, sessionId);
msg.put(NAME, name);
msg.put(PUBLIC_KEY, publicKey);
msg.put(NAME, author.getName());
msg.put(PUBLIC_KEY, author.getPublicKey());
msg.put(MSG, text);
return msg;
@@ -164,16 +160,16 @@ public class IntroductionValidatorTest extends BriarTestCase {
//
@Test
public void testValidateIntroductionAcceptResponse() throws IOException {
byte[] groupId = TestUtils.getRandomId();
byte[] sessionId = TestUtils.getRandomId();
public void testValidateIntroductionAcceptResponse() throws Exception {
byte[] groupId = getRandomId();
byte[] sessionId = getRandomId();
long time = clock.currentTimeMillis();
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String transportId = StringUtils
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String transportId =
getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
BdfDictionary tProps = BdfDictionary.of(
new BdfEntry(StringUtils.getRandomString(MAX_PROPERTY_LENGTH),
StringUtils.getRandomString(MAX_PROPERTY_LENGTH))
new BdfEntry(getRandomString(MAX_PROPERTY_LENGTH),
getRandomString(MAX_PROPERTY_LENGTH))
);
BdfDictionary tp = BdfDictionary.of(
new BdfEntry(transportId, tProps)
@@ -204,8 +200,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
}
@Test
public void testValidateIntroductionDeclineResponse()
throws IOException {
public void testValidateIntroductionDeclineResponse() throws Exception {
BdfDictionary msg = getValidIntroductionResponse(false);
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
msg.getBoolean(ACCEPT));
@@ -219,7 +214,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
@Test(expected = FormatException.class)
public void testValidateIntroductionResponseWithoutAccept()
throws IOException {
throws Exception {
BdfDictionary msg = getValidIntroductionResponse(false);
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID));
@@ -228,11 +223,11 @@ public class IntroductionValidatorTest extends BriarTestCase {
@Test(expected = FormatException.class)
public void testValidateIntroductionResponseWithBrokenTp()
throws IOException {
throws Exception {
BdfDictionary msg = getValidIntroductionResponse(true);
BdfDictionary tp = msg.getDictionary(TRANSPORT);
tp.put(StringUtils
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH), "X");
tp.put(
getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH), "X");
msg.put(TRANSPORT, tp);
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
@@ -244,7 +239,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
@Test(expected = FormatException.class)
public void testValidateIntroductionResponseWithoutPublicKey()
throws IOException {
throws Exception {
BdfDictionary msg = getValidIntroductionResponse(true);
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
@@ -255,17 +250,17 @@ public class IntroductionValidatorTest extends BriarTestCase {
}
private BdfDictionary getValidIntroductionResponse(boolean accept)
throws FormatException {
throws Exception {
byte[] groupId = TestUtils.getRandomId();
byte[] sessionId = TestUtils.getRandomId();
byte[] groupId = getRandomId();
byte[] sessionId = getRandomId();
long time = clock.currentTimeMillis();
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String transportId = StringUtils
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
String transportId =
getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
BdfDictionary tProps = BdfDictionary.of(
new BdfEntry(StringUtils.getRandomString(MAX_PROPERTY_LENGTH),
StringUtils.getRandomString(MAX_PROPERTY_LENGTH))
new BdfEntry(getRandomString(MAX_PROPERTY_LENGTH),
getRandomString(MAX_PROPERTY_LENGTH))
);
BdfDictionary tp = BdfDictionary.of(
new BdfEntry(transportId, tProps)
@@ -290,10 +285,10 @@ public class IntroductionValidatorTest extends BriarTestCase {
//
@Test
public void testValidateProperIntroductionAck() throws IOException {
byte[] sessionId = TestUtils.getRandomId();
byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
public void testValidateProperIntroductionAck() throws Exception {
byte[] sessionId = getRandomId();
byte[] mac = getRandomBytes(MAC_LENGTH);
byte[] sig = getRandomBytes(MAX_SIGNATURE_LENGTH);
BdfList body = BdfList.of(TYPE_ACK, sessionId, mac, sig);
BdfDictionary result =
@@ -307,11 +302,11 @@ public class IntroductionValidatorTest extends BriarTestCase {
}
@Test(expected = FormatException.class)
public void testValidateTooLongIntroductionAck() throws IOException {
public void testValidateTooLongIntroductionAck() throws Exception {
BdfDictionary msg = BdfDictionary.of(
new BdfEntry(TYPE, TYPE_ACK),
new BdfEntry(SESSION_ID, TestUtils.getRandomId()),
new BdfEntry("garbage", StringUtils.getRandomString(255))
new BdfEntry(SESSION_ID, getRandomId()),
new BdfEntry("garbage", getRandomString(255))
);
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
msg.getString("garbage"));
@@ -321,7 +316,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
@Test(expected = FormatException.class)
public void testValidateIntroductionAckWithLongSessionId()
throws IOException {
throws Exception {
BdfDictionary msg = BdfDictionary.of(
new BdfEntry(TYPE, TYPE_ACK),
new BdfEntry(SESSION_ID, new byte[SessionId.LENGTH + 1])
@@ -336,8 +331,8 @@ public class IntroductionValidatorTest extends BriarTestCase {
//
@Test
public void testValidateProperIntroductionAbort() throws IOException {
byte[] sessionId = TestUtils.getRandomId();
public void testValidateProperIntroductionAbort() throws Exception {
byte[] sessionId = getRandomId();
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, TYPE_ABORT);
@@ -354,11 +349,11 @@ public class IntroductionValidatorTest extends BriarTestCase {
}
@Test(expected = FormatException.class)
public void testValidateTooLongIntroductionAbort() throws IOException {
public void testValidateTooLongIntroductionAbort() throws Exception {
BdfDictionary msg = BdfDictionary.of(
new BdfEntry(TYPE, TYPE_ABORT),
new BdfEntry(SESSION_ID, TestUtils.getRandomId()),
new BdfEntry("garbage", StringUtils.getRandomString(255))
new BdfEntry(SESSION_ID, getRandomId()),
new BdfEntry("garbage", getRandomString(255))
);
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
msg.getString("garbage"));

View File

@@ -8,9 +8,6 @@ import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.system.SystemModule;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.forum.ForumConstants;
import org.briarproject.briar.api.forum.ForumPost;
import org.briarproject.briar.api.forum.ForumPostFactory;
import org.briarproject.briar.api.messaging.PrivateMessage;
@@ -22,8 +19,9 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
import static org.junit.Assert.assertTrue;
@@ -47,12 +45,11 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
}
@Test
public void testPrivateMessageFitsIntoPacket() throws Exception {
public void testPrivateMessageFitsIntoRecord() throws Exception {
// Create a maximum-length private message
GroupId groupId = new GroupId(getRandomId());
long timestamp = Long.MAX_VALUE;
String body =
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
String body = getRandomString(MAX_PRIVATE_MESSAGE_BODY_LENGTH);
PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, body);
// Check the size of the serialised message
@@ -63,27 +60,25 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
}
@Test
public void testForumPostFitsIntoPacket() throws Exception {
public void testForumPostFitsIntoRecord() throws Exception {
// Create a maximum-length author
String authorName = StringUtils.getRandomString(
MAX_AUTHOR_NAME_LENGTH);
int formatVersion = Integer.MAX_VALUE;
String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
LocalAuthor author = authorFactory
.createLocalAuthor(authorName, authorPublic,
privateKey.getEncoded());
LocalAuthor author = authorFactory.createLocalAuthor(formatVersion,
authorName, authorPublic, privateKey.getEncoded());
// Create a maximum-length forum post
GroupId groupId = new GroupId(getRandomId());
long timestamp = Long.MAX_VALUE;
MessageId parent = new MessageId(getRandomId());
String body = StringUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
String body = getRandomString(MAX_FORUM_POST_BODY_LENGTH);
ForumPost post = forumPostFactory.createPost(groupId,
timestamp, parent, author, body);
// Check the size of the serialised message
int length = post.getMessage().getRaw().length;
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH + 4
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
+ MAX_FORUM_POST_BODY_LENGTH);
assertTrue(length <= MAX_RECORD_PAYLOAD_LENGTH);
}

View File

@@ -5,8 +5,6 @@ import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
@@ -36,10 +34,12 @@ import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.test.TestPluginConfigModule.MAX_LATENCY;
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -47,16 +47,13 @@ import static org.junit.Assert.assertTrue;
public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final static String ALICE = "Alice";
private final static String BOB = "Bob";
private final File testDir = TestUtils.getTestDirectory();
private final File testDir = getTestDirectory();
private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob");
private final SecretKey master = TestUtils.getSecretKey();
private final SecretKey master = getSecretKey();
private final long timestamp = System.currentTimeMillis();
private final AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
private final AuthorId bobId = new AuthorId(TestUtils.getRandomId());
private final LocalAuthor aliceAuthor = getLocalAuthor();
private final LocalAuthor bobAuthor = getLocalAuthor();
private SimplexMessagingIntegrationTestComponent alice, bob;
@@ -95,12 +92,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
lifecycleManager.startServices(null);
lifecycleManager.waitForStartup();
// Add an identity for Alice
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.registerLocalAuthor(aliceAuthor);
// Add Bob as a contact
Author bobAuthor = new Author(bobId, BOB,
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(bobAuthor,
aliceAuthor.getId(), master, timestamp, true, true, true);
@@ -146,12 +139,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
lifecycleManager.startServices(null);
lifecycleManager.waitForStartup();
// Add an identity for Bob
LocalAuthor bobAuthor = new LocalAuthor(bobId, BOB,
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.registerLocalAuthor(bobAuthor);
// Add Alice as a contact
Author aliceAuthor = new Author(aliceId, ALICE,
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(aliceAuthor,
bobAuthor.getId(), master, timestamp, false, true, true);
// Set up an event listener

View File

@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.ValidatorTestCase;
@@ -21,9 +20,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -36,6 +34,7 @@ import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_FORMAT_VERSION;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_ID;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_NAME;
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
@@ -56,119 +55,129 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
private final GroupInvitationFactory groupInvitationFactory =
context.mock(GroupInvitationFactory.class);
private final String creatorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final String memberName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final byte[] creatorKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final byte[] memberKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final Author member = getAuthor();
private final BdfList memberList = BdfList.of(
member.getFormatVersion(),
member.getName(),
member.getPublicKey()
);
private final byte[] memberSignature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final Author creator = getAuthor();
private final BdfList creatorList = BdfList.of(
creator.getFormatVersion(),
creator.getName(),
creator.getPublicKey()
);
private final byte[] creatorSignature =
getRandomBytes(MAX_SIGNATURE_LENGTH);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final Author member =
new Author(new AuthorId(getRandomId()), memberName, memberKey);
private final Author creator =
new Author(new AuthorId(getRandomId()), creatorName, creatorKey);
private final long inviteTimestamp = 42L;
private final long inviteTimestamp = message.getTimestamp() - 1;
private final BdfList invite =
BdfList.of(inviteTimestamp, creatorSignature);
private final PrivateGroup privateGroup = new PrivateGroup(group,
getRandomString(MAX_GROUP_NAME_LENGTH), creator,
getRandomBytes(GROUP_SALT_LENGTH));
private final BdfList token = BdfList.of("token");
private final BdfList token = new BdfList();
private final MessageId parentId = new MessageId(getRandomId());
private final MessageId previousMsgId = new MessageId(getRandomId());
private final String postContent =
getRandomString(MAX_GROUP_POST_BODY_LENGTH);
private final String content = getRandomString(MAX_GROUP_POST_BODY_LENGTH);
private final GroupMessageValidator validator =
new GroupMessageValidator(privateGroupFactory, clientHelper,
metadataEncoder, clock, authorFactory,
groupInvitationFactory);
metadataEncoder, clock, groupInvitationFactory);
// JOIN message
@Test(expected = FormatException.class)
public void testRejectsTooShortJoinMessage() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey, null);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongJoinMessage() throws Exception {
expectCreateAuthor(creator);
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey, null,
signature, "");
expectParseAuthor(memberList, member);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
memberSignature, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooShortMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), "", memberKey, null,
signature);
public void testRejectsJoinWithNullAuthor() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), null, invite, memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithTooLongMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(),
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), memberKey, null,
signature);
public void testRejectsJoinWithNonListAuthor() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), 123, invite, memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNullMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), null, memberKey, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNonStringMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), getRandomBytes(5), memberKey,
null, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooShortMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName, new byte[0], null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooLongMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), null, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithNoullMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName, null, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithNonRawMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName, "not raw", null,
signature);
public void testRejectsJoinWithInvalidAuthor() throws Exception {
expectRejectAuthor(memberList);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithNonListInvitation() throws Exception {
expectCreateAuthor(creator);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey,
"not a list", signature);
expectParseAuthor(memberList, member);
BdfList body = BdfList.of(JOIN.getInt(), memberList, "not a list",
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsCreatorJoinWithTooShortMemberSignature()
throws Exception {
expectParseAuthor(creatorList, creator);
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite,
new byte[0]);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsCreatorJoinWithTooLongMemberSignature()
throws Exception {
expectParseAuthor(creatorList, creator);
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsCreatorJoinWithNullMemberSignature()
throws Exception {
expectParseAuthor(creatorList, creator);
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite, null);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsCreatorJoinWithNonRawMemberSignature()
throws Exception {
expectParseAuthor(creatorList, creator);
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite,
"not raw");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsCreatorJoinWithInvalidMemberSignature()
throws Exception {
expectCreatorJoinMessage(false);
BdfList body = BdfList.of(JOIN.getInt(), creatorList, null,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsCreatorJoin() throws Exception {
expectJoinMessage(creator, null, true, true);
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey,
null, signature);
expectCreatorJoinMessage(true);
BdfList body = BdfList.of(JOIN.getInt(), creatorList, null,
memberSignature);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, JOIN, creator,
@@ -177,151 +186,183 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
.getBoolean(KEY_INITIAL_JOIN_MSG));
}
@Test(expected = InvalidMessageException.class)
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullInvitation() throws Exception {
expectCreateAuthor(member);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, null,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, null,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooShortInvitation() throws Exception {
BdfList invite = BdfList.of(inviteTimestamp);
expectCreateAuthor(member);
BdfList invalidInvite = BdfList.of(inviteTimestamp);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooLongInvitation() throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature, "");
expectCreateAuthor(member);
BdfList invalidInvite =
BdfList.of(inviteTimestamp, creatorSignature, "");
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithEqualInvitationTime()
throws Exception {
BdfList invite = BdfList.of(message.getTimestamp(), creatorSignature);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithLaterInvitationTime()
throws Exception {
BdfList invite = BdfList.of(message.getTimestamp() + 1,
creatorSignature);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullInvitationTime()
public void testRejectsMemberJoinWithEqualInvitationTime()
throws Exception {
BdfList invite = BdfList.of(null, creatorSignature);
expectCreateAuthor(member);
BdfList invalidInvite =
BdfList.of(message.getTimestamp(), creatorSignature);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithLaterInvitationTime()
throws Exception {
BdfList invalidInvite =
BdfList.of(message.getTimestamp() + 1, creatorSignature);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullInvitationTime() throws Exception {
BdfList invalidInvite = BdfList.of(null, creatorSignature);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNonLongInvitationTime()
throws Exception {
BdfList invite = BdfList.of("not long", creatorSignature);
expectCreateAuthor(member);
BdfList invalidInvite = BdfList.of("not long", creatorSignature);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooShortCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, new byte[0]);
expectCreateAuthor(member);
BdfList invalidInvite = BdfList.of(inviteTimestamp, new byte[0]);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooLongCreatorSignature()
public void testRejectsMemberJoinWithTooLongCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp,
BdfList invalidInvite = BdfList.of(inviteTimestamp,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
expectCreateAuthor(member);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, null);
expectCreateAuthor(member);
BdfList invalidInvite = BdfList.of(inviteTimestamp, null);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNonRawCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, "not raw");
expectCreateAuthor(member);
BdfList invalidInvite = BdfList.of(inviteTimestamp, "not raw");
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithInvalidCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
expectJoinMessage(member, invite, false, true);
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
expectMemberJoinMessage(false, true);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooShortMemberSignature()
throws Exception {
expectParseAuthor(memberList, member);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
new byte[0]);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooLongMemberSignature()
throws Exception {
expectParseAuthor(memberList, member);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullMemberSignature()
throws Exception {
expectParseAuthor(memberList, member);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite, null);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNonRawMemberSignature()
throws Exception {
expectParseAuthor(memberList, member);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite, "not raw");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithInvalidMemberSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
expectJoinMessage(member, invite, true, false);
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
expectMemberJoinMessage(true, false);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
memberSignature);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsMemberJoin() throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
expectJoinMessage(member, invite, true, true);
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
expectMemberJoinMessage(true, true);
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
memberSignature);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, JOIN, member,
@@ -330,11 +371,18 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
.getBoolean(KEY_INITIAL_JOIN_MSG));
}
private void expectCreateAuthor(Author member) {
private void expectParseAuthor(BdfList authorList, Author author)
throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(member.getName(),
member.getPublicKey());
will(returnValue(member));
oneOf(clientHelper).parseAndValidateAuthor(authorList);
will(returnValue(author));
}});
}
private void expectRejectAuthor(BdfList authorList) throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateAuthor(authorList);
will(throwException(new FormatException()));
}});
}
@@ -345,26 +393,46 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
}});
}
private void expectJoinMessage(Author member, BdfList invite,
boolean creatorSigValid, boolean memberSigValid) throws Exception {
BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
JOIN.getInt(), member.getName(), member.getPublicKey(), invite);
expectCreateAuthor(member);
private void expectCreatorJoinMessage(boolean memberSigValid)
throws Exception {
BdfList signed = BdfList.of(
group.getId(),
message.getTimestamp(),
creatorList,
null
);
expectParseAuthor(creatorList, creator);
expectParsePrivateGroup();
context.checking(new Expectations() {{
if (invite != null) {
oneOf(groupInvitationFactory).createInviteToken(creator.getId(),
member.getId(), privateGroup.getId(), inviteTimestamp);
will(returnValue(token));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE,
creatorSignature, creatorKey, token);
if (!memberSigValid)
will(throwException(new GeneralSecurityException()));
}
if (memberSigValid) {
oneOf(clientHelper).verifySignature(SIGNING_LABEL_JOIN,
memberSignature, creator.getPublicKey(), signed);
if (!memberSigValid)
will(throwException(new GeneralSecurityException()));
}});
}
private void expectMemberJoinMessage(boolean creatorSigValid,
boolean memberSigValid) throws Exception {
BdfList signed = BdfList.of(
group.getId(),
message.getTimestamp(),
memberList,
invite
);
expectParseAuthor(memberList, member);
expectParsePrivateGroup();
context.checking(new Expectations() {{
oneOf(groupInvitationFactory).createInviteToken(creator.getId(),
member.getId(), privateGroup.getId(), inviteTimestamp);
will(returnValue(token));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE,
creatorSignature, creator.getPublicKey(), token);
if (!creatorSigValid) {
will(throwException(new GeneralSecurityException()));
} else {
oneOf(clientHelper).verifySignature(SIGNING_LABEL_JOIN,
signature, member.getPublicKey(), signed);
if (!creatorSigValid)
memberSignature, member.getPublicKey(), signed);
if (!memberSigValid)
will(throwException(new GeneralSecurityException()));
}
}});
@@ -374,216 +442,178 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class)
public void testRejectsTooShortPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, signature, "");
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, memberSignature, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(), "", memberKey, parentId,
previousMsgId, postContent, signature);
public void testRejectsPostWithNullAuthor() throws Exception {
BdfList body = BdfList.of(POST.getInt(), null, parentId, previousMsgId,
content, memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(),
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), memberKey,
parentId, previousMsgId, postContent, signature);
public void testRejectsPostWithNonListAuthor() throws Exception {
BdfList body = BdfList.of(POST.getInt(), 123, parentId, previousMsgId,
content, memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(), null, memberKey,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonStringMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(), getRandomBytes(5), memberKey,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, new byte[0],
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), parentId,
previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, null,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, "not raw",
parentId, previousMsgId, postContent, signature);
public void testRejectsPostWithInvalidAuthor() throws Exception {
expectRejectAuthor(memberList);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, memberSignature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortParentId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
getRandomBytes(MessageId.LENGTH - 1), previousMsgId,
postContent, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList,
getRandomBytes(MessageId.LENGTH - 1), previousMsgId, content,
memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongParentId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
getRandomBytes(MessageId.LENGTH + 1), previousMsgId,
postContent, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList,
getRandomBytes(MessageId.LENGTH + 1), previousMsgId, content,
memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawParentId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
"not raw", previousMsgId, postContent, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, "not raw",
previousMsgId, content, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, getRandomBytes(MessageId.LENGTH - 1), postContent,
signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
getRandomBytes(MessageId.LENGTH - 1), content, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, getRandomBytes(MessageId.LENGTH + 1), postContent,
signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
getRandomBytes(MessageId.LENGTH + 1), content, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, null, postContent, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId, null,
content, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, "not raw", postContent, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
"not raw", content, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, "", signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, "", memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId,
getRandomString(MAX_GROUP_POST_BODY_LENGTH + 1), signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, getRandomString(MAX_GROUP_POST_BODY_LENGTH + 1),
memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, null, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, null, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonStringContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, getRandomBytes(5), signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, getRandomBytes(5), memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, new byte[0]);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, new byte[0]);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent,
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
expectCreateAuthor(member);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent,null);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, null);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, "not raw");
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, "not raw");
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
@Test(expected = FormatException.class)
public void testRejectsPostWithInvalidSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, signature);
expectPostMessage(member, parentId, false);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, memberSignature);
expectPostMessage(parentId, false);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, signature);
expectPostMessage(member, parentId, true);
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
previousMsgId, content, memberSignature);
expectPostMessage(parentId, true);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, POST, member,
@@ -596,9 +626,9 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
@Test
public void testAcceptsTopLevelPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey, null,
previousMsgId, postContent, signature);
expectPostMessage(member, null, true);
BdfList body = BdfList.of(POST.getInt(), memberList, null,
previousMsgId, content, memberSignature);
expectPostMessage(null, true);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, POST, member,
@@ -609,17 +639,22 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
messageContext.getDictionary().containsKey(KEY_PARENT_MSG_ID));
}
private void expectPostMessage(Author member, MessageId parentId,
boolean sigValid) throws Exception {
BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
POST.getInt(), member.getName(), member.getPublicKey(),
private void expectPostMessage(MessageId parentId, boolean sigValid)
throws Exception {
BdfList signed = BdfList.of(
group.getId(),
message.getTimestamp(),
memberList,
parentId == null ? null : parentId.getBytes(),
previousMsgId.getBytes(), postContent);
expectCreateAuthor(member);
previousMsgId.getBytes(),
content
);
expectParseAuthor(memberList, member);
context.checking(new Expectations() {{
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
member.getPublicKey(), signed);
if (!sigValid) will(throwException(new GeneralSecurityException()));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST,
memberSignature, member.getPublicKey(), signed);
if (!sigValid)
will(throwException(new GeneralSecurityException()));
}});
}
@@ -632,6 +667,8 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
d.getLong(KEY_TIMESTAMP).longValue());
assertFalse(d.getBoolean(KEY_READ));
assertEquals(member.getId().getBytes(), d.getRaw(KEY_MEMBER_ID));
assertEquals(member.getFormatVersion(),
d.getLong(KEY_MEMBER_FORMAT_VERSION).intValue());
assertEquals(member.getName(), d.getString(KEY_MEMBER_NAME));
assertEquals(member.getPublicKey(), d.getRaw(KEY_MEMBER_PUBLIC_KEY));
assertEquals(dependencies, c.getDependencies());
@@ -639,9 +676,9 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
@Test(expected = InvalidMessageException.class)
public void testRejectsMessageWithUnknownType() throws Exception {
BdfList body = BdfList.of(POST.getInt() + 1, memberName, memberKey,
parentId, previousMsgId, postContent, signature);
expectCreateAuthor(member);
BdfList body = BdfList.of(POST.getInt() + 1, memberList,
parentId, previousMsgId, content, memberSignature);
expectParseAuthor(memberList, member);
validator.validateMessage(message, group, body);
}
}

View File

@@ -23,8 +23,14 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.jmock.Expectations;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
@@ -59,14 +65,13 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
protected final GroupId contactGroupId = new GroupId(getRandomId());
protected final GroupId privateGroupId = new GroupId(getRandomId());
protected final Group privateGroupGroup =
new Group(privateGroupId, CLIENT_ID, getRandomBytes(5));
private final AuthorId authorId = new AuthorId(getRandomId());
protected final Author author =
new Author(authorId, "Author", getRandomBytes(12));
new Group(privateGroupId, CLIENT_ID, getRandomBytes(123));
protected final Author author = getAuthor();
protected final PrivateGroup privateGroup =
new PrivateGroup(privateGroupGroup, "Private Group", author,
getRandomBytes(8));
protected final byte[] signature = getRandomBytes(42);
new PrivateGroup(privateGroupGroup,
getRandomString(MAX_GROUP_NAME_LENGTH), author,
getRandomBytes(GROUP_SALT_LENGTH));
protected final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
protected final MessageId lastLocalMessageId = new MessageId(getRandomId());
protected final MessageId lastRemoteMessageId =
new MessageId(getRandomId());
@@ -74,20 +79,19 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
protected final long inviteTimestamp = 6L;
protected final long messageTimestamp = inviteTimestamp + 1;
protected final MessageId messageId = new MessageId(getRandomId());
protected final Message message =
new Message(messageId, contactGroupId, messageTimestamp,
getRandomBytes(42));
protected final Message message = new Message(messageId, contactGroupId,
messageTimestamp, getRandomBytes(42));
private final BdfDictionary meta =
BdfDictionary.of(new BdfEntry("me", "ta"));
protected final ContactId contactId = new ContactId(5);
protected final Contact contact =
new Contact(contactId, author, new AuthorId(getRandomId()), true,
true);
protected final Contact contact = new Contact(contactId, author,
new AuthorId(getRandomId()), true, true);
protected final InviteMessage inviteMessage =
new InviteMessage(new MessageId(getRandomId()), contactGroupId,
privateGroupId, 0L, privateGroup.getName(),
privateGroup.getCreator(), privateGroup.getSalt(), "msg",
privateGroup.getCreator(), privateGroup.getSalt(),
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH),
signature);
protected final JoinMessage joinMessage =
new JoinMessage(new MessageId(getRandomId()), contactGroupId,

View File

@@ -4,10 +4,8 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.ValidatorTestCase;
@@ -18,9 +16,8 @@ import org.junit.Test;
import java.security.GeneralSecurityException;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -42,194 +39,149 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
private final MessageEncoder messageEncoder =
context.mock(MessageEncoder.class);
private final Author creator = getAuthor();
private final BdfList creatorList = BdfList.of(
creator.getFormatVersion(),
creator.getName(),
creator.getPublicKey()
);
private final String groupName = getRandomString(MAX_GROUP_NAME_LENGTH);
private final String creatorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final byte[] creatorKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final Author creator =
new Author(new AuthorId(getRandomId()), creatorName, creatorKey);
private final byte[] salt = getRandomBytes(GROUP_SALT_LENGTH);
private final PrivateGroup privateGroup =
new PrivateGroup(group, groupName, creator, salt);
private final String inviteText =
private final String content =
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final BdfDictionary meta =
BdfDictionary.of(new BdfEntry("meta", "data"));
private final PrivateGroup privateGroup =
new PrivateGroup(group, groupName, creator, salt);
private final BdfDictionary meta = new BdfDictionary();
private final MessageId previousMessageId = new MessageId(getRandomId());
private final GroupInvitationValidator validator =
new GroupInvitationValidator(clientHelper, metadataEncoder,
clock, authorFactory, privateGroupFactory, messageEncoder);
clock, privateGroupFactory, messageEncoder);
// INVITE Message
@Test(expected = FormatException.class)
public void testRejectsTooShortInviteMessage() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongInviteMessage() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, signature, "");
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, signature, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), "", creatorName,
creatorKey, salt, inviteText, signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, "", salt,
content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(),
getRandomString(MAX_GROUP_NAME_LENGTH + 1), creatorName,
creatorKey, salt, inviteText, signature);
String tooLongName = getRandomString(MAX_GROUP_NAME_LENGTH + 1);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, tooLongName,
salt, content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), null, creatorName,
creatorKey, salt, inviteText, signature);
public void testRejectsInviteMessageWithNullGroupName() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), creatorList, null, salt,
content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonStringGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), getRandomBytes(5),
creatorName, creatorKey, salt, inviteText, signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList,
getRandomBytes(5), salt, content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, "", creatorKey,
salt, inviteText, signature);
public void testRejectsInviteMessageWithNullCreator() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), null, groupName, salt,
content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName,
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), creatorKey, salt,
inviteText, signature);
public void testRejectsInviteMessageWithNonListCreator() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), 123, groupName, salt,
content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, null,
creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
public void testRejectsInviteMessageWithInvalidCreator() throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateAuthor(creatorList);
will(throwException(new FormatException()));
}});
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonStringCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName,
getRandomBytes(5), creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
new byte[0], salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), salt, inviteText,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
null, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonRawCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
"not raw", salt, inviteText, signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, getRandomBytes(GROUP_SALT_LENGTH - 1), inviteText,
signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
getRandomBytes(GROUP_SALT_LENGTH - 1), content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, getRandomBytes(GROUP_SALT_LENGTH + 1), inviteText,
signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
getRandomBytes(GROUP_SALT_LENGTH + 1), content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, null, inviteText, signature);
public void testRejectsInviteMessageWithNullGroupSalt() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
null, content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonRawGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, "not raw", inviteText, signature);
public void testRejectsInviteMessageWithNonRawGroupSalt() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
"not raw", content, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortContent() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, "", signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, "", signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongContent() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt,
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH + 1),
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH + 1),
signature);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsInviteMessageWithNullContent() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, null, signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, null, signature);
expectInviteMessage(false);
validator.validateMessage(message, group, body);
}
@@ -237,57 +189,54 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonStringContent()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, getRandomBytes(5), signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, getRandomBytes(5), signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, new byte[0]);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, new byte[0]);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, null);
public void testRejectsInviteMessageWithNullSignature() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, null);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonRawSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, "not raw");
public void testRejectsInviteMessageWithNonRawSignature() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, "not raw");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithInvalidSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, null, signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, signature);
expectInviteMessage(true);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsValidInviteMessage() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, signature);
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
salt, content, signature);
expectInviteMessage(false);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
@@ -296,16 +245,19 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
}
private void expectInviteMessage(boolean exception) throws Exception {
BdfList signed = BdfList.of(message.getTimestamp(),
message.getGroupId(), privateGroup.getId());
BdfList signed = BdfList.of(
message.getTimestamp(),
message.getGroupId(),
privateGroup.getId()
);
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(creatorName, creatorKey);
oneOf(clientHelper).parseAndValidateAuthor(creatorList);
will(returnValue(creator));
oneOf(privateGroupFactory).createPrivateGroup(groupName, creator,
salt);
will(returnValue(privateGroup));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE, signature,
creatorKey, signed);
creator.getPublicKey(), signed);
if (exception) {
will(throwException(new GeneralSecurityException()));
} else {

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.ProtocolStateException;
@@ -18,8 +17,11 @@ import java.util.Map;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
import static org.briarproject.briar.privategroup.invitation.InviteeState.ACCEPTED;
import static org.briarproject.briar.privategroup.invitation.InviteeState.DISSOLVED;
import static org.briarproject.briar.privategroup.invitation.InviteeState.ERROR;
@@ -39,9 +41,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
new InviteeProtocolEngine(db, clientHelper, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
private final LocalAuthor localAuthor =
new LocalAuthor(new AuthorId(getRandomId()), "Local Author",
getRandomBytes(12), getRandomBytes(12), 42L);
private final LocalAuthor localAuthor = getLocalAuthor();
private InviteeSession getDefaultSession(InviteeState state) {
return new InviteeSession(contactGroupId, privateGroupId,
@@ -323,13 +323,12 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
new InviteMessage(new MessageId(getRandomId()), contactGroupId,
privateGroupId, session.getInviteTimestamp() + 1,
privateGroup.getName(), privateGroup.getCreator(),
privateGroup.getSalt(), "msg", signature);
Author notCreator =
new Author(new AuthorId(getRandomId()), "Not Creator",
getRandomBytes(5));
Contact notCreatorContact =
new Contact(contactId, notCreator, localAuthor.getId(), true,
true);
privateGroup.getSalt(),
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH),
signature);
Author notCreator = getAuthor();
Contact notCreatorContact = new Contact(contactId, notCreator,
localAuthor.getId(), true, true);
expectGetContactId();
context.checking(new Expectations() {{

View File

@@ -83,12 +83,10 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
MessageParser<Blog> messageParser = context.mock(MessageParser.class);
InvitationFactory<Blog, BlogInvitationResponse> invitationFactory =
context.mock(InvitationFactory.class);
blogSharingManager =
new BlogSharingManagerImpl(db, clientHelper, metadataParser,
messageParser, sessionEncoder, sessionParser,
messageTracker, contactGroupFactory,
engine, invitationFactory, identityManager,
blogManager);
blogSharingManager = new BlogSharingManagerImpl(db, clientHelper,
metadataParser, messageParser, sessionEncoder, sessionParser,
messageTracker, contactGroupFactory, engine, invitationFactory,
identityManager, blogManager);
}
@Test
@@ -228,13 +226,11 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
private void expectPreShareShareable(Transaction txn, Contact contact,
Blog blog, Map<MessageId, BdfDictionary> sessions)
throws Exception {
Group contactGroup =
new Group(new GroupId(getRandomId()), CLIENT_ID,
getRandomBytes(42));
Group contactGroup = new Group(new GroupId(getRandomId()), CLIENT_ID,
getRandomBytes(42));
BdfDictionary sessionDict = new BdfDictionary();
Message message =
new Message(new MessageId(getRandomId()), contactGroup.getId(),
42L, getRandomBytes(1337));
Message message = new Message(new MessageId(getRandomId()),
contactGroup.getId(), 42L, getRandomBytes(1337));
context.checking(new Expectations() {{
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
CLIENT_VERSION, contact);
@@ -242,9 +238,8 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
oneOf(sessionParser)
.getSessionQuery(new SessionId(blog.getId().getBytes()));
will(returnValue(sessionDict));
oneOf(clientHelper)
.getMessageMetadataAsDictionary(txn, contactGroup.getId(),
sessionDict);
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup.getId(), sessionDict);
will(returnValue(sessions));
if (sessions.size() == 0) {
oneOf(db).addGroup(txn, blog.getGroup());
@@ -277,9 +272,8 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
oneOf(sessionParser)
.getSessionQuery(new SessionId(blog.getId().getBytes()));
will(returnValue(sessionDict));
oneOf(clientHelper)
.getMessageMetadataAsDictionary(txn, contactGroup.getId(),
sessionDict);
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup.getId(), sessionDict);
will(returnValue(sessions));
if (sessions.size() == 1) {
oneOf(sessionParser)

View File

@@ -4,184 +4,130 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.blog.Blog;
import org.jmock.Expectations;
import org.junit.Test;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_NAME_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
import static org.briarproject.briar.sharing.MessageType.INVITE;
public class BlogSharingValidatorTest extends SharingValidatorTest {
private final AuthorId authorId = new AuthorId(getRandomId());
private final String authorName = StringUtils.getRandomString(42);
private final byte[] publicKey =
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final Author author = new Author(authorId, authorName, publicKey);
private final Author author = getAuthor();
private final Blog blog = new Blog(group, author, false);
private final BdfList descriptor = BdfList.of(authorName, publicKey, false);
private final BdfList authorList = BdfList.of(author.getFormatVersion(),
author.getName(), author.getPublicKey());
private final BdfList descriptor = BdfList.of(authorList, false);
private final String content =
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
@Override
SharingValidator getValidator() {
return new BlogSharingValidator(messageEncoder, clientHelper,
metadataEncoder, clock, blogFactory, authorFactory);
metadataEncoder, clock, blogFactory);
}
@Test
public void testAcceptsInvitationWithContent() throws Exception {
expectCreateBlog(authorName, publicKey);
expectCreateBlog();
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
content));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsInvitationWithNullContent() throws Exception {
expectCreateBlog(authorName, publicKey);
expectCreateBlog();
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
expectCreateBlog(authorName, publicKey);
expectCreateBlog();
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, null));
assertExpectedContext(messageContext, null);
}
@Test(expected = FormatException.class)
public void testRejectsNullBlogName() throws Exception {
BdfList invalidDescriptor = BdfList.of(null, publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsNonStringBlogName() throws Exception {
BdfList invalidDescriptor = BdfList.of(123, publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortBlogName() throws Exception {
BdfList invalidDescriptor = BdfList.of("", publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, content));
assertExpectedContext(context, null);
}
@Test
public void testAcceptsMinLengthBlogName() throws Exception {
String shortBlogName = StringUtils.getRandomString(1);
BdfList validDescriptor = BdfList.of(shortBlogName, publicKey, false);
expectCreateBlog(shortBlogName, publicKey);
public void testAcceptsInvitationForRssBlog() throws Exception {
expectCreateRssBlog();
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
null));
assertExpectedContext(messageContext, previousMsgId);
BdfList rssDescriptor = BdfList.of(authorList, true);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, rssDescriptor,
content));
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongBlogName() throws Exception {
String invalidBlogName =
StringUtils.getRandomString(MAX_BLOG_NAME_LENGTH + 1);
BdfList invalidDescriptor =
BdfList.of(invalidBlogName, publicKey, false);
v.validateMessage(message, group,
public void testRejectsNullAuthor() throws Exception {
BdfList invalidDescriptor = BdfList.of(null, false);
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsNullPublicKey() throws Exception {
BdfList invalidDescriptor = BdfList.of(authorName, null, false);
v.validateMessage(message, group,
public void testRejectsNonListAuthor() throws Exception {
BdfList invalidDescriptor = BdfList.of(123, false);
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsNonRawPublicKey() throws Exception {
BdfList invalidDescriptor = BdfList.of(authorName, 123, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongPublicKey() throws Exception {
byte[] invalidKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1);
BdfList invalidDescriptor = BdfList.of(authorName, invalidKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test
public void testAcceptsMinLengthPublicKey() throws Exception {
byte[] key = TestUtils.getRandomBytes(1);
BdfList validDescriptor = BdfList.of(authorName, key, false);
expectCreateBlog(authorName, key);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
null));
assertExpectedContext(messageContext, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsNonStringContent() throws Exception {
expectCreateBlog(authorName, publicKey);
v.validateMessage(message, group,
expectCreateBlog();
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
123));
}
@Test
public void testAcceptsMinLengthContent() throws Exception {
expectCreateBlog(authorName, publicKey);
String shortContent = getRandomString(1);
expectCreateBlog();
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
assertExpectedContext(messageContext, previousMsgId);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
shortContent));
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongContent() throws Exception {
String invalidContent =
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
expectCreateBlog(authorName, publicKey);
v.validateMessage(message, group,
getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
expectCreateBlog();
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
invalidContent));
}
private void expectCreateBlog(String name, byte[] key) {
private void expectCreateBlog() throws Exception {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(name, key);
oneOf(clientHelper).parseAndValidateAuthor(authorList);
will(returnValue(author));
oneOf(blogFactory).createBlog(author);
will(returnValue(blog));
}});
}
private void expectCreateRssBlog() throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateAuthor(authorList);
will(returnValue(author));
oneOf(blogFactory).createFeedBlog(author);
will(returnValue(blog));
}});
}
}

View File

@@ -3,12 +3,12 @@ package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.forum.Forum;
import org.jmock.Expectations;
import org.junit.Test;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
@@ -16,13 +16,12 @@ import static org.briarproject.briar.sharing.MessageType.INVITE;
public class ForumSharingValidatorTest extends SharingValidatorTest {
private final String forumName =
StringUtils.getRandomString(MAX_FORUM_NAME_LENGTH);
private final byte[] salt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH);
private final String forumName = getRandomString(MAX_FORUM_NAME_LENGTH);
private final byte[] salt = getRandomBytes(FORUM_SALT_LENGTH);
private final Forum forum = new Forum(group, forumName, salt);
private final BdfList descriptor = BdfList.of(forumName, salt);
private final String content =
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
@Override
SharingValidator getValidator() {
@@ -34,34 +33,34 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
public void testAcceptsInvitationWithContent() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
content));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsInvitationWithNullContent() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, null));
assertExpectedContext(messageContext, null);
assertExpectedContext(context, null);
}
@Test(expected = FormatException.class)
public void testRejectsNullForumName() throws Exception {
BdfList invalidDescriptor = BdfList.of(null, salt);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@@ -69,7 +68,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNonStringForumName() throws Exception {
BdfList invalidDescriptor = BdfList.of(123, salt);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@@ -77,29 +76,28 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsTooShortForumName() throws Exception {
BdfList invalidDescriptor = BdfList.of("", salt);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test
public void testAcceptsMinLengthForumName() throws Exception {
String shortForumName = StringUtils.getRandomString(1);
String shortForumName = getRandomString(1);
BdfList validDescriptor = BdfList.of(shortForumName, salt);
expectCreateForum(shortForumName);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
null));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongForumName() throws Exception {
String invalidForumName =
StringUtils.getRandomString(MAX_FORUM_NAME_LENGTH + 1);
String invalidForumName = getRandomString(MAX_FORUM_NAME_LENGTH + 1);
BdfList invalidDescriptor = BdfList.of(invalidForumName, salt);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@@ -107,7 +105,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNullSalt() throws Exception {
BdfList invalidDescriptor = BdfList.of(forumName, null);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@@ -115,25 +113,25 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNonRawSalt() throws Exception {
BdfList invalidDescriptor = BdfList.of(forumName, 123);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortSalt() throws Exception {
byte[] invalidSalt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH - 1);
byte[] invalidSalt = getRandomBytes(FORUM_SALT_LENGTH - 1);
BdfList invalidDescriptor = BdfList.of(forumName, invalidSalt);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongSalt() throws Exception {
byte[] invalidSalt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH + 1);
byte[] invalidSalt = getRandomBytes(FORUM_SALT_LENGTH + 1);
BdfList invalidDescriptor = BdfList.of(forumName, invalidSalt);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
}
@@ -141,26 +139,25 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNonStringContent() throws Exception {
expectCreateForum(forumName);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
123));
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, 123));
}
@Test
public void testAcceptsMinLengthContent() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongContent() throws Exception {
String invalidContent =
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
expectCreateForum(forumName);
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
invalidContent));
}

View File

@@ -4,10 +4,8 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.test.ValidatorTestCase;
import org.briarproject.briar.api.blog.BlogFactory;
import org.briarproject.briar.api.forum.ForumFactory;
@@ -18,6 +16,7 @@ import java.util.Collection;
import javax.annotation.Nullable;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.sharing.MessageType.ABORT;
import static org.briarproject.briar.sharing.MessageType.ACCEPT;
@@ -29,28 +28,26 @@ import static org.junit.Assert.assertTrue;
public abstract class SharingValidatorTest extends ValidatorTestCase {
protected final MessageEncoder messageEncoder =
context.mock(MessageEncoder.class);
protected final ForumFactory forumFactory =
context.mock(ForumFactory.class);
protected final BlogFactory blogFactory = context.mock(BlogFactory.class);
protected final SharingValidator v = getValidator();
final MessageEncoder messageEncoder = context.mock(MessageEncoder.class);
final ForumFactory forumFactory = context.mock(ForumFactory.class);
final BlogFactory blogFactory = context.mock(BlogFactory.class);
protected final MessageId previousMsgId = new MessageId(getRandomId());
private final BdfDictionary meta =
BdfDictionary.of(new BdfEntry("meta", "data"));
final SharingValidator validator = getValidator();
final MessageId previousMsgId = new MessageId(getRandomId());
private final BdfDictionary meta = new BdfDictionary();
abstract SharingValidator getValidator();
@Test(expected = FormatException.class)
public void testRejectsTooShortBodyForInvitation() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongBodyForInvitation() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null,
123));
}
@@ -58,101 +55,101 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Test
public void testAcceptsAccept() throws Exception {
expectEncodeMetadata(ACCEPT);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(ACCEPT.getValue(), groupId, previousMsgId));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsDecline() throws Exception {
expectEncodeMetadata(DECLINE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(DECLINE.getValue(), groupId, previousMsgId));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsLeave() throws Exception {
expectEncodeMetadata(LEAVE);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(LEAVE.getValue(), groupId, previousMsgId));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test
public void testAcceptsAbort() throws Exception {
expectEncodeMetadata(ABORT);
BdfMessageContext messageContext = v.validateMessage(message, group,
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), groupId, previousMsgId));
assertExpectedContext(messageContext, previousMsgId);
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsNullMessageType() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(null, groupId, previousMsgId));
}
@Test(expected = FormatException.class)
public void testRejectsNonLongMessageType() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of("", groupId, previousMsgId));
}
@Test(expected = FormatException.class)
public void testRejectsInvalidMessageType() throws Exception {
int invalidMessageType = ABORT.getValue() + 1;
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(invalidMessageType, groupId, previousMsgId));
}
@Test(expected = FormatException.class)
public void testRejectsNullSessionId() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), null, previousMsgId));
}
@Test(expected = FormatException.class)
public void testRejectsNonRawSessionId() throws Exception {
v.validateMessage(message, group, BdfList.of(ABORT.getValue(), 123));
validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), 123));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortSessionId() throws Exception {
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH - 1);
v.validateMessage(message, group,
byte[] invalidGroupId = getRandomBytes(UniqueId.LENGTH - 1);
validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongSessionId() throws Exception {
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH + 1);
v.validateMessage(message, group,
byte[] invalidGroupId = getRandomBytes(UniqueId.LENGTH + 1);
validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
}
@Test(expected = FormatException.class)
public void testRejectsTooShortBodyForAbort() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), groupId));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongBodyForAbort() throws Exception {
v.validateMessage(message, group,
validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
}
protected void expectEncodeMetadata(MessageType type) {
void expectEncodeMetadata(MessageType type) {
context.checking(new Expectations() {{
oneOf(messageEncoder)
.encodeMetadata(type, groupId, timestamp, false, false,
false, false, false);
oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp,
false, false, false, false, false);
will(returnValue(meta));
}});
}
protected void assertExpectedContext(BdfMessageContext messageContext,
void assertExpectedContext(BdfMessageContext messageContext,
@Nullable MessageId previousMsgId) throws FormatException {
Collection<MessageId> dependencies = messageContext.getDependencies();
if (previousMsgId == null) {

View File

@@ -30,7 +30,6 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
import org.briarproject.bramble.properties.PropertiesModule;
import org.briarproject.bramble.sync.SyncModule;
import org.briarproject.bramble.system.SystemModule;
import org.briarproject.bramble.test.TestPluginConfigModule;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.transport.TransportModule;
import org.briarproject.briar.api.blog.BlogFactory;
@@ -64,6 +63,7 @@ import static junit.framework.Assert.assertNotNull;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.bramble.test.TestPluginConfigModule.MAX_LATENCY;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.junit.Assert.assertTrue;
@@ -328,7 +328,7 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
ByteArrayOutputStream out = new ByteArrayOutputStream();
// Create an outgoing sync session
SyncSession sessionFrom =
fromSync.createSimplexOutgoingSession(toId, TestPluginConfigModule.MAX_LATENCY, out);
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
// Write whatever needs to be written
sessionFrom.run();
out.close();