diff --git a/api/net/sf/briar/api/protocol/MessageEncoder.java b/api/net/sf/briar/api/protocol/MessageEncoder.java index c11c2bc14cbf4bbef0538008d6dd27f5493f47d1..e1322cbedcb994d31547e243af608d17b9ec28a3 100644 --- a/api/net/sf/briar/api/protocol/MessageEncoder.java +++ b/api/net/sf/briar/api/protocol/MessageEncoder.java @@ -6,7 +6,11 @@ import java.security.PrivateKey; public interface MessageEncoder { - /** Encodes an anonymous to an unrestricted group. */ + /** Encodes a private message. */ + Message encodeMessage(MessageId parent, byte[] body) throws IOException, + GeneralSecurityException; + + /** Encodes an anonymous message to an unrestricted group. */ Message encodeMessage(MessageId parent, Group group, byte[] body) throws IOException, GeneralSecurityException; diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java index d4891e7e70584ea908d7aa95a75fac334b687f02..099ac144f462ff199769d3785bc3936850a8e176 100644 --- a/components/net/sf/briar/db/JdbcDatabase.java +++ b/components/net/sf/briar/db/JdbcDatabase.java @@ -53,7 +53,7 @@ abstract class JdbcDatabase implements Database<Connection> { "CREATE TABLE messages" + " (messageId HASH NOT NULL," + " parentId HASH," - + " groupId HASH NOT NULL," + + " groupId HASH," + " authorId HASH," + " timestamp BIGINT NOT NULL," + " size INT NOT NULL," diff --git a/components/net/sf/briar/protocol/MessageEncoderImpl.java b/components/net/sf/briar/protocol/MessageEncoderImpl.java index 0a5b92a0a7ad00247d02b119b2030e3d3a5562ec..f36e94a2227304131a2979c2b7ada59a8571f0a8 100644 --- a/components/net/sf/briar/protocol/MessageEncoderImpl.java +++ b/components/net/sf/briar/protocol/MessageEncoderImpl.java @@ -33,6 +33,11 @@ class MessageEncoderImpl implements MessageEncoder { this.writerFactory = writerFactory; } + public Message encodeMessage(MessageId parent, byte[] body) + throws IOException, GeneralSecurityException { + return encodeMessage(parent, null, null, null, null, body); + } + public Message encodeMessage(MessageId parent, Group group, byte[] body) throws IOException, GeneralSecurityException { return encodeMessage(parent, group, null, null, null, body); @@ -56,7 +61,8 @@ class MessageEncoderImpl implements MessageEncoder { if((author == null) != (authorKey == null)) throw new IllegalArgumentException(); - if((group.getPublicKey() == null) != (groupKey == null)) + if((group == null || group.getPublicKey() == null) != + (groupKey == null)) throw new IllegalArgumentException(); if(body.length > Message.MAX_BODY_LENGTH) throw new IllegalArgumentException(); @@ -68,7 +74,8 @@ class MessageEncoderImpl implements MessageEncoder { w.writeUserDefinedTag(Types.MESSAGE); if(parent == null) w.writeNull(); else parent.writeTo(w); - group.writeTo(w); + if(group == null) w.writeNull(); + else group.writeTo(w); if(author == null) w.writeNull(); else author.writeTo(w); w.writeInt64(timestamp); diff --git a/components/net/sf/briar/protocol/MessageReader.java b/components/net/sf/briar/protocol/MessageReader.java index 688056e01930a56c45d2ed1e496ed0bc86594203..abcf512065429758dac2cfc0646d2de99faf3417 100644 --- a/components/net/sf/briar/protocol/MessageReader.java +++ b/components/net/sf/briar/protocol/MessageReader.java @@ -12,6 +12,7 @@ import net.sf.briar.api.crypto.KeyParser; import net.sf.briar.api.protocol.Author; import net.sf.briar.api.protocol.AuthorId; import net.sf.briar.api.protocol.Group; +import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.ProtocolConstants; @@ -57,10 +58,15 @@ class MessageReader implements ObjectReader<Message> { parent = r.readUserDefined(Types.MESSAGE_ID, MessageId.class); r.removeObjectReader(Types.MESSAGE_ID); } - // Read the group - r.addObjectReader(Types.GROUP, groupReader); - Group group = r.readUserDefined(Types.GROUP, Group.class); - r.removeObjectReader(Types.GROUP); + // Read the group, if there is one + Group group = null; + if(r.hasNull()) { + r.readNull(); + } else { + r.addObjectReader(Types.GROUP, groupReader); + group = r.readUserDefined(Types.GROUP, Group.class); + r.removeObjectReader(Types.GROUP); + } // Read the author, if there is one Author author = null; if(r.hasNull()) { @@ -85,7 +91,7 @@ class MessageReader implements ObjectReader<Message> { int signedByGroup = (int) counting.getCount(); // Read the group's signature, if there is one byte[] groupSig = null; - if(group.getPublicKey() == null) r.readNull(); + if(group == null || group.getPublicKey() == null) r.readNull(); else groupSig = r.readBytes(Message.MAX_SIGNATURE_LENGTH); // That's all, folks r.removeConsumer(counting); @@ -103,7 +109,7 @@ class MessageReader implements ObjectReader<Message> { } } // Verify the group's signature, if there is one - if(group.getPublicKey() != null) { + if(group != null && group.getPublicKey() != null) { try { PublicKey k = keyParser.parsePublicKey(group.getPublicKey()); signature.initVerify(k); @@ -118,7 +124,7 @@ class MessageReader implements ObjectReader<Message> { messageDigest.update(raw); MessageId id = new MessageId(messageDigest.digest()); AuthorId authorId = author == null ? null : author.getId(); - return new MessageImpl(id, parent, group.getId(), authorId, timestamp, - raw); + GroupId groupId = group == null ? null : group.getId(); + return new MessageImpl(id, parent, groupId, authorId, timestamp, raw); } }