mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Add tests for IntroductionManager and Validator
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
package org.briarproject.introduction;
|
||||
|
||||
import org.briarproject.BriarTestCase;
|
||||
import org.briarproject.TestUtils;
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfEntry;
|
||||
import org.briarproject.api.data.BdfList;
|
||||
import org.briarproject.api.data.MetadataEncoder;
|
||||
import org.briarproject.api.introduction.SessionId;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.briarproject.api.system.Clock;
|
||||
import org.briarproject.system.SystemClock;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ACCEPT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.E_PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MSG;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TRANSPORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
|
||||
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class IntroductionValidatorTest extends BriarTestCase {
|
||||
|
||||
private final Mockery context = new Mockery();
|
||||
private final Group group;
|
||||
private final Message message;
|
||||
private final IntroductionValidator validator;
|
||||
private final Clock clock = new SystemClock();
|
||||
|
||||
public IntroductionValidatorTest() {
|
||||
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||
ClientId clientId = new ClientId(TestUtils.getRandomId());
|
||||
byte[] descriptor = TestUtils.getRandomBytes(12);
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
|
||||
MessageId messageId = new MessageId(TestUtils.getRandomId());
|
||||
long timestamp = System.currentTimeMillis();
|
||||
byte[] raw = TestUtils.getRandomBytes(123);
|
||||
message = new Message(messageId, group.getId(), timestamp, raw);
|
||||
|
||||
|
||||
ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||
MetadataEncoder metadataEncoder = context.mock(MetadataEncoder.class);
|
||||
validator = new IntroductionValidator(clientHelper, metadataEncoder,
|
||||
clock);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
//
|
||||
// Introduction Requests
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateProperIntroductionRequest() throws IOException {
|
||||
final byte[] sessionId = TestUtils.getRandomId();
|
||||
final String name = TestUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
final byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
final String text = TestUtils.getRandomString(MAX_MESSAGE_BODY_LENGTH);
|
||||
|
||||
BdfList body = BdfList.of(TYPE_REQUEST, sessionId,
|
||||
name, publicKey, text);
|
||||
|
||||
final BdfDictionary result =
|
||||
validator.validateMessage(message, group, body);
|
||||
|
||||
assertEquals(Long.valueOf(TYPE_REQUEST), result.getLong(TYPE));
|
||||
assertEquals(sessionId, result.getRaw(SESSION_ID));
|
||||
assertEquals(name, result.getString(NAME));
|
||||
assertEquals(publicKey, result.getRaw(PUBLIC_KEY));
|
||||
assertEquals(text, result.getString(MSG));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionRequestWithNoName() throws IOException {
|
||||
BdfDictionary msg = getValidIntroductionRequest();
|
||||
|
||||
// no NAME is message
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getRaw(PUBLIC_KEY));
|
||||
if (msg.containsKey(MSG)) body.add(msg.getString(MSG));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionRequestWithLongName() throws IOException {
|
||||
// too long NAME in message
|
||||
BdfDictionary msg = getValidIntroductionRequest();
|
||||
msg.put(NAME, msg.get(NAME) + "x");
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getString(NAME), msg.getRaw(PUBLIC_KEY));
|
||||
if (msg.containsKey(MSG)) body.add(msg.getString(MSG));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionRequestWithWrongType()
|
||||
throws IOException {
|
||||
// wrong message type
|
||||
BdfDictionary msg = getValidIntroductionRequest();
|
||||
msg.put(TYPE, 324234);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getString(NAME), msg.getRaw(PUBLIC_KEY));
|
||||
if (msg.containsKey(MSG)) body.add(msg.getString(MSG));
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
private BdfDictionary getValidIntroductionRequest() throws FormatException {
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
String name = TestUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String text = TestUtils.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(MSG, text);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
//
|
||||
// Introduction Responses
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateIntroductionAcceptResponse() throws IOException {
|
||||
byte[] groupId = TestUtils.getRandomId();
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
long time = clock.currentTimeMillis();
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String transportId = TestUtils
|
||||
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
|
||||
BdfDictionary tProps = BdfDictionary.of(
|
||||
new BdfEntry(TestUtils.getRandomString(MAX_PROPERTY_LENGTH),
|
||||
TestUtils.getRandomString(MAX_PROPERTY_LENGTH))
|
||||
);
|
||||
BdfDictionary tp = BdfDictionary.of(
|
||||
new BdfEntry(transportId, tProps)
|
||||
);
|
||||
|
||||
BdfDictionary msg = new BdfDictionary();
|
||||
msg.put(TYPE, TYPE_RESPONSE);
|
||||
msg.put(GROUP_ID, groupId);
|
||||
msg.put(SESSION_ID, sessionId);
|
||||
msg.put(ACCEPT, true);
|
||||
msg.put(TIME, time);
|
||||
msg.put(E_PUBLIC_KEY, publicKey);
|
||||
msg.put(TRANSPORT, tp);
|
||||
|
||||
BdfList body = BdfList.of(TYPE_RESPONSE, msg.getRaw(SESSION_ID),
|
||||
msg.getBoolean(ACCEPT), msg.getLong(TIME),
|
||||
msg.getRaw(E_PUBLIC_KEY), msg.getDictionary(TRANSPORT));
|
||||
|
||||
final BdfDictionary result =
|
||||
validator.validateMessage(message, group, body);
|
||||
|
||||
assertEquals(Long.valueOf(TYPE_RESPONSE), result.getLong(TYPE));
|
||||
assertEquals(sessionId, result.getRaw(SESSION_ID));
|
||||
assertEquals(true, result.getBoolean(ACCEPT));
|
||||
assertEquals(publicKey, result.getRaw(E_PUBLIC_KEY));
|
||||
assertEquals(tp, result.getDictionary(TRANSPORT));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateIntroductionDeclineResponse()
|
||||
throws IOException {
|
||||
BdfDictionary msg = getValidIntroductionResponse(false);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getBoolean(ACCEPT));
|
||||
|
||||
BdfDictionary result = validator.validateMessage(message, group, body);
|
||||
|
||||
assertFalse(result.getBoolean(ACCEPT));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionResponseWithoutAccept()
|
||||
throws IOException {
|
||||
BdfDictionary msg = getValidIntroductionResponse(false);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionResponseWithBrokenTp()
|
||||
throws IOException {
|
||||
BdfDictionary msg = getValidIntroductionResponse(true);
|
||||
BdfDictionary tp = msg.getDictionary(TRANSPORT);
|
||||
tp.put(TestUtils
|
||||
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH), "X");
|
||||
msg.put(TRANSPORT, tp);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getBoolean(ACCEPT), msg.getLong(TIME),
|
||||
msg.getRaw(E_PUBLIC_KEY), msg.getDictionary(TRANSPORT));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionResponseWithoutPublicKey()
|
||||
throws IOException {
|
||||
BdfDictionary msg = getValidIntroductionResponse(true);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getBoolean(ACCEPT), msg.getLong(TIME),
|
||||
msg.getDictionary(TRANSPORT));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
private BdfDictionary getValidIntroductionResponse(boolean accept)
|
||||
throws FormatException {
|
||||
|
||||
byte[] groupId = TestUtils.getRandomId();
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
long time = clock.currentTimeMillis();
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String transportId = TestUtils
|
||||
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
|
||||
BdfDictionary tProps = BdfDictionary.of(
|
||||
new BdfEntry(TestUtils.getRandomString(MAX_PROPERTY_LENGTH),
|
||||
TestUtils.getRandomString(MAX_PROPERTY_LENGTH))
|
||||
);
|
||||
BdfDictionary tp = BdfDictionary.of(
|
||||
new BdfEntry(transportId, tProps)
|
||||
);
|
||||
|
||||
BdfDictionary msg = new BdfDictionary();
|
||||
msg.put(TYPE, TYPE_RESPONSE);
|
||||
msg.put(GROUP_ID, groupId);
|
||||
msg.put(SESSION_ID, sessionId);
|
||||
msg.put(ACCEPT, accept);
|
||||
if (accept) {
|
||||
msg.put(TIME, time);
|
||||
msg.put(E_PUBLIC_KEY, publicKey);
|
||||
msg.put(TRANSPORT, tp);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
//
|
||||
// Introduction ACK
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateProperIntroductionAck() throws IOException {
|
||||
final byte[] sessionId = TestUtils.getRandomId();
|
||||
|
||||
BdfDictionary msg = new BdfDictionary();
|
||||
msg.put(TYPE, TYPE_ACK);
|
||||
msg.put(SESSION_ID, sessionId);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID));
|
||||
|
||||
BdfDictionary result =
|
||||
validator.validateMessage(message, group, body);
|
||||
|
||||
assertEquals(Long.valueOf(TYPE_ACK), result.getLong(TYPE));
|
||||
assertEquals(sessionId, result.getRaw(SESSION_ID));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateTooLongIntroductionAck() throws IOException {
|
||||
BdfDictionary msg = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ACK),
|
||||
new BdfEntry(SESSION_ID, TestUtils.getRandomId()),
|
||||
new BdfEntry("garbage", TestUtils.getRandomString(255))
|
||||
);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getString("garbage"));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionAckWithLongSessionId() throws IOException {
|
||||
BdfDictionary msg = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ACK),
|
||||
new BdfEntry(SESSION_ID, new byte[SessionId.LENGTH + 1])
|
||||
);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
//
|
||||
// Introduction Abort
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateProperIntroductionAbort() throws IOException {
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
|
||||
BdfDictionary msg = new BdfDictionary();
|
||||
msg.put(TYPE, TYPE_ABORT);
|
||||
msg.put(SESSION_ID, sessionId);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID));
|
||||
|
||||
BdfDictionary result =
|
||||
validator.validateMessage(message, group, body);
|
||||
|
||||
assertEquals(Long.valueOf(TYPE_ABORT), result.getLong(TYPE));
|
||||
assertEquals(sessionId, result.getRaw(SESSION_ID));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateTooLongIntroductionAbort() throws IOException {
|
||||
BdfDictionary msg = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ABORT),
|
||||
new BdfEntry(SESSION_ID, TestUtils.getRandomId()),
|
||||
new BdfEntry("garbage", TestUtils.getRandomString(255))
|
||||
);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getString("garbage"));
|
||||
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user