Implement MessageEncoder and MessageParser

This commit is contained in:
Torsten Grote
2018-04-17 18:13:35 -03:00
parent 155c6a5613
commit 672a52b2e5
13 changed files with 844 additions and 20 deletions

View File

@@ -41,6 +41,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
private final String text =
getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
private final BdfDictionary meta = new BdfDictionary();
private final long acceptTimestamp = 42;
private final BdfDictionary transportProperties = BdfDictionary.of(
new BdfEntry("transportId", new BdfDictionary())
);
@@ -124,7 +125,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testAcceptsAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
transportProperties);
acceptTimestamp, transportProperties);
context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateTransportProperties(
transportProperties.getDictionary("transportId"));
@@ -140,7 +141,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testRejectsTooShortBodyForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp);
validator.validateMessage(message, group, body);
}
@@ -148,7 +149,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testRejectsTooLongBodyForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
transportProperties, null);
acceptTimestamp, transportProperties, null);
validator.validateMessage(message, group, body);
}
@@ -156,7 +157,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testRejectsInvalidSessionIdForAccept() throws Exception {
BdfList body =
BdfList.of(ACCEPT.getValue(), null, previousMsgId.getBytes(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp,
transportProperties);
validator.validateMessage(message, group, body);
}
@@ -164,7 +165,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class)
public void testRejectsInvalidPreviousMsgIdForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
null, getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
null, getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp,
transportProperties);
validator.validateMessage(message, group, body);
}
@@ -173,7 +174,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testRejectsTooLongPublicKeyForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), transportProperties);
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), acceptTimestamp,
transportProperties);
validator.validateMessage(message, group, body);
}
@@ -182,7 +184,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), new BdfDictionary());
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), acceptTimestamp,
new BdfDictionary());
validator.validateMessage(message, group, body);
}
@@ -397,9 +400,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
private void expectEncodeRequestMetadata() {
context.checking(new Expectations() {{
oneOf(messageEncoder)
.encodeRequestMetadata(REQUEST, message.getTimestamp(),
false, false,
false, false, false);
.encodeRequestMetadata(message.getTimestamp(), false, false,
false, false);
will(returnValue(meta));
}});
}

View File

@@ -0,0 +1,231 @@
package org.briarproject.briar.introduction2;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties;
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.test.BrambleTestCase;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
import org.junit.Test;
import java.util.Map;
import javax.inject.Inject;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_MESSAGE_LENGTH;
import static org.briarproject.briar.introduction2.MessageType.ABORT;
import static org.briarproject.briar.introduction2.MessageType.REQUEST;
import static org.briarproject.briar.test.BriarTestUtils.getRealAuthor;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
@Inject
ClientHelper clientHelper;
@Inject
MessageFactory messageFactory;
@Inject
AuthorFactory authorFactory;
private final MessageEncoder messageEncoder;
private final MessageParser messageParser;
private final GroupId groupId = new GroupId(getRandomId());
private final long timestamp = 42L;
private final SessionId sessionId = new SessionId(getRandomId());
private final MessageId previousMsgId = new MessageId(getRandomId());
private final Author author;
private final String text =
getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
private final byte[] ephemeralPublicKey =
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final byte[] mac = getRandomBytes(MAC_BYTES);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES);
public MessageEncoderParserIntegrationTest() {
BriarIntegrationTestComponent component =
DaggerBriarIntegrationTestComponent.builder().build();
component.inject(this);
messageEncoder = new MessageEncoderImpl(clientHelper, messageFactory);
messageParser = new MessageParserImpl(clientHelper);
author = getRealAuthor(authorFactory);
}
@Test
public void testRequestMessageMetadata() throws FormatException {
BdfDictionary d = messageEncoder
.encodeRequestMetadata(timestamp, true, false, false,
true);
MessageMetadata meta = messageParser.parseMetadata(d);
assertEquals(REQUEST, meta.getMessageType());
assertNull(meta.getSessionId());
assertEquals(timestamp, meta.getTimestamp());
assertTrue(meta.isLocal());
assertFalse(meta.isRead());
assertFalse(meta.isVisibleInConversation());
assertFalse(meta.isAvailableToAnswer());
assertTrue(meta.wasAccepted());
}
@Test
public void testMessageMetadata() throws FormatException {
BdfDictionary d = messageEncoder
.encodeMetadata(ABORT, sessionId, timestamp, false, true,
false);
MessageMetadata meta = messageParser.parseMetadata(d);
assertEquals(ABORT, meta.getMessageType());
assertEquals(sessionId, meta.getSessionId());
assertEquals(timestamp, meta.getTimestamp());
assertFalse(meta.isLocal());
assertTrue(meta.isRead());
assertFalse(meta.isVisibleInConversation());
assertFalse(meta.isAvailableToAnswer());
assertFalse(meta.wasAccepted());
}
@Test
public void testRequestMessage() throws FormatException {
Message m = messageEncoder
.encodeRequestMessage(groupId, timestamp, previousMsgId, author,
text);
RequestMessage rm =
messageParser.parseRequestMessage(m, clientHelper.toList(m));
assertEquals(m.getId(), rm.getMessageId());
assertEquals(m.getGroupId(), rm.getGroupId());
assertEquals(m.getTimestamp(), rm.getTimestamp());
assertEquals(previousMsgId, rm.getPreviousMessageId());
assertEquals(author, rm.getAuthor());
assertEquals(text, rm.getMessage());
}
@Test
public void testRequestMessageWithPreviousMsgNull() throws FormatException {
Message m = messageEncoder
.encodeRequestMessage(groupId, timestamp, null, author, text);
RequestMessage rm =
messageParser.parseRequestMessage(m, clientHelper.toList(m));
assertNull(rm.getPreviousMessageId());
}
@Test
public void testRequestMessageWithMsgNull() throws FormatException {
Message m = messageEncoder
.encodeRequestMessage(groupId, timestamp, previousMsgId, author,
null);
RequestMessage rm =
messageParser.parseRequestMessage(m, clientHelper.toList(m));
assertNull(rm.getMessage());
}
@Test
public void testAcceptMessage() throws Exception {
Map<TransportId, TransportProperties> transportProperties =
getTransportPropertiesMap(2);
long acceptTimestamp = 1337L;
Message m = messageEncoder
.encodeAcceptMessage(groupId, timestamp, previousMsgId,
sessionId, ephemeralPublicKey, acceptTimestamp,
transportProperties);
AcceptMessage rm =
messageParser.parseAcceptMessage(m, clientHelper.toList(m));
assertEquals(m.getId(), rm.getMessageId());
assertEquals(m.getGroupId(), rm.getGroupId());
assertEquals(m.getTimestamp(), rm.getTimestamp());
assertEquals(previousMsgId, rm.getPreviousMessageId());
assertEquals(sessionId, rm.getSessionId());
assertArrayEquals(ephemeralPublicKey, rm.getEphemeralPublicKey());
assertEquals(acceptTimestamp, rm.getAcceptTimestamp());
assertEquals(transportProperties, rm.getTransportProperties());
}
@Test
public void testDeclineMessage() throws Exception {
Message m = messageEncoder
.encodeDeclineMessage(groupId, timestamp, previousMsgId,
sessionId);
DeclineMessage rm =
messageParser.parseDeclineMessage(m, clientHelper.toList(m));
assertEquals(m.getId(), rm.getMessageId());
assertEquals(m.getGroupId(), rm.getGroupId());
assertEquals(m.getTimestamp(), rm.getTimestamp());
assertEquals(previousMsgId, rm.getPreviousMessageId());
assertEquals(sessionId, rm.getSessionId());
}
@Test
public void testAuthMessage() throws Exception {
Message m = messageEncoder
.encodeAuthMessage(groupId, timestamp, previousMsgId,
sessionId, mac, signature);
AuthMessage rm =
messageParser.parseAuthMessage(m, clientHelper.toList(m));
assertEquals(m.getId(), rm.getMessageId());
assertEquals(m.getGroupId(), rm.getGroupId());
assertEquals(m.getTimestamp(), rm.getTimestamp());
assertEquals(previousMsgId, rm.getPreviousMessageId());
assertEquals(sessionId, rm.getSessionId());
assertArrayEquals(mac, rm.getMac());
assertArrayEquals(signature, rm.getSignature());
}
@Test
public void testActivateMessage() throws Exception {
Message m = messageEncoder
.encodeActivateMessage(groupId, timestamp, previousMsgId,
sessionId);
ActivateMessage rm =
messageParser.parseActivateMessage(m, clientHelper.toList(m));
assertEquals(m.getId(), rm.getMessageId());
assertEquals(m.getGroupId(), rm.getGroupId());
assertEquals(m.getTimestamp(), rm.getTimestamp());
assertEquals(previousMsgId, rm.getPreviousMessageId());
assertEquals(sessionId, rm.getSessionId());
}
@Test
public void testAbortMessage() throws Exception {
Message m = messageEncoder
.encodeAbortMessage(groupId, timestamp, previousMsgId,
sessionId);
AbortMessage rm =
messageParser.parseAbortMessage(m, clientHelper.toList(m));
assertEquals(m.getId(), rm.getMessageId());
assertEquals(m.getGroupId(), rm.getGroupId());
assertEquals(m.getTimestamp(), rm.getTimestamp());
assertEquals(previousMsgId, rm.getPreviousMessageId());
assertEquals(sessionId, rm.getSessionId());
}
}

View File

@@ -0,0 +1,63 @@
package org.briarproject.briar.introduction2;
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.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.test.BrambleMockTestCase;
import org.jmock.Expectations;
import org.junit.Test;
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.MAX_INTRODUCTION_MESSAGE_LENGTH;
import static org.briarproject.briar.introduction2.MessageType.REQUEST;
public class MessageEncoderTest extends BrambleMockTestCase {
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final MessageFactory messageFactory =
context.mock(MessageFactory.class);
private final MessageEncoder messageEncoder =
new MessageEncoderImpl(clientHelper, messageFactory);
private final GroupId groupId = new GroupId(getRandomId());
private final long timestamp = 42L;
private final Message message =
new Message(new MessageId(getRandomId()), groupId, timestamp,
getRandomBytes(48));
private final byte[] body = getRandomBytes(42);
private final Author author = getAuthor();
private final BdfList authorList = new BdfList();
private final String text =
getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
@Test
public void testEncodeRequestMessage() throws FormatException {
context.checking(new Expectations() {{
oneOf(clientHelper).toList(author);
will(returnValue(authorList));
}});
expectCreateMessage(
BdfList.of(REQUEST.getValue(), null, authorList, text));
messageEncoder
.encodeRequestMessage(groupId, timestamp, null, author, text);
}
private void expectCreateMessage(BdfList bodyList) throws FormatException {
context.checking(new Expectations() {{
oneOf(clientHelper).toByteArray(bodyList);
will(returnValue(body));
oneOf(messageFactory).createMessage(groupId, timestamp, body);
will(returnValue(message));
}});
}
}

View File

@@ -37,6 +37,7 @@ import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.forum.ForumModule;
import org.briarproject.briar.introduction.IntroductionModule;
import org.briarproject.briar.introduction2.MessageEncoderParserIntegrationTest;
import org.briarproject.briar.messaging.MessagingModule;
import org.briarproject.briar.privategroup.PrivateGroupModule;
import org.briarproject.briar.privategroup.invitation.GroupInvitationModule;
@@ -76,6 +77,8 @@ public interface BriarIntegrationTestComponent {
void inject(BriarIntegrationTest<BriarIntegrationTestComponent> init);
void inject(MessageEncoderParserIntegrationTest init);
void inject(BlogModule.EagerSingletons init);
void inject(ContactModule.EagerSingletons init);

View File

@@ -1,10 +1,15 @@
package org.briarproject.briar.test;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertEquals;
public class BriarTestUtils {
@@ -25,4 +30,9 @@ public class BriarTestUtils {
assertEquals(unreadCount, c1.getUnreadCount());
}
public static Author getRealAuthor(AuthorFactory authorFactory) {
return authorFactory.createAuthor(getRandomString(5),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
}
}