Skip to content
Snippets Groups Projects
Verified Commit 91961695 authored by akwizgran's avatar akwizgran
Browse files

Generate message and group IDs in a forward-compatible way.

parent 8decc73f
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,11 @@ public class Group { ...@@ -10,6 +10,11 @@ public class Group {
SHARED // The group is visible and messages are shared SHARED // The group is visible and messages are shared
} }
/**
* The current version of the group format.
*/
public static final int FORMAT_VERSION = 1;
private final GroupId id; private final GroupId id;
private final ClientId clientId; private final ClientId clientId;
private final byte[] descriptor; private final byte[] descriptor;
......
...@@ -5,6 +5,11 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LEN ...@@ -5,6 +5,11 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LEN
public class Message { public class Message {
/**
* The current version of the message format.
*/
public static final int FORMAT_VERSION = 1;
private final MessageId id; private final MessageId id;
private final GroupId groupId; private final GroupId groupId;
private final long timestamp; private final long timestamp;
......
...@@ -16,7 +16,13 @@ public class MessageId extends UniqueId { ...@@ -16,7 +16,13 @@ public class MessageId extends UniqueId {
/** /**
* Label for hashing messages to calculate their identifiers. * Label for hashing messages to calculate their identifiers.
*/ */
public static final String LABEL = "org.briarproject.bramble/MESSAGE_ID"; public static final String ID_LABEL = "org.briarproject.bramble/MESSAGE_ID";
/**
* Label for hashing the root blocks of messages.
*/
public static final String ROOT_LABEL =
"org.briarproject.bramble/MESSAGE_ROOT";
public MessageId(byte[] id) { public MessageId(byte[] id) {
super(id); super(id);
......
...@@ -12,8 +12,8 @@ import org.briarproject.bramble.util.StringUtils; ...@@ -12,8 +12,8 @@ import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.Group.FORMAT_VERSION;
import static org.briarproject.bramble.api.sync.GroupId.LABEL; import static org.briarproject.bramble.api.sync.GroupId.LABEL;
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES; import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
@Immutable @Immutable
...@@ -31,7 +31,7 @@ class GroupFactoryImpl implements GroupFactory { ...@@ -31,7 +31,7 @@ class GroupFactoryImpl implements GroupFactory {
public Group createGroup(ClientId c, int clientVersion, byte[] descriptor) { public Group createGroup(ClientId c, int clientVersion, byte[] descriptor) {
byte[] clientVersionBytes = new byte[INT_32_BYTES]; byte[] clientVersionBytes = new byte[INT_32_BYTES];
ByteUtils.writeUint32(clientVersion, clientVersionBytes, 0); ByteUtils.writeUint32(clientVersion, clientVersionBytes, 0);
byte[] hash = crypto.hash(LABEL, new byte[] {PROTOCOL_VERSION}, byte[] hash = crypto.hash(LABEL, new byte[] {FORMAT_VERSION},
StringUtils.toUtf8(c.getString()), clientVersionBytes, StringUtils.toUtf8(c.getString()), clientVersionBytes,
descriptor); descriptor);
return new Group(new GroupId(hash), c, descriptor); return new Group(new GroupId(hash), c, descriptor);
......
...@@ -12,10 +12,12 @@ import org.briarproject.bramble.util.ByteUtils; ...@@ -12,10 +12,12 @@ import org.briarproject.bramble.util.ByteUtils;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.MessageId.LABEL; import static org.briarproject.bramble.api.sync.Message.FORMAT_VERSION;
import static org.briarproject.bramble.api.sync.MessageId.ID_LABEL;
import static org.briarproject.bramble.api.sync.MessageId.ROOT_LABEL;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
...@@ -32,11 +34,14 @@ class MessageFactoryImpl implements MessageFactory { ...@@ -32,11 +34,14 @@ class MessageFactoryImpl implements MessageFactory {
public Message createMessage(GroupId g, long timestamp, byte[] body) { public Message createMessage(GroupId g, long timestamp, byte[] body) {
if (body.length > MAX_MESSAGE_BODY_LENGTH) if (body.length > MAX_MESSAGE_BODY_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
byte[] timeBytes = new byte[ByteUtils.INT_64_BYTES]; byte[] versionBytes = new byte[] {FORMAT_VERSION};
// There's only one block, so the root hash is the hash of the block
byte[] rootHash = crypto.hash(ROOT_LABEL, versionBytes, body);
byte[] timeBytes = new byte[INT_64_BYTES];
ByteUtils.writeUint64(timestamp, timeBytes, 0); ByteUtils.writeUint64(timestamp, timeBytes, 0);
byte[] hash = crypto.hash(LABEL, new byte[] {PROTOCOL_VERSION}, byte[] idHash = crypto.hash(ID_LABEL, versionBytes, g.getBytes(),
g.getBytes(), timeBytes, body); timeBytes, rootHash);
MessageId id = new MessageId(hash); MessageId id = new MessageId(idHash);
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length]; byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH); System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH); ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
......
package org.briarproject.briar.client; package org.briarproject.briar.client;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.ValidationManager; import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.briar.api.client.MessageQueueManager; import org.briarproject.briar.api.client.MessageQueueManager;
import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.MessageTracker;
...@@ -26,8 +26,9 @@ public class BriarClientModule { ...@@ -26,8 +26,9 @@ public class BriarClientModule {
} }
@Provides @Provides
QueueMessageFactory provideQueueMessageFactory(CryptoComponent crypto) { QueueMessageFactory provideQueueMessageFactory(
return new QueueMessageFactoryImpl(crypto); MessageFactory messageFactory) {
return new QueueMessageFactoryImpl(messageFactory);
} }
@Provides @Provides
......
package org.briarproject.briar.client; package org.briarproject.briar.client;
import org.briarproject.bramble.api.UniqueId; import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.util.ByteUtils; import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.briar.api.client.QueueMessage; import org.briarproject.briar.api.client.QueueMessage;
...@@ -12,10 +13,8 @@ import org.briarproject.briar.api.client.QueueMessageFactory; ...@@ -12,10 +13,8 @@ import org.briarproject.briar.api.client.QueueMessageFactory;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.MessageId.LABEL;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES; import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
import static org.briarproject.briar.api.client.QueueMessage.MAX_QUEUE_MESSAGE_BODY_LENGTH; import static org.briarproject.briar.api.client.QueueMessage.MAX_QUEUE_MESSAGE_BODY_LENGTH;
import static org.briarproject.briar.api.client.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH; import static org.briarproject.briar.api.client.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH;
...@@ -24,11 +23,11 @@ import static org.briarproject.briar.api.client.QueueMessage.QUEUE_MESSAGE_HEADE ...@@ -24,11 +23,11 @@ import static org.briarproject.briar.api.client.QueueMessage.QUEUE_MESSAGE_HEADE
@NotNullByDefault @NotNullByDefault
class QueueMessageFactoryImpl implements QueueMessageFactory { class QueueMessageFactoryImpl implements QueueMessageFactory {
private final CryptoComponent crypto; private final MessageFactory messageFactory;
@Inject @Inject
QueueMessageFactoryImpl(CryptoComponent crypto) { QueueMessageFactoryImpl(MessageFactory messageFactory) {
this.crypto = crypto; this.messageFactory = messageFactory;
} }
@Override @Override
...@@ -36,21 +35,13 @@ class QueueMessageFactoryImpl implements QueueMessageFactory { ...@@ -36,21 +35,13 @@ class QueueMessageFactoryImpl implements QueueMessageFactory {
long queuePosition, byte[] body) { long queuePosition, byte[] body) {
if (body.length > MAX_QUEUE_MESSAGE_BODY_LENGTH) if (body.length > MAX_QUEUE_MESSAGE_BODY_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH + body.length]; byte[] messageBody = new byte[INT_64_BYTES + body.length];
System.arraycopy(groupId.getBytes(), 0, raw, 0, UniqueId.LENGTH); ByteUtils.writeUint64(queuePosition, messageBody, 0);
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH); System.arraycopy(body, 0, messageBody, INT_64_BYTES, body.length);
ByteUtils.writeUint64(queuePosition, raw, MESSAGE_HEADER_LENGTH); Message m = messageFactory.createMessage(groupId, timestamp,
System.arraycopy(body, 0, raw, QUEUE_MESSAGE_HEADER_LENGTH, messageBody);
body.length); return new QueueMessage(m.getId(), groupId, timestamp, queuePosition,
byte[] timeBytes = new byte[INT_64_BYTES]; m.getRaw());
ByteUtils.writeUint64(timestamp, timeBytes, 0);
byte[] bodyBytes = new byte[body.length + INT_64_BYTES];
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, bodyBytes, 0,
body.length + INT_64_BYTES);
byte[] hash = crypto.hash(LABEL, new byte[] {PROTOCOL_VERSION},
groupId.getBytes(), timeBytes, bodyBytes);
MessageId id = new MessageId(hash);
return new QueueMessage(id, groupId, timestamp, queuePosition, raw);
} }
@Override @Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment