mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Implement SessionEncoder and SessionParser
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.briar.api.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public enum Role {
|
||||
|
||||
INTRODUCER(0), INTRODUCEE(1);
|
||||
|
||||
private final int value;
|
||||
|
||||
Role(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Role fromValue(int value) throws FormatException {
|
||||
for (Role r : values()) if (r.value == value) return r;
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
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.MessageId;
|
||||
import org.briarproject.bramble.api.transport.KeySetId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction2.Role;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.briar.introduction2.IntroduceeState.AWAIT_ACTIVATE;
|
||||
import static org.briarproject.briar.introduction2.IntroduceeState.START;
|
||||
import static org.briarproject.briar.api.introduction2.Role.INTRODUCEE;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class IntroduceeSession extends Session<IntroduceeState>
|
||||
implements PeerSession {
|
||||
|
||||
private final GroupId contactGroupId;
|
||||
private final long localTimestamp, acceptTimestamp, remoteAcceptTimestamp;
|
||||
@Nullable
|
||||
private final MessageId lastLocalMessageId, lastRemoteMessageId;
|
||||
private final Author introducer, remoteAuthor;
|
||||
@Nullable
|
||||
private final byte[] ephemeralPublicKey, ephemeralPrivateKey;
|
||||
@Nullable
|
||||
private final byte[] masterKey, remoteEphemeralPublicKey;
|
||||
@Nullable
|
||||
private final Map<TransportId, TransportProperties> transportProperties;
|
||||
@Nullable
|
||||
private final Map<TransportId, TransportProperties>
|
||||
remoteTransportProperties;
|
||||
@Nullable
|
||||
private final Map<TransportId, KeySetId> transportKeys;
|
||||
|
||||
IntroduceeSession(SessionId sessionId, IntroduceeState state,
|
||||
long requestTimestamp, GroupId contactGroupId,
|
||||
@Nullable MessageId lastLocalMessageId, long localTimestamp,
|
||||
@Nullable MessageId lastRemoteMessageId, Author introducer,
|
||||
@Nullable byte[] ephemeralPublicKey,
|
||||
@Nullable byte[] ephemeralPrivateKey,
|
||||
@Nullable Map<TransportId, TransportProperties> transportProperties,
|
||||
long acceptTimestamp, @Nullable byte[] masterKey,
|
||||
Author remoteAuthor,
|
||||
@Nullable byte[] remoteEphemeralPublicKey, @Nullable
|
||||
Map<TransportId, TransportProperties> remoteTransportProperties,
|
||||
long remoteAcceptTimestamp,
|
||||
@Nullable Map<TransportId, KeySetId> transportKeys) {
|
||||
super(sessionId, state, requestTimestamp);
|
||||
this.contactGroupId = contactGroupId;
|
||||
this.lastLocalMessageId = lastLocalMessageId;
|
||||
this.localTimestamp = localTimestamp;
|
||||
this.lastRemoteMessageId = lastRemoteMessageId;
|
||||
this.introducer = introducer;
|
||||
this.ephemeralPublicKey = ephemeralPublicKey;
|
||||
this.ephemeralPrivateKey = ephemeralPrivateKey;
|
||||
this.transportProperties = transportProperties;
|
||||
this.acceptTimestamp = acceptTimestamp;
|
||||
this.masterKey = masterKey;
|
||||
this.remoteAuthor = remoteAuthor;
|
||||
this.remoteEphemeralPublicKey = remoteEphemeralPublicKey;
|
||||
this.remoteTransportProperties = remoteTransportProperties;
|
||||
this.remoteAcceptTimestamp = remoteAcceptTimestamp;
|
||||
this.transportKeys = transportKeys;
|
||||
}
|
||||
|
||||
static IntroduceeSession getInitial(GroupId contactGroupId,
|
||||
SessionId sessionId, Author introducer, Author remoteAuthor) {
|
||||
return new IntroduceeSession(sessionId, START, -1, contactGroupId, null,
|
||||
-1, null, introducer, null, null, null, -1, null, remoteAuthor,
|
||||
null, null, -1, null);
|
||||
}
|
||||
|
||||
static IntroduceeSession addRemoteRequest(IntroduceeSession s,
|
||||
IntroduceeState state, RequestMessage m) {
|
||||
return new IntroduceeSession(s.getSessionId(), state, m.getTimestamp(),
|
||||
s.contactGroupId, s.lastLocalMessageId, s.localTimestamp,
|
||||
m.getMessageId(), s.introducer, s.ephemeralPublicKey,
|
||||
s.ephemeralPrivateKey, s.transportProperties, s.acceptTimestamp,
|
||||
s.masterKey, s.remoteAuthor, s.remoteEphemeralPublicKey,
|
||||
s.remoteTransportProperties, s.remoteAcceptTimestamp,
|
||||
s.transportKeys);
|
||||
}
|
||||
|
||||
static IntroduceeSession addLocalAccept(IntroduceeSession s,
|
||||
IntroduceeState state, Message acceptMessage,
|
||||
byte[] ephemeralPublicKey, byte[] ephemeralPrivateKey,
|
||||
long acceptTimestamp,
|
||||
Map<TransportId, TransportProperties> transportProperties) {
|
||||
return new IntroduceeSession(s.getSessionId(), state,
|
||||
s.getRequestTimestamp(), s.contactGroupId,
|
||||
acceptMessage.getId(), acceptMessage.getTimestamp(),
|
||||
s.lastRemoteMessageId, s.introducer, ephemeralPublicKey,
|
||||
ephemeralPrivateKey, transportProperties,
|
||||
acceptTimestamp, s.masterKey, s.remoteAuthor,
|
||||
s.remoteEphemeralPublicKey, s.remoteTransportProperties,
|
||||
s.remoteAcceptTimestamp, s.transportKeys);
|
||||
}
|
||||
|
||||
static IntroduceeSession addRemoteAccept(IntroduceeSession s,
|
||||
IntroduceeState state, AcceptMessage acceptMessage) {
|
||||
return new IntroduceeSession(s.getSessionId(), state,
|
||||
s.getRequestTimestamp(), s.contactGroupId, s.lastLocalMessageId,
|
||||
s.localTimestamp, acceptMessage.getMessageId(), s.introducer,
|
||||
s.ephemeralPublicKey, s.ephemeralPrivateKey,
|
||||
s.transportProperties, s.acceptTimestamp, s.masterKey,
|
||||
s.remoteAuthor, acceptMessage.getEphemeralPublicKey(),
|
||||
acceptMessage.getTransportProperties(),
|
||||
acceptMessage.getAcceptTimestamp(), s.transportKeys);
|
||||
}
|
||||
|
||||
static IntroduceeSession addLocalAuth(IntroduceeSession s,
|
||||
IntroduceeState state, SecretKey masterKey, Message m) {
|
||||
return new IntroduceeSession(s.getSessionId(), state,
|
||||
s.getRequestTimestamp(), s.contactGroupId, m.getId(),
|
||||
m.getTimestamp(), s.lastRemoteMessageId, s.introducer,
|
||||
s.ephemeralPublicKey, s.ephemeralPrivateKey,
|
||||
s.transportProperties, s.acceptTimestamp, masterKey.getBytes(),
|
||||
s.remoteAuthor, s.remoteEphemeralPublicKey,
|
||||
s.remoteTransportProperties, s.remoteAcceptTimestamp,
|
||||
s.transportKeys);
|
||||
}
|
||||
|
||||
static IntroduceeSession awaitActivate(IntroduceeSession s, AuthMessage m,
|
||||
Message sent, Map<TransportId, KeySetId> transportKeys) {
|
||||
return new IntroduceeSession(s.getSessionId(), AWAIT_ACTIVATE,
|
||||
s.getRequestTimestamp(), s.contactGroupId, sent.getId(),
|
||||
sent.getTimestamp(), m.getMessageId(), s.introducer, null, null,
|
||||
null, s.acceptTimestamp, null, s.getRemoteAuthor(), null, null,
|
||||
s.remoteAcceptTimestamp, transportKeys);
|
||||
}
|
||||
|
||||
static IntroduceeSession clear(IntroduceeSession s,
|
||||
@Nullable MessageId lastLocalMessageId, long localTimestamp,
|
||||
@Nullable MessageId lastRemoteMessageId) {
|
||||
return new IntroduceeSession(s.getSessionId(), START,
|
||||
s.getRequestTimestamp(), s.getContactGroupId(),
|
||||
lastLocalMessageId, localTimestamp, lastRemoteMessageId,
|
||||
s.getIntroducer(), null, null, null, -1, null,
|
||||
s.getRemoteAuthor(), null, null, -1, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
Role getRole() {
|
||||
return INTRODUCEE;
|
||||
}
|
||||
|
||||
public GroupId getContactGroupId() {
|
||||
return contactGroupId;
|
||||
}
|
||||
|
||||
public long getLocalTimestamp() {
|
||||
return localTimestamp;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MessageId getLastLocalMessageId() {
|
||||
return lastLocalMessageId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MessageId getLastRemoteMessageId() {
|
||||
return lastRemoteMessageId;
|
||||
}
|
||||
|
||||
Author getIntroducer() {
|
||||
return introducer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
byte[] getEphemeralPublicKey() {
|
||||
return ephemeralPublicKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
byte[] getEphemeralPrivateKey() {
|
||||
return ephemeralPrivateKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Map<TransportId, TransportProperties> getTransportProperties() {
|
||||
return transportProperties;
|
||||
}
|
||||
|
||||
long getAcceptTimestamp() {
|
||||
return acceptTimestamp;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
byte[] getMasterKey() {
|
||||
return masterKey;
|
||||
}
|
||||
|
||||
Author getRemoteAuthor() {
|
||||
return remoteAuthor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
byte[] getRemotePublicKey() {
|
||||
return remoteEphemeralPublicKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Map<TransportId, TransportProperties> getRemoteTransportProperties() {
|
||||
return remoteTransportProperties;
|
||||
}
|
||||
|
||||
long getRemoteAcceptTimestamp() {
|
||||
return remoteAcceptTimestamp;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Map<TransportId, KeySetId> getTransportKeys() {
|
||||
return transportKeys;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
enum IntroduceeState implements State {
|
||||
|
||||
START(0),
|
||||
AWAIT_RESPONSES(1),
|
||||
LOCAL_DECLINED(2),
|
||||
LOCAL_ACCEPTED(3),
|
||||
REMOTE_ACCEPTED(4),
|
||||
AWAIT_AUTH(5),
|
||||
AWAIT_ACTIVATE(6);
|
||||
|
||||
private final int value;
|
||||
|
||||
IntroduceeState(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
static IntroduceeState fromValue(int value) throws FormatException {
|
||||
for (IntroduceeState s : values()) if (s.value == value) return s;
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction2.Role;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.briar.api.introduction2.Role.INTRODUCER;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class IntroducerSession extends Session<IntroducerState> {
|
||||
|
||||
private final Introducee introducee1, introducee2;
|
||||
|
||||
IntroducerSession(SessionId sessionId, IntroducerState state,
|
||||
long requestTimestamp, Introducee introducee1,
|
||||
Introducee introducee2) {
|
||||
super(sessionId, state, requestTimestamp);
|
||||
this.introducee1 = introducee1;
|
||||
this.introducee2 = introducee2;
|
||||
}
|
||||
|
||||
IntroducerSession(SessionId sessionId, GroupId groupId1, Author author1,
|
||||
GroupId groupId2, Author author2) {
|
||||
this(sessionId, IntroducerState.START, -1,
|
||||
new Introducee(sessionId, groupId1, author1),
|
||||
new Introducee(sessionId, groupId2, author2));
|
||||
}
|
||||
|
||||
@Override
|
||||
Role getRole() {
|
||||
return INTRODUCER;
|
||||
}
|
||||
|
||||
Introducee getIntroducee1() {
|
||||
return introducee1;
|
||||
}
|
||||
|
||||
Introducee getIntroducee2() {
|
||||
return introducee2;
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
static class Introducee implements PeerSession {
|
||||
final SessionId sessionId;
|
||||
final GroupId groupId;
|
||||
final Author author;
|
||||
final long localTimestamp;
|
||||
@Nullable
|
||||
final MessageId lastLocalMessageId, lastRemoteMessageId;
|
||||
|
||||
Introducee(SessionId sessionId, GroupId groupId, Author author,
|
||||
long localTimestamp,
|
||||
@Nullable MessageId lastLocalMessageId,
|
||||
@Nullable MessageId lastRemoteMessageId) {
|
||||
this.sessionId = sessionId;
|
||||
this.groupId = groupId;
|
||||
this.localTimestamp = localTimestamp;
|
||||
this.author = author;
|
||||
this.lastLocalMessageId = lastLocalMessageId;
|
||||
this.lastRemoteMessageId = lastRemoteMessageId;
|
||||
}
|
||||
|
||||
Introducee(Introducee i, Message sent) {
|
||||
this(i.sessionId, i.groupId, i.author, sent.getTimestamp(),
|
||||
sent.getId(), i.lastRemoteMessageId);
|
||||
}
|
||||
|
||||
Introducee(Introducee i, MessageId remoteMessageId) {
|
||||
this(i.sessionId, i.groupId, i.author, i.localTimestamp,
|
||||
i.lastLocalMessageId, remoteMessageId);
|
||||
}
|
||||
|
||||
private Introducee(SessionId sessionId, GroupId groupId,
|
||||
Author author) {
|
||||
this(sessionId, groupId, author, -1, null, null);
|
||||
}
|
||||
|
||||
public SessionId getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupId getContactGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLocalTimestamp() {
|
||||
return localTimestamp;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MessageId getLastLocalMessageId() {
|
||||
return lastLocalMessageId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MessageId getLastRemoteMessageId() {
|
||||
return lastRemoteMessageId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
enum IntroducerState implements State {
|
||||
|
||||
START(0),
|
||||
AWAIT_RESPONSES(1),
|
||||
AWAIT_RESPONSE_A(2), AWAIT_RESPONSE_B(3),
|
||||
AWAIT_AUTHS(4),
|
||||
AWAIT_AUTH_A(5), AWAIT_AUTH_B(6),
|
||||
AWAIT_ACTIVATES(7),
|
||||
AWAIT_ACTIVATE_A(8), AWAIT_ACTIVATE_B(9);
|
||||
|
||||
private final int value;
|
||||
|
||||
IntroducerState(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
static IntroducerState fromValue(int value) throws FormatException {
|
||||
for (IntroducerState s : values()) if (s.value == value) return s;
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,4 +11,33 @@ interface IntroductionConstants {
|
||||
String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer";
|
||||
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
|
||||
|
||||
// Session Keys
|
||||
String SESSION_KEY_SESSION_ID = "sessionId";
|
||||
String SESSION_KEY_ROLE = "role";
|
||||
String SESSION_KEY_STATE = "state";
|
||||
String SESSION_KEY_REQUEST_TIMESTAMP = "requestTimestamp";
|
||||
String SESSION_KEY_LOCAL_TIMESTAMP = "localTimestamp";
|
||||
String SESSION_KEY_LAST_LOCAL_MESSAGE_ID = "lastLocalMessageId";
|
||||
String SESSION_KEY_LAST_REMOTE_MESSAGE_ID = "lastRemoteMessageId";
|
||||
|
||||
// Session Keys Introducer
|
||||
String SESSION_KEY_INTRODUCEE_1 = "introducee1";
|
||||
String SESSION_KEY_INTRODUCEE_2 = "introducee2";
|
||||
String SESSION_KEY_GROUP_ID = "groupId";
|
||||
String SESSION_KEY_AUTHOR = "author";
|
||||
|
||||
// Session Keys Introducee
|
||||
String SESSION_KEY_INTRODUCER = "introducer";
|
||||
String SESSION_KEY_EPHEMERAL_PUBLIC_KEY = "ephemeralPublicKey";
|
||||
String SESSION_KEY_EPHEMERAL_PRIVATE_KEY = "ephemeralPrivateKey";
|
||||
String SESSION_KEY_TRANSPORT_PROPERTIES = "transportProperties";
|
||||
String SESSION_KEY_ACCEPT_TIMESTAMP = "acceptTimestamp";
|
||||
String SESSION_KEY_MASTER_KEY = "masterKey";
|
||||
String SESSION_KEY_REMOTE_AUTHOR = "remoteAuthor";
|
||||
String SESSION_KEY_REMOTE_EPHEMERAL_PUBLIC_KEY = "remoteEphemeralPublicKey";
|
||||
String SESSION_KEY_REMOTE_TRANSPORT_PROPERTIES =
|
||||
"remoteTransportProperties";
|
||||
String SESSION_KEY_REMOTE_ACCEPT_TIMESTAMP = "remoteAcceptTimestamp";
|
||||
String SESSION_KEY_TRANSPORT_KEYS = "transportKeys";
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
interface PeerSession {
|
||||
|
||||
SessionId getSessionId();
|
||||
|
||||
GroupId getContactGroupId();
|
||||
|
||||
long getLocalTimestamp();
|
||||
|
||||
@Nullable
|
||||
MessageId getLastLocalMessageId();
|
||||
|
||||
@Nullable
|
||||
MessageId getLastRemoteMessageId();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction2.Role;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
abstract class Session<S extends State> {
|
||||
|
||||
private final SessionId sessionId;
|
||||
private final S state;
|
||||
private long requestTimestamp;
|
||||
|
||||
Session(SessionId sessionId, S state, long requestTimestamp) {
|
||||
this.sessionId = sessionId;
|
||||
this.state = state;
|
||||
this.requestTimestamp = requestTimestamp;
|
||||
}
|
||||
|
||||
abstract Role getRole();
|
||||
|
||||
public SessionId getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
S getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public long getRequestTimestamp() {
|
||||
return requestTimestamp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
interface SessionEncoder {
|
||||
|
||||
BdfDictionary encodeIntroducerSession(IntroducerSession s);
|
||||
|
||||
BdfDictionary encodeIntroduceeSession(IntroduceeSession s);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.transport.KeySetId;
|
||||
import org.briarproject.briar.introduction2.IntroducerSession.Introducee;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_ACCEPT_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_AUTHOR;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_EPHEMERAL_PRIVATE_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_EPHEMERAL_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_GROUP_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_INTRODUCEE_1;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_INTRODUCEE_2;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_INTRODUCER;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_LAST_LOCAL_MESSAGE_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_LAST_REMOTE_MESSAGE_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_LOCAL_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_MASTER_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_ACCEPT_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_AUTHOR;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_EPHEMERAL_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_TRANSPORT_PROPERTIES;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REQUEST_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_ROLE;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_SESSION_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_STATE;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_TRANSPORT_KEYS;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_TRANSPORT_PROPERTIES;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class SessionEncoderImpl implements SessionEncoder {
|
||||
|
||||
private final ClientHelper clientHelper;
|
||||
|
||||
@Inject
|
||||
SessionEncoderImpl(ClientHelper clientHelper) {
|
||||
this.clientHelper = clientHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary encodeIntroducerSession(IntroducerSession s) {
|
||||
BdfDictionary d = encodeSession(s);
|
||||
d.put(SESSION_KEY_INTRODUCEE_1, encodeIntroducee(s.getIntroducee1()));
|
||||
d.put(SESSION_KEY_INTRODUCEE_2, encodeIntroducee(s.getIntroducee2()));
|
||||
return d;
|
||||
}
|
||||
|
||||
private BdfDictionary encodeIntroducee(Introducee i) {
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
putNullable(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID, i.lastLocalMessageId);
|
||||
putNullable(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID,
|
||||
i.lastRemoteMessageId);
|
||||
d.put(SESSION_KEY_LOCAL_TIMESTAMP, i.localTimestamp);
|
||||
d.put(SESSION_KEY_GROUP_ID, i.groupId);
|
||||
d.put(SESSION_KEY_AUTHOR, clientHelper.toList(i.author));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary encodeIntroduceeSession(IntroduceeSession s) {
|
||||
BdfDictionary d = encodeSession(s);
|
||||
d.put(SESSION_KEY_LOCAL_TIMESTAMP, s.getLocalTimestamp());
|
||||
putNullable(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID,
|
||||
s.getLastLocalMessageId());
|
||||
putNullable(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID,
|
||||
s.getLastRemoteMessageId());
|
||||
d.put(SESSION_KEY_INTRODUCER, clientHelper.toList(s.getIntroducer()));
|
||||
d.put(SESSION_KEY_REMOTE_AUTHOR,
|
||||
clientHelper.toList(s.getRemoteAuthor()));
|
||||
putNullable(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY,
|
||||
s.getEphemeralPublicKey());
|
||||
putNullable(d, SESSION_KEY_EPHEMERAL_PRIVATE_KEY,
|
||||
s.getEphemeralPrivateKey());
|
||||
putNullable(d, SESSION_KEY_TRANSPORT_PROPERTIES,
|
||||
s.getTransportProperties() == null ? null :
|
||||
clientHelper.toDictionary(s.getTransportProperties()));
|
||||
d.put(SESSION_KEY_ACCEPT_TIMESTAMP, s.getAcceptTimestamp());
|
||||
putNullable(d, SESSION_KEY_MASTER_KEY, s.getMasterKey());
|
||||
putNullable(d, SESSION_KEY_REMOTE_EPHEMERAL_PUBLIC_KEY,
|
||||
s.getRemotePublicKey());
|
||||
putNullable(d, SESSION_KEY_REMOTE_TRANSPORT_PROPERTIES,
|
||||
s.getRemoteTransportProperties() == null ? null : clientHelper
|
||||
.toDictionary(s.getRemoteTransportProperties()));
|
||||
d.put(SESSION_KEY_REMOTE_ACCEPT_TIMESTAMP, s.getRemoteAcceptTimestamp());
|
||||
putNullable(d, SESSION_KEY_TRANSPORT_KEYS,
|
||||
encodeTransportKeys(s.getTransportKeys()));
|
||||
return d;
|
||||
}
|
||||
|
||||
private BdfDictionary encodeSession(Session s) {
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
d.put(SESSION_KEY_SESSION_ID, s.getSessionId());
|
||||
d.put(SESSION_KEY_ROLE, s.getRole().getValue());
|
||||
d.put(SESSION_KEY_STATE, s.getState().getValue());
|
||||
d.put(SESSION_KEY_REQUEST_TIMESTAMP, s.getRequestTimestamp());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BdfDictionary encodeTransportKeys(
|
||||
@Nullable Map<TransportId, KeySetId> keys) {
|
||||
if (keys == null) return null;
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
for (Map.Entry<TransportId, KeySetId> e : keys.entrySet()) {
|
||||
d.put(e.getKey().getString(), e.getValue().getInt());
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private void putNullable(BdfDictionary d, String key, @Nullable Object o) {
|
||||
d.put(key, o == null ? NULL_VALUE : o);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction2.Role;
|
||||
|
||||
@NotNullByDefault
|
||||
interface SessionParser {
|
||||
|
||||
BdfDictionary getSessionQuery(SessionId s);
|
||||
|
||||
Role getRole(BdfDictionary d) throws FormatException;
|
||||
|
||||
IntroducerSession parseIntroducerSession(BdfDictionary d)
|
||||
throws FormatException;
|
||||
|
||||
IntroduceeSession parseIntroduceeSession(GroupId introducerGroupId,
|
||||
BdfDictionary d) throws FormatException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
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.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
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.MessageId;
|
||||
import org.briarproject.bramble.api.transport.KeySetId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction2.Role;
|
||||
import org.briarproject.briar.introduction2.IntroducerSession.Introducee;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_ACCEPT_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_AUTHOR;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_EPHEMERAL_PRIVATE_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_EPHEMERAL_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_GROUP_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_INTRODUCEE_1;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_INTRODUCEE_2;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_INTRODUCER;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_LAST_LOCAL_MESSAGE_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_LAST_REMOTE_MESSAGE_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_LOCAL_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_MASTER_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_ACCEPT_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_AUTHOR;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_EPHEMERAL_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REMOTE_TRANSPORT_PROPERTIES;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_REQUEST_TIMESTAMP;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_ROLE;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_SESSION_ID;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_STATE;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_TRANSPORT_KEYS;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_TRANSPORT_PROPERTIES;
|
||||
import static org.briarproject.briar.api.introduction2.Role.INTRODUCEE;
|
||||
import static org.briarproject.briar.api.introduction2.Role.INTRODUCER;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class SessionParserImpl implements SessionParser {
|
||||
|
||||
private final ClientHelper clientHelper;
|
||||
|
||||
@Inject
|
||||
SessionParserImpl(ClientHelper clientHelper) {
|
||||
this.clientHelper = clientHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary getSessionQuery(SessionId s) {
|
||||
return BdfDictionary.of(new BdfEntry(SESSION_KEY_SESSION_ID, s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Role getRole(BdfDictionary d) throws FormatException {
|
||||
return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntroducerSession parseIntroducerSession(BdfDictionary d)
|
||||
throws FormatException {
|
||||
if (getRole(d) != INTRODUCER) throw new IllegalArgumentException();
|
||||
SessionId sessionId = getSessionId(d);
|
||||
IntroducerState state = IntroducerState.fromValue(getState(d));
|
||||
long requestTimestamp = d.getLong(SESSION_KEY_REQUEST_TIMESTAMP);
|
||||
Introducee introducee1 = parseIntroducee(sessionId,
|
||||
d.getDictionary(SESSION_KEY_INTRODUCEE_1));
|
||||
Introducee introducee2 = parseIntroducee(sessionId,
|
||||
d.getDictionary(SESSION_KEY_INTRODUCEE_2));
|
||||
return new IntroducerSession(sessionId, state, requestTimestamp,
|
||||
introducee1, introducee2);
|
||||
}
|
||||
|
||||
private Introducee parseIntroducee(SessionId sessionId, BdfDictionary d)
|
||||
throws FormatException {
|
||||
MessageId lastLocalMessageId =
|
||||
getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID);
|
||||
MessageId lastRemoteMessageId =
|
||||
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
||||
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
||||
GroupId groupId = getGroupId(d, SESSION_KEY_GROUP_ID);
|
||||
Author author = getAuthor(d, SESSION_KEY_AUTHOR);
|
||||
return new Introducee(sessionId, groupId, author, localTimestamp,
|
||||
lastLocalMessageId, lastRemoteMessageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntroduceeSession parseIntroduceeSession(GroupId introducerGroupId,
|
||||
BdfDictionary d) throws FormatException {
|
||||
if (getRole(d) != INTRODUCEE) throw new IllegalArgumentException();
|
||||
SessionId sessionId = getSessionId(d);
|
||||
IntroduceeState state = IntroduceeState.fromValue(getState(d));
|
||||
long requestTimestamp = d.getLong(SESSION_KEY_REQUEST_TIMESTAMP);
|
||||
MessageId lastLocalMessageId =
|
||||
getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID);
|
||||
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
||||
MessageId lastRemoteMessageId =
|
||||
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
||||
Author introducer = getAuthor(d, SESSION_KEY_INTRODUCER);
|
||||
byte[] ephemeralPublicKey =
|
||||
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||
byte[] ephemeralPrivateKey =
|
||||
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PRIVATE_KEY);
|
||||
BdfDictionary tpDict =
|
||||
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
||||
Map<TransportId, TransportProperties> transportProperties =
|
||||
tpDict == null ? null : clientHelper
|
||||
.parseAndValidateTransportPropertiesMap(tpDict);
|
||||
long acceptTimestamp = d.getLong(SESSION_KEY_ACCEPT_TIMESTAMP);
|
||||
byte[] masterKey = d.getOptionalRaw(SESSION_KEY_MASTER_KEY);
|
||||
Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR);
|
||||
byte[] remoteEphemeralPublicKey =
|
||||
d.getOptionalRaw(SESSION_KEY_REMOTE_EPHEMERAL_PUBLIC_KEY);
|
||||
BdfDictionary rptDict = d.getOptionalDictionary(
|
||||
SESSION_KEY_REMOTE_TRANSPORT_PROPERTIES);
|
||||
Map<TransportId, TransportProperties> remoteTransportProperties =
|
||||
rptDict == null ? null : clientHelper
|
||||
.parseAndValidateTransportPropertiesMap(rptDict);
|
||||
long remoteAcceptTimestamp =
|
||||
d.getLong(SESSION_KEY_REMOTE_ACCEPT_TIMESTAMP);
|
||||
Map<TransportId, KeySetId> transportKeys = parseTransportKeys(
|
||||
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_KEYS));
|
||||
return new IntroduceeSession(sessionId, state, requestTimestamp,
|
||||
introducerGroupId, lastLocalMessageId, localTimestamp,
|
||||
lastRemoteMessageId, introducer, ephemeralPublicKey,
|
||||
ephemeralPrivateKey, transportProperties, acceptTimestamp,
|
||||
masterKey, remoteAuthor, remoteEphemeralPublicKey,
|
||||
remoteTransportProperties, remoteAcceptTimestamp,
|
||||
transportKeys);
|
||||
}
|
||||
|
||||
private int getState(BdfDictionary d) throws FormatException {
|
||||
return d.getLong(SESSION_KEY_STATE).intValue();
|
||||
}
|
||||
|
||||
private SessionId getSessionId(BdfDictionary d) throws FormatException {
|
||||
byte[] b = d.getRaw(SESSION_KEY_SESSION_ID);
|
||||
return new SessionId(b);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private MessageId getMessageId(BdfDictionary d, String key)
|
||||
throws FormatException {
|
||||
byte[] b = d.getOptionalRaw(key);
|
||||
return b == null ? null : new MessageId(b);
|
||||
}
|
||||
|
||||
private GroupId getGroupId(BdfDictionary d, String key)
|
||||
throws FormatException {
|
||||
return new GroupId(d.getRaw(key));
|
||||
}
|
||||
|
||||
private Author getAuthor(BdfDictionary d, String key)
|
||||
throws FormatException {
|
||||
return clientHelper.parseAndValidateAuthor(d.getList(key));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Map<TransportId, KeySetId> parseTransportKeys(
|
||||
@Nullable BdfDictionary d) throws FormatException {
|
||||
if (d == null) return null;
|
||||
Map<TransportId, KeySetId> map = new HashMap<>(d.size());
|
||||
for (String key : d.keySet()) {
|
||||
map.put(new TransportId(key),
|
||||
new KeySetId(d.getLong(key).intValue())
|
||||
);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
interface State {
|
||||
|
||||
int getValue();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
package org.briarproject.briar.introduction2;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
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.MessageId;
|
||||
import org.briarproject.bramble.api.transport.KeySetId;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.introduction2.IntroducerSession.Introducee;
|
||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
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.getTransportId;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.introduction2.IntroduceeState.LOCAL_ACCEPTED;
|
||||
import static org.briarproject.briar.introduction2.IntroducerState.AWAIT_AUTHS;
|
||||
import static org.briarproject.briar.introduction2.IntroductionConstants.SESSION_KEY_ROLE;
|
||||
import static org.briarproject.briar.api.introduction2.Role.INTRODUCEE;
|
||||
import static org.briarproject.briar.api.introduction2.Role.INTRODUCER;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
|
||||
@Inject
|
||||
ClientHelper clientHelper;
|
||||
@Inject
|
||||
AuthorFactory authorFactory;
|
||||
|
||||
private final SessionEncoder sessionEncoder;
|
||||
private final SessionParser sessionParser;
|
||||
|
||||
private final GroupId groupId1 = new GroupId(getRandomId());
|
||||
private final GroupId groupId2 = new GroupId(getRandomId());
|
||||
private final SessionId sessionId = new SessionId(getRandomId());
|
||||
private final long requestTimestamp = 42;
|
||||
private final long localTimestamp = 1337;
|
||||
private final long localTimestamp2 = 1338;
|
||||
private final long acceptTimestamp = 123456;
|
||||
private final long remoteAcceptTimestamp = 1234567;
|
||||
private final MessageId lastLocalMessageId = new MessageId(getRandomId());
|
||||
private final MessageId lastLocalMessageId2 = new MessageId(getRandomId());
|
||||
private final MessageId lastRemoteMessageId = new MessageId(getRandomId());
|
||||
private final MessageId lastRemoteMessageId2 = new MessageId(getRandomId());
|
||||
private final Author author1;
|
||||
private final Author author2;
|
||||
private final byte[] ephemeralPublicKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final byte[] ephemeralPrivateKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final byte[] masterKey = getRandomBytes(SecretKey.LENGTH);
|
||||
private final byte[] remoteEphemeralPublicKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final Map<TransportId, TransportProperties> transportProperties =
|
||||
getTransportPropertiesMap(3);
|
||||
private final Map<TransportId, TransportProperties>
|
||||
remoteTransportProperties = getTransportPropertiesMap(3);
|
||||
private final Map<TransportId, KeySetId> transportKeys = new HashMap<>();
|
||||
|
||||
public SessionEncoderParserIntegrationTest() {
|
||||
BriarIntegrationTestComponent component =
|
||||
DaggerBriarIntegrationTestComponent.builder().build();
|
||||
component.inject(this);
|
||||
|
||||
sessionEncoder = new SessionEncoderImpl(clientHelper);
|
||||
sessionParser = new SessionParserImpl(clientHelper);
|
||||
author1 = getRealAuthor();
|
||||
author2 = getRealAuthor();
|
||||
transportKeys.put(getTransportId(), new KeySetId(1));
|
||||
transportKeys.put(getTransportId(), new KeySetId(2));
|
||||
transportKeys.put(getTransportId(), new KeySetId(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntroducerSession() throws FormatException {
|
||||
IntroducerSession s1 = getIntroducerSession();
|
||||
|
||||
BdfDictionary d = sessionEncoder.encodeIntroducerSession(s1);
|
||||
IntroducerSession s2 = sessionParser.parseIntroducerSession(d);
|
||||
|
||||
assertEquals(INTRODUCER, s1.getRole());
|
||||
assertEquals(s1.getRole(), s2.getRole());
|
||||
assertEquals(sessionId, s1.getSessionId());
|
||||
assertEquals(s1.getSessionId(), s2.getSessionId());
|
||||
assertEquals(AWAIT_AUTHS, s1.getState());
|
||||
assertEquals(s1.getState(), s2.getState());
|
||||
assertIntroduceeEquals(s1.getIntroducee1(), s2.getIntroducee1());
|
||||
assertIntroduceeEquals(s1.getIntroducee2(), s2.getIntroducee2());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntroducerSessionWithNulls() throws FormatException {
|
||||
Introducee introducee1 =
|
||||
new Introducee(sessionId, groupId1, author1, localTimestamp,
|
||||
null, null);
|
||||
Introducee introducee2 =
|
||||
new Introducee(sessionId, groupId2, author2, localTimestamp2,
|
||||
null, null);
|
||||
IntroducerSession s1 = new IntroducerSession(sessionId,
|
||||
AWAIT_AUTHS, requestTimestamp, introducee1,
|
||||
introducee2);
|
||||
|
||||
BdfDictionary d = sessionEncoder.encodeIntroducerSession(s1);
|
||||
IntroducerSession s2 = sessionParser.parseIntroducerSession(d);
|
||||
|
||||
assertNull(s1.getIntroducee1().lastLocalMessageId);
|
||||
assertEquals(s1.getIntroducee1().lastLocalMessageId,
|
||||
s2.getIntroducee1().lastLocalMessageId);
|
||||
assertNull(s1.getIntroducee1().lastRemoteMessageId);
|
||||
assertEquals(s1.getIntroducee1().lastRemoteMessageId,
|
||||
s2.getIntroducee1().lastRemoteMessageId);
|
||||
|
||||
assertNull(s1.getIntroducee2().lastLocalMessageId);
|
||||
assertEquals(s1.getIntroducee2().lastLocalMessageId,
|
||||
s2.getIntroducee2().lastLocalMessageId);
|
||||
assertNull(s1.getIntroducee2().lastRemoteMessageId);
|
||||
assertEquals(s1.getIntroducee2().lastRemoteMessageId,
|
||||
s2.getIntroducee2().lastRemoteMessageId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testIntroducerSessionUnknownRole() throws FormatException {
|
||||
IntroducerSession s = getIntroducerSession();
|
||||
BdfDictionary d = sessionEncoder.encodeIntroducerSession(s);
|
||||
d.put(SESSION_KEY_ROLE, 1337);
|
||||
sessionParser.parseIntroducerSession(d);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIntroducerSessionWrongRole() throws FormatException {
|
||||
IntroducerSession s = getIntroducerSession();
|
||||
BdfDictionary d = sessionEncoder.encodeIntroducerSession(s);
|
||||
d.put(SESSION_KEY_ROLE, INTRODUCEE.getValue());
|
||||
sessionParser.parseIntroducerSession(d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntroduceeSession() throws FormatException {
|
||||
IntroduceeSession s1 = getIntroduceeSession();
|
||||
BdfDictionary d = sessionEncoder.encodeIntroduceeSession(s1);
|
||||
IntroduceeSession s2 =
|
||||
sessionParser.parseIntroduceeSession(groupId1, d);
|
||||
|
||||
assertEquals(LOCAL_ACCEPTED, s1.getState());
|
||||
assertEquals(s1.getState(), s2.getState());
|
||||
assertEquals(INTRODUCEE, s1.getRole());
|
||||
assertEquals(s1.getRole(), s2.getRole());
|
||||
assertEquals(sessionId, s1.getSessionId());
|
||||
assertEquals(s1.getSessionId(), s2.getSessionId());
|
||||
assertEquals(groupId1, s1.getContactGroupId());
|
||||
assertEquals(s1.getContactGroupId(), s2.getContactGroupId());
|
||||
assertEquals(localTimestamp, s1.getLocalTimestamp());
|
||||
assertEquals(s1.getLocalTimestamp(), s2.getLocalTimestamp());
|
||||
assertEquals(lastLocalMessageId, s1.getLastLocalMessageId());
|
||||
assertEquals(s1.getLastLocalMessageId(), s2.getLastLocalMessageId());
|
||||
assertEquals(lastRemoteMessageId, s1.getLastRemoteMessageId());
|
||||
assertEquals(s1.getLastRemoteMessageId(), s2.getLastRemoteMessageId());
|
||||
assertEquals(author1, s1.getIntroducer());
|
||||
assertEquals(s1.getIntroducer(), s2.getIntroducer());
|
||||
assertEquals(author2, s1.getRemoteAuthor());
|
||||
assertEquals(s1.getRemoteAuthor(), s2.getRemoteAuthor());
|
||||
assertArrayEquals(ephemeralPublicKey, s1.getEphemeralPublicKey());
|
||||
assertArrayEquals(s1.getEphemeralPublicKey(),
|
||||
s2.getEphemeralPublicKey());
|
||||
assertArrayEquals(ephemeralPrivateKey, s1.getEphemeralPrivateKey());
|
||||
assertArrayEquals(s1.getEphemeralPrivateKey(),
|
||||
s2.getEphemeralPrivateKey());
|
||||
assertEquals(acceptTimestamp, s1.getAcceptTimestamp());
|
||||
assertEquals(s1.getAcceptTimestamp(), s2.getAcceptTimestamp());
|
||||
assertArrayEquals(masterKey, s1.getMasterKey());
|
||||
assertArrayEquals(s1.getMasterKey(), s2.getMasterKey());
|
||||
assertArrayEquals(remoteEphemeralPublicKey, s1.getRemotePublicKey());
|
||||
assertArrayEquals(s1.getRemotePublicKey(),
|
||||
s2.getRemotePublicKey());
|
||||
assertEquals(transportProperties, s1.getTransportProperties());
|
||||
assertEquals(s1.getTransportProperties(), s2.getTransportProperties());
|
||||
assertEquals(remoteTransportProperties,
|
||||
s1.getRemoteTransportProperties());
|
||||
assertEquals(s1.getRemoteTransportProperties(),
|
||||
s2.getRemoteTransportProperties());
|
||||
assertEquals(remoteAcceptTimestamp, s1.getRemoteAcceptTimestamp());
|
||||
assertEquals(s1.getRemoteAcceptTimestamp(), s2.getRemoteAcceptTimestamp());
|
||||
assertEquals(transportKeys, s1.getTransportKeys());
|
||||
assertEquals(s1.getTransportKeys(), s2.getTransportKeys());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntroduceeSessionWithNulls() throws FormatException {
|
||||
IntroduceeSession s1 =
|
||||
new IntroduceeSession(sessionId, LOCAL_ACCEPTED,
|
||||
requestTimestamp, groupId1, null, localTimestamp, null,
|
||||
author1, null, null, null, acceptTimestamp, null,
|
||||
author2, null, null, remoteAcceptTimestamp, null);
|
||||
|
||||
BdfDictionary d = sessionEncoder.encodeIntroduceeSession(s1);
|
||||
IntroduceeSession s2 =
|
||||
sessionParser.parseIntroduceeSession(groupId1, d);
|
||||
|
||||
assertNull(s1.getLastLocalMessageId());
|
||||
assertEquals(s1.getLastLocalMessageId(), s2.getLastLocalMessageId());
|
||||
assertNull(s1.getLastRemoteMessageId());
|
||||
assertEquals(s1.getLastRemoteMessageId(), s2.getLastRemoteMessageId());
|
||||
assertNull(s1.getEphemeralPublicKey());
|
||||
assertArrayEquals(s1.getEphemeralPublicKey(),
|
||||
s2.getEphemeralPublicKey());
|
||||
assertNull(s1.getEphemeralPrivateKey());
|
||||
assertArrayEquals(s1.getEphemeralPrivateKey(),
|
||||
s2.getEphemeralPrivateKey());
|
||||
assertNull(s1.getTransportKeys());
|
||||
assertEquals(s1.getTransportKeys(), s2.getTransportKeys());
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testIntroduceeSessionUnknownRole() throws FormatException {
|
||||
IntroduceeSession s = getIntroduceeSession();
|
||||
BdfDictionary d = sessionEncoder.encodeIntroduceeSession(s);
|
||||
d.put(SESSION_KEY_ROLE, 1337);
|
||||
sessionParser.parseIntroduceeSession(groupId1, d);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIntroduceeSessionWrongRole() throws FormatException {
|
||||
IntroduceeSession s = getIntroduceeSession();
|
||||
BdfDictionary d = sessionEncoder.encodeIntroduceeSession(s);
|
||||
d.put(SESSION_KEY_ROLE, INTRODUCER.getValue());
|
||||
sessionParser.parseIntroduceeSession(groupId1, d);
|
||||
}
|
||||
|
||||
private IntroducerSession getIntroducerSession() {
|
||||
Introducee introducee1 =
|
||||
new Introducee(sessionId, groupId1, author1, localTimestamp,
|
||||
lastLocalMessageId, lastRemoteMessageId);
|
||||
Introducee introducee2 =
|
||||
new Introducee(sessionId, groupId2, author2, localTimestamp2,
|
||||
lastLocalMessageId2, lastRemoteMessageId2);
|
||||
return new IntroducerSession(sessionId, AWAIT_AUTHS,
|
||||
requestTimestamp, introducee1, introducee2);
|
||||
}
|
||||
|
||||
private IntroduceeSession getIntroduceeSession() {
|
||||
return new IntroduceeSession(sessionId, LOCAL_ACCEPTED,
|
||||
requestTimestamp, groupId1, lastLocalMessageId, localTimestamp,
|
||||
lastRemoteMessageId, author1, ephemeralPublicKey,
|
||||
ephemeralPrivateKey, transportProperties, acceptTimestamp,
|
||||
masterKey, author2, remoteEphemeralPublicKey,
|
||||
remoteTransportProperties, remoteAcceptTimestamp,
|
||||
transportKeys);
|
||||
}
|
||||
|
||||
private void assertIntroduceeEquals(Introducee i1, Introducee i2) {
|
||||
assertEquals(i1.author, i2.author);
|
||||
assertEquals(i1.groupId, i2.groupId);
|
||||
assertEquals(i1.localTimestamp, i2.localTimestamp);
|
||||
assertEquals(i1.lastLocalMessageId, i2.lastLocalMessageId);
|
||||
assertEquals(i1.lastRemoteMessageId, i2.lastRemoteMessageId);
|
||||
}
|
||||
|
||||
private Author getRealAuthor() {
|
||||
return authorFactory.createAuthor(getRandomString(5),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@ 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.introduction2.SessionEncoderParserIntegrationTest;
|
||||
import org.briarproject.briar.messaging.MessagingModule;
|
||||
import org.briarproject.briar.privategroup.PrivateGroupModule;
|
||||
import org.briarproject.briar.privategroup.invitation.GroupInvitationModule;
|
||||
@@ -78,6 +79,7 @@ public interface BriarIntegrationTestComponent {
|
||||
void inject(BriarIntegrationTest<BriarIntegrationTestComponent> init);
|
||||
|
||||
void inject(MessageEncoderParserIntegrationTest init);
|
||||
void inject(SessionEncoderParserIntegrationTest init);
|
||||
|
||||
void inject(BlogModule.EagerSingletons init);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user