From edbf5ff5b41239c97cd0803afd1bcf2730e05765 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Tue, 8 Nov 2016 15:44:23 +0000 Subject: [PATCH] Preliminaries for private group invitation protocol. --- .../res/layout/fragment_create_group.xml | 2 + briar-android/res/values/strings.xml | 6 +- .../android/ActivityComponent.java | 19 ++++++ .../api/clients/BdfMessageContext.java | 22 ++++--- .../api/clients/ClientHelper.java | 20 ++++-- .../briarproject/api/clients/NamedGroup.java | 3 +- .../briarproject/api/data/BdfDictionary.java | 9 +++ .../org/briarproject/api/data/BdfList.java | 8 +++ .../api/forum/ForumInvitationResponse.java | 5 +- .../api/privategroup/GroupMessageFactory.java | 2 + .../api/privategroup/PrivateGroup.java | 4 +- .../api/privategroup/PrivateGroupFactory.java | 5 +- .../api/sync/BaseMessageContext.java | 19 ------ .../briarproject/api/sync/MessageContext.java | 21 ++++--- .../briarproject/api/sync/MessageFactory.java | 4 +- .../clients/BdfMessageValidator.java | 23 ++++--- .../clients/ClientHelperImpl.java | 61 +++++++++++++++---- .../briarproject/clients/ClientsModule.java | 4 +- .../privategroup/PrivateGroupFactoryImpl.java | 7 ++- .../briarproject/sync/MessageFactoryImpl.java | 16 ++++- .../sync/ValidationManagerImpl.java | 3 +- 21 files changed, 179 insertions(+), 84 deletions(-) delete mode 100644 briar-api/src/org/briarproject/api/sync/BaseMessageContext.java diff --git a/briar-android/res/layout/fragment_create_group.xml b/briar-android/res/layout/fragment_create_group.xml index a9601e2abb..67754dfd56 100644 --- a/briar-android/res/layout/fragment_create_group.xml +++ b/briar-android/res/layout/fragment_create_group.xml @@ -12,6 +12,8 @@ android:layout_height="0dp" android:layout_weight="1" android:gravity="bottom" + android:maxLines="1" + android:inputType="text|textCapSentences" android:hint="@string/groups_create_group_hint"/> <Button diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 3d9e47c001..368fc5664f 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -181,7 +181,7 @@ <!-- Private Group Invitations --> <string name="groups_invitations_title">Group Invitations</string> - <string name="groups_invitations_invitation_sent">You have invited %1$s to your group "%2$s".</string> + <string name="groups_invitations_invitation_sent">You have invited %1$s to join the group "%2$s".</string> <string name="groups_invitations_invitation_received">%1$s has invited you to join the group "%2$s".</string> <string name="groups_invitations_joined">Joined group</string> <string name="groups_invitations_declined">Group invitation declined</string> @@ -191,8 +191,8 @@ </plurals> <string name="groups_invitations_response_accepted_sent">You accepted the group invitation from %s.</string> <string name="groups_invitations_response_declined_sent">You declined the group invitation from %s.</string> - <string name="groups_invitations_response_accepted_received">%s accepted your group invitation.</string> - <string name="groups_invitations_response_declined_received">%s declined your group invitation.</string> + <string name="groups_invitations_response_accepted_received">%s accepted the group invitation.</string> + <string name="groups_invitations_response_declined_received">%s declined the group invitation.</string> <!-- Forums --> <string name="no_forums">You don\'t have any forums yet.\n\nWhy don\'t you create a new one yourself by tapping the + icon at the top?\n\nYou can also ask your contacts to share forums with you.</string> diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java index ee1ee02d59..fa2e845d58 100644 --- a/briar-android/src/org/briarproject/android/ActivityComponent.java +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -80,9 +80,13 @@ public interface ActivityComponent { void inject(BlogInvitationActivity activity); void inject(CreateGroupActivity activity); + void inject(GroupActivity activity); + void inject(GroupInviteActivity activity); + void inject(GroupInvitationActivity activity); + void inject(GroupMemberListActivity activity); void inject(CreateForumActivity activity); @@ -104,9 +108,11 @@ public interface ActivityComponent { void inject(BlogFragment fragment); void inject(BlogPostFragment fragment); + void inject(FeedPostFragment fragment); void inject(BlogPostPagerFragment fragment); + void inject(FeedPostPagerFragment fragment); void inject(ReblogFragment fragment); @@ -124,21 +130,34 @@ public interface ActivityComponent { void inject(RssFeedManageActivity activity); void inject(EmojiProvider emojiProvider); + void inject(RecentEmojiPageModel recentEmojiPageModel); // Fragments void inject(ContactListFragment fragment); + void inject(CreateGroupFragment fragment); + void inject(CreateGroupMessageFragment fragment); + void inject(GroupListFragment fragment); + void inject(ForumListFragment fragment); + void inject(FeedFragment fragment); + void inject(IntroFragment fragment); + void inject(ShowQrCodeFragment fragment); + void inject(ContactChooserFragment fragment); + void inject(ContactSelectorFragment fragment); + void inject(ShareForumMessageFragment fragment); + void inject(ShareBlogMessageFragment fragment); + void inject(IntroductionMessageFragment fragment); } diff --git a/briar-api/src/org/briarproject/api/clients/BdfMessageContext.java b/briar-api/src/org/briarproject/api/clients/BdfMessageContext.java index 70f410c039..6eceac96d0 100644 --- a/briar-api/src/org/briarproject/api/clients/BdfMessageContext.java +++ b/briar-api/src/org/briarproject/api/clients/BdfMessageContext.java @@ -1,25 +1,28 @@ package org.briarproject.api.clients; import org.briarproject.api.data.BdfDictionary; -import org.briarproject.api.sync.BaseMessageContext; +import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sync.MessageId; -import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Collections; -public class BdfMessageContext extends BaseMessageContext { +import javax.annotation.concurrent.Immutable; - private final BdfDictionary dictionary; +@Immutable +@NotNullByDefault +public class BdfMessageContext { - public BdfMessageContext(@NotNull BdfDictionary dictionary, - @NotNull Collection<MessageId> dependencies) { + private final BdfDictionary dictionary; + private final Collection<MessageId> dependencies; - super(dependencies); + public BdfMessageContext(BdfDictionary dictionary, + Collection<MessageId> dependencies) { this.dictionary = dictionary; + this.dependencies = dependencies; } - public BdfMessageContext(@NotNull BdfDictionary dictionary) { + public BdfMessageContext(BdfDictionary dictionary) { this(dictionary, Collections.<MessageId>emptyList()); } @@ -27,4 +30,7 @@ public class BdfMessageContext extends BaseMessageContext { return dictionary; } + public Collection<MessageId> getDependencies() { + return dependencies; + } } diff --git a/briar-api/src/org/briarproject/api/clients/ClientHelper.java b/briar-api/src/org/briarproject/api/clients/ClientHelper.java index b24c9d2b71..7743f3ba5e 100644 --- a/briar-api/src/org/briarproject/api/clients/ClientHelper.java +++ b/briar-api/src/org/briarproject/api/clients/ClientHelper.java @@ -5,14 +5,17 @@ import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfList; import org.briarproject.api.db.DbException; import org.briarproject.api.db.Transaction; +import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sync.GroupId; -import org.briarproject.api.sync.InvalidMessageException; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import java.security.GeneralSecurityException; import java.util.Map; +import javax.annotation.Nullable; + +@NotNullByDefault public interface ClientHelper { void addLocalMessage(Message m, BdfDictionary metadata, boolean shared) @@ -21,14 +24,21 @@ public interface ClientHelper { void addLocalMessage(Transaction txn, Message m, BdfDictionary metadata, boolean shared) throws DbException, FormatException; - Message createMessage(GroupId g, long timestamp, BdfDictionary body) - throws FormatException; - Message createMessage(GroupId g, long timestamp, BdfList body) throws FormatException; + Message createMessageForStoringMetadata(GroupId g); + + @Nullable + Message getMessage(MessageId m) throws DbException; + + @Nullable + Message getMessage(Transaction txn, MessageId m) throws DbException; + + @Nullable BdfList getMessageAsList(MessageId m) throws DbException, FormatException; + @Nullable BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException, FormatException; @@ -80,6 +90,8 @@ public interface ClientHelper { BdfList toList(byte[] b) throws FormatException; + BdfList toList(Message m) throws FormatException; + byte[] sign(BdfList toSign, byte[] privateKey) throws FormatException, GeneralSecurityException; diff --git a/briar-api/src/org/briarproject/api/clients/NamedGroup.java b/briar-api/src/org/briarproject/api/clients/NamedGroup.java index ed4589cae6..176a50858d 100644 --- a/briar-api/src/org/briarproject/api/clients/NamedGroup.java +++ b/briar-api/src/org/briarproject/api/clients/NamedGroup.java @@ -2,7 +2,6 @@ package org.briarproject.api.clients; import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sync.Group; -import org.jetbrains.annotations.NotNull; import javax.annotation.concurrent.Immutable; @@ -13,7 +12,7 @@ public abstract class NamedGroup extends BaseGroup { private final String name; private final byte[] salt; - public NamedGroup(@NotNull Group group, @NotNull String name, byte[] salt) { + public NamedGroup(Group group, String name, byte[] salt) { super(group); this.name = name; this.salt = salt; diff --git a/briar-api/src/org/briarproject/api/data/BdfDictionary.java b/briar-api/src/org/briarproject/api/data/BdfDictionary.java index 24f133e82b..cae6f728d6 100644 --- a/briar-api/src/org/briarproject/api/data/BdfDictionary.java +++ b/briar-api/src/org/briarproject/api/data/BdfDictionary.java @@ -6,6 +6,8 @@ import org.briarproject.api.FormatException; import java.util.Map; import java.util.concurrent.ConcurrentSkipListMap; +import javax.annotation.Nullable; + public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { public static final Object NULL_VALUE = new Object(); @@ -39,6 +41,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public Boolean getOptionalBoolean(String key) throws FormatException { Object o = get(key); if (o == null || o == NULL_VALUE) return null; @@ -61,6 +64,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public Long getOptionalLong(String key) throws FormatException { Object o = get(key); if (o == null || o == NULL_VALUE) return null; @@ -87,6 +91,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public Double getOptionalDouble(String key) throws FormatException { Object o = get(key); if (o == null || o == NULL_VALUE) return null; @@ -108,6 +113,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public String getOptionalString(String key) throws FormatException { Object o = get(key); if (o == null || o == NULL_VALUE) return null; @@ -128,6 +134,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public byte[] getOptionalRaw(String key) throws FormatException { Object o = get(key); if (o == null || o == NULL_VALUE) return null; @@ -149,6 +156,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public BdfList getOptionalList(String key) throws FormatException { Object o = get(key); if (o == null || o == NULL_VALUE) return null; @@ -168,6 +176,7 @@ public class BdfDictionary extends ConcurrentSkipListMap<String, Object> { throw new FormatException(); } + @Nullable public BdfDictionary getOptionalDictionary(String key) throws FormatException { Object o = get(key); diff --git a/briar-api/src/org/briarproject/api/data/BdfList.java b/briar-api/src/org/briarproject/api/data/BdfList.java index 59732f4a05..39b7bd89e9 100644 --- a/briar-api/src/org/briarproject/api/data/BdfList.java +++ b/briar-api/src/org/briarproject/api/data/BdfList.java @@ -2,6 +2,7 @@ package org.briarproject.api.data; import org.briarproject.api.Bytes; import org.briarproject.api.FormatException; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.List; @@ -40,6 +41,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public Boolean getOptionalBoolean(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); Object o = get(index); @@ -65,6 +67,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public Long getOptionalLong(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); Object o = get(index); @@ -94,6 +97,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public Double getOptionalDouble(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); Object o = get(index); @@ -118,6 +122,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public String getOptionalString(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); Object o = get(index); @@ -141,6 +146,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public byte[] getOptionalRaw(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); Object o = get(index); @@ -165,6 +171,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public BdfList getOptionalList(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); Object o = get(index); @@ -187,6 +194,7 @@ public class BdfList extends Vector<Object> { throw new FormatException(); } + @Nullable public BdfDictionary getOptionalDictionary(int index) throws FormatException { if (!isInRange(index)) throw new FormatException(); diff --git a/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java b/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java index d9c49d1545..54969d97cb 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java +++ b/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java @@ -6,13 +6,12 @@ import org.briarproject.api.sharing.InvitationResponse; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public class ForumInvitationResponse extends InvitationResponse { public ForumInvitationResponse(@NotNull MessageId id, SessionId sessionId, - GroupId groupId, ContactId contactId, boolean accept, long time, boolean local, - boolean sent, boolean seen, boolean read) { + GroupId groupId, ContactId contactId, boolean accept, long time, + boolean local, boolean sent, boolean seen, boolean read) { super(id, sessionId, groupId, contactId, accept, time, local, sent, seen, read); diff --git a/briar-api/src/org/briarproject/api/privategroup/GroupMessageFactory.java b/briar-api/src/org/briarproject/api/privategroup/GroupMessageFactory.java index 3b50246958..ff1b72e84f 100644 --- a/briar-api/src/org/briarproject/api/privategroup/GroupMessageFactory.java +++ b/briar-api/src/org/briarproject/api/privategroup/GroupMessageFactory.java @@ -3,10 +3,12 @@ package org.briarproject.api.privategroup; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.identity.Author; import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; import org.jetbrains.annotations.Nullable; +@NotNullByDefault public interface GroupMessageFactory { /** diff --git a/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java b/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java index 9b57d99910..ab8d520590 100644 --- a/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java +++ b/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java @@ -5,7 +5,6 @@ import org.briarproject.api.identity.Author; import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sharing.Shareable; import org.briarproject.api.sync.Group; -import org.jetbrains.annotations.NotNull; import javax.annotation.concurrent.Immutable; @@ -15,8 +14,7 @@ public class PrivateGroup extends NamedGroup implements Shareable { private final Author author; - public PrivateGroup(@NotNull Group group, @NotNull String name, - @NotNull Author author, @NotNull byte[] salt) { + public PrivateGroup(Group group, String name, Author author, byte[] salt) { super(group, name, salt); this.author = author; } diff --git a/briar-api/src/org/briarproject/api/privategroup/PrivateGroupFactory.java b/briar-api/src/org/briarproject/api/privategroup/PrivateGroupFactory.java index 6a27552fa2..e4a13eeb78 100644 --- a/briar-api/src/org/briarproject/api/privategroup/PrivateGroupFactory.java +++ b/briar-api/src/org/briarproject/api/privategroup/PrivateGroupFactory.java @@ -2,21 +2,20 @@ package org.briarproject.api.privategroup; import org.briarproject.api.FormatException; import org.briarproject.api.identity.Author; +import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sync.Group; -import org.jetbrains.annotations.NotNull; +@NotNullByDefault public interface PrivateGroupFactory { /** * Creates a private group with the given name and author. */ - @NotNull PrivateGroup createPrivateGroup(String name, Author author); /** * Creates a private group with the given name, author and salt. */ - @NotNull PrivateGroup createPrivateGroup(String name, Author author, byte[] salt); /** diff --git a/briar-api/src/org/briarproject/api/sync/BaseMessageContext.java b/briar-api/src/org/briarproject/api/sync/BaseMessageContext.java deleted file mode 100644 index 7eb411a6a0..0000000000 --- a/briar-api/src/org/briarproject/api/sync/BaseMessageContext.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.briarproject.api.sync; - -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; - -public abstract class BaseMessageContext { - - private final Collection<MessageId> dependencies; - - public BaseMessageContext(@NotNull Collection<MessageId> dependencies) { - this.dependencies = dependencies; - } - - public Collection<MessageId> getDependencies() { - return dependencies; - } - -} diff --git a/briar-api/src/org/briarproject/api/sync/MessageContext.java b/briar-api/src/org/briarproject/api/sync/MessageContext.java index d0bef01179..ce78942213 100644 --- a/briar-api/src/org/briarproject/api/sync/MessageContext.java +++ b/briar-api/src/org/briarproject/api/sync/MessageContext.java @@ -1,23 +1,27 @@ package org.briarproject.api.sync; import org.briarproject.api.db.Metadata; -import org.jetbrains.annotations.NotNull; +import org.briarproject.api.nullsafety.NotNullByDefault; import java.util.Collection; import java.util.Collections; -public class MessageContext extends BaseMessageContext { +import javax.annotation.concurrent.Immutable; - private final Metadata metadata; +@Immutable +@NotNullByDefault +public class MessageContext { - public MessageContext(@NotNull Metadata metadata, - @NotNull Collection<MessageId> dependencies) { + private final Metadata metadata; + private final Collection<MessageId> dependencies; - super(dependencies); + public MessageContext(Metadata metadata, + Collection<MessageId> dependencies) { this.metadata = metadata; + this.dependencies = dependencies; } - public MessageContext(@NotNull Metadata metadata) { + public MessageContext(Metadata metadata) { this(metadata, Collections.<MessageId>emptyList()); } @@ -25,4 +29,7 @@ public class MessageContext extends BaseMessageContext { return metadata; } + public Collection<MessageId> getDependencies() { + return dependencies; + } } diff --git a/briar-api/src/org/briarproject/api/sync/MessageFactory.java b/briar-api/src/org/briarproject/api/sync/MessageFactory.java index 35a3746249..6b599a8f1f 100644 --- a/briar-api/src/org/briarproject/api/sync/MessageFactory.java +++ b/briar-api/src/org/briarproject/api/sync/MessageFactory.java @@ -2,5 +2,7 @@ package org.briarproject.api.sync; public interface MessageFactory { - Message createMessage(GroupId groupId, long timestamp, byte[] body); + Message createMessage(GroupId g, long timestamp, byte[] body); + + Message createMessage(MessageId m, byte[] raw); } diff --git a/briar-core/src/org/briarproject/clients/BdfMessageValidator.java b/briar-core/src/org/briarproject/clients/BdfMessageValidator.java index 0ebcbfb155..2a78e794dd 100644 --- a/briar-core/src/org/briarproject/clients/BdfMessageValidator.java +++ b/briar-core/src/org/briarproject/clients/BdfMessageValidator.java @@ -1,10 +1,10 @@ package org.briarproject.clients; import org.briarproject.api.FormatException; +import org.briarproject.api.clients.BdfMessageContext; import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.MessageQueueManager.QueueMessageValidator; import org.briarproject.api.clients.QueueMessage; -import org.briarproject.api.clients.BdfMessageContext; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfList; import org.briarproject.api.data.MetadataEncoder; @@ -12,13 +12,15 @@ import org.briarproject.api.db.Metadata; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.InvalidMessageException; import org.briarproject.api.sync.Message; -import org.briarproject.api.sync.ValidationManager.MessageValidator; import org.briarproject.api.sync.MessageContext; +import org.briarproject.api.sync.ValidationManager.MessageValidator; import org.briarproject.api.system.Clock; import org.briarproject.util.StringUtils; import java.util.logging.Logger; +import javax.annotation.Nullable; + import static org.briarproject.api.clients.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH; import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE; @@ -78,7 +80,7 @@ public abstract class BdfMessageValidator implements MessageValidator, } } - protected void checkLength(String s, int minLength, int maxLength) + protected void checkLength(@Nullable String s, int minLength, int maxLength) throws FormatException { if (s != null) { int length = StringUtils.toUtf8(s).length; @@ -87,12 +89,13 @@ public abstract class BdfMessageValidator implements MessageValidator, } } - protected void checkLength(String s, int length) throws FormatException { + protected void checkLength(@Nullable String s, int length) + throws FormatException { if (s != null && StringUtils.toUtf8(s).length != length) throw new FormatException(); } - protected void checkLength(byte[] b, int minLength, int maxLength) + protected void checkLength(@Nullable byte[] b, int minLength, int maxLength) throws FormatException { if (b != null) { if (b.length < minLength) throw new FormatException(); @@ -100,7 +103,8 @@ public abstract class BdfMessageValidator implements MessageValidator, } } - protected void checkLength(byte[] b, int length) throws FormatException { + protected void checkLength(@Nullable byte[] b, int length) + throws FormatException { if (b != null && b.length != length) throw new FormatException(); } @@ -112,11 +116,12 @@ public abstract class BdfMessageValidator implements MessageValidator, } } - protected void checkSize(BdfList list, int size) throws FormatException { + protected void checkSize(@Nullable BdfList list, int size) + throws FormatException { if (list != null && list.size() != size) throw new FormatException(); } - protected void checkSize(BdfDictionary dictionary, int minSize, + protected void checkSize(@Nullable BdfDictionary dictionary, int minSize, int maxSize) throws FormatException { if (dictionary != null) { if (dictionary.size() < minSize) throw new FormatException(); @@ -124,7 +129,7 @@ public abstract class BdfMessageValidator implements MessageValidator, } } - protected void checkSize(BdfDictionary dictionary, int size) + protected void checkSize(@Nullable BdfDictionary dictionary, int size) throws FormatException { if (dictionary != null && dictionary.size() != size) throw new FormatException(); diff --git a/briar-core/src/org/briarproject/clients/ClientHelperImpl.java b/briar-core/src/org/briarproject/clients/ClientHelperImpl.java index d72d78b550..e78e1d36f1 100644 --- a/briar-core/src/org/briarproject/clients/ClientHelperImpl.java +++ b/briar-core/src/org/briarproject/clients/ClientHelperImpl.java @@ -19,6 +19,7 @@ import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.db.Metadata; import org.briarproject.api.db.Transaction; +import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageFactory; @@ -37,28 +38,35 @@ import javax.inject.Inject; import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; +@NotNullByDefault class ClientHelperImpl implements ClientHelper { + /** + * Length in bytes of the random salt used for creating local messages for + * storing metadata. + */ + private static final int SALT_LENGTH = 32; + private final DatabaseComponent db; private final MessageFactory messageFactory; private final BdfReaderFactory bdfReaderFactory; private final BdfWriterFactory bdfWriterFactory; private final MetadataParser metadataParser; private final MetadataEncoder metadataEncoder; - private final CryptoComponent cryptoComponent; + private final CryptoComponent crypto; @Inject ClientHelperImpl(DatabaseComponent db, MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory, BdfWriterFactory bdfWriterFactory, MetadataParser metadataParser, - MetadataEncoder metadataEncoder, CryptoComponent cryptoComponent) { + MetadataEncoder metadataEncoder, CryptoComponent crypto) { this.db = db; this.messageFactory = messageFactory; this.bdfReaderFactory = bdfReaderFactory; this.bdfWriterFactory = bdfWriterFactory; this.metadataParser = metadataParser; this.metadataEncoder = metadataEncoder; - this.cryptoComponent = cryptoComponent; + this.crypto = crypto; } @Override @@ -81,15 +89,36 @@ class ClientHelperImpl implements ClientHelper { } @Override - public Message createMessage(GroupId g, long timestamp, BdfDictionary body) + public Message createMessage(GroupId g, long timestamp, BdfList body) throws FormatException { return messageFactory.createMessage(g, timestamp, toByteArray(body)); } @Override - public Message createMessage(GroupId g, long timestamp, BdfList body) - throws FormatException { - return messageFactory.createMessage(g, timestamp, toByteArray(body)); + public Message createMessageForStoringMetadata(GroupId g) { + byte[] salt = new byte[SALT_LENGTH]; + crypto.getSecureRandom().nextBytes(salt); + return messageFactory.createMessage(g, 0, salt); + } + + @Override + public Message getMessage(MessageId m) throws DbException { + Message message; + Transaction txn = db.startTransaction(true); + try { + message = getMessage(txn, m); + db.commitTransaction(txn); + } finally { + db.endTransaction(txn); + } + return message; + } + + @Override + public Message getMessage(Transaction txn, MessageId m) throws DbException { + byte[] raw = db.getRawMessage(txn, m); + if (raw == null) return null; + return messageFactory.createMessage(m, raw); } @Override @@ -310,13 +339,19 @@ class ClientHelperImpl implements ClientHelper { return toList(b, 0, b.length); } + @Override + public BdfList toList(Message m) throws FormatException { + byte[] raw = m.getRaw(); + return toList(raw, MESSAGE_HEADER_LENGTH, + raw.length - MESSAGE_HEADER_LENGTH); + } + @Override public byte[] sign(BdfList toSign, byte[] privateKey) throws FormatException, GeneralSecurityException { - Signature signature = cryptoComponent.getSignature(); - KeyParser keyParser = cryptoComponent.getSignatureKeyParser(); - PrivateKey key = - keyParser.parsePrivateKey(privateKey); + Signature signature = crypto.getSignature(); + KeyParser keyParser = crypto.getSignatureKeyParser(); + PrivateKey key = keyParser.parsePrivateKey(privateKey); signature.initSign(key); signature.update(toByteArray(toSign)); return signature.sign(); @@ -326,10 +361,10 @@ class ClientHelperImpl implements ClientHelper { public void verifySignature(byte[] sig, byte[] publicKey, BdfList signed) throws FormatException, GeneralSecurityException { // Parse the public key - KeyParser keyParser = cryptoComponent.getSignatureKeyParser(); + KeyParser keyParser = crypto.getSignatureKeyParser(); PublicKey key = keyParser.parsePublicKey(publicKey); // Verify the signature - Signature signature = cryptoComponent.getSignature(); + Signature signature = crypto.getSignature(); signature.initVerify(key); signature.update(toByteArray(signed)); if (!signature.verify(sig)) { diff --git a/briar-core/src/org/briarproject/clients/ClientsModule.java b/briar-core/src/org/briarproject/clients/ClientsModule.java index 9f4160ce3e..480c7f016d 100644 --- a/briar-core/src/org/briarproject/clients/ClientsModule.java +++ b/briar-core/src/org/briarproject/clients/ClientsModule.java @@ -1,8 +1,8 @@ package org.briarproject.clients; import org.briarproject.api.clients.ClientHelper; -import org.briarproject.api.clients.MessageQueueManager; import org.briarproject.api.clients.ContactGroupFactory; +import org.briarproject.api.clients.MessageQueueManager; import org.briarproject.api.clients.QueueMessageFactory; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.data.BdfReaderFactory; @@ -33,7 +33,7 @@ public class ClientsModule { } @Provides - ContactGroupFactory providePrivateGroupFactory(GroupFactory groupFactory, + ContactGroupFactory provideContactGroupFactory(GroupFactory groupFactory, ClientHelper clientHelper) { return new ContactGroupFactoryImpl(groupFactory, clientHelper); } diff --git a/briar-core/src/org/briarproject/privategroup/PrivateGroupFactoryImpl.java b/briar-core/src/org/briarproject/privategroup/PrivateGroupFactoryImpl.java index 7389f2fd69..183bcbd7b7 100644 --- a/briar-core/src/org/briarproject/privategroup/PrivateGroupFactoryImpl.java +++ b/briar-core/src/org/briarproject/privategroup/PrivateGroupFactoryImpl.java @@ -5,20 +5,23 @@ import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.data.BdfList; import org.briarproject.api.identity.Author; import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.privategroup.PrivateGroup; import org.briarproject.api.privategroup.PrivateGroupFactory; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.GroupFactory; import org.briarproject.util.StringUtils; -import org.jetbrains.annotations.NotNull; import java.security.SecureRandom; +import javax.annotation.concurrent.Immutable; import javax.inject.Inject; import static org.briarproject.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH; import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH; +@Immutable +@NotNullByDefault class PrivateGroupFactoryImpl implements PrivateGroupFactory { private final GroupFactory groupFactory; @@ -37,7 +40,6 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory { this.random = random; } - @NotNull @Override public PrivateGroup createPrivateGroup(String name, Author author) { int length = StringUtils.toUtf8(name).length; @@ -50,7 +52,6 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory { return createPrivateGroup(name, author, salt); } - @NotNull @Override public PrivateGroup createPrivateGroup(String name, Author author, byte[] salt) { diff --git a/briar-core/src/org/briarproject/sync/MessageFactoryImpl.java b/briar-core/src/org/briarproject/sync/MessageFactoryImpl.java index 68b5e01b0d..a92f550c64 100644 --- a/briar-core/src/org/briarproject/sync/MessageFactoryImpl.java +++ b/briar-core/src/org/briarproject/sync/MessageFactoryImpl.java @@ -24,14 +24,24 @@ class MessageFactoryImpl implements MessageFactory { } @Override - public Message createMessage(GroupId groupId, long timestamp, byte[] body) { + public Message createMessage(GroupId g, long timestamp, byte[] body) { if (body.length > MAX_MESSAGE_BODY_LENGTH) throw new IllegalArgumentException(); byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length]; - System.arraycopy(groupId.getBytes(), 0, raw, 0, UniqueId.LENGTH); + System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH); ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH); System.arraycopy(body, 0, raw, MESSAGE_HEADER_LENGTH, body.length); MessageId id = new MessageId(crypto.hash(MessageId.LABEL, raw)); - return new Message(id, groupId, timestamp, raw); + return new Message(id, g, timestamp, raw); + } + + @Override + public Message createMessage(MessageId m, byte[] raw) { + if (raw.length < MESSAGE_HEADER_LENGTH) + throw new IllegalArgumentException(); + byte[] groupId = new byte[UniqueId.LENGTH]; + System.arraycopy(raw, 0, groupId, 0, UniqueId.LENGTH); + long timestamp = ByteUtils.readUint64(raw, UniqueId.LENGTH); + return new Message(m, new GroupId(groupId), timestamp, raw); } } diff --git a/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java b/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java index babfac7576..289bde1228 100644 --- a/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java +++ b/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java @@ -274,7 +274,8 @@ class ValidationManagerImpl implements ValidationManager, Service, MessageContext context = v.validateMessage(m, g); storeMessageContextAsync(m, g.getClientId(), context); } catch (InvalidMessageException e) { - if (LOG.isLoggable(INFO)) LOG.info(e.toString()); + if (LOG.isLoggable(INFO)) + LOG.log(INFO, e.toString(), e); Queue<MessageId> invalidate = new LinkedList<MessageId>(); invalidate.add(m.getId()); invalidateNextMessageAsync(invalidate); -- GitLab