mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
FIX: Addresses reviewer comments
This commit is contained in:
@@ -1141,7 +1141,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
time);
|
||||
}
|
||||
}
|
||||
} catch (DbException | IOException | NullPointerException exception) {
|
||||
} catch (DbException | IOException exception) {
|
||||
msgWaiter.rethrow(exception);
|
||||
eventWaiter.rethrow(exception);
|
||||
} finally {
|
||||
|
||||
@@ -36,23 +36,15 @@ import static org.briarproject.api.introduction.IntroduceeProtocolState.FINISHED
|
||||
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.INTRODUCER;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MAC;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MSG;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_MAC;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_SIGNATURE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCEE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SIGNATURE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK_ACTIVATE_CONTACT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK_ADD_CONTACT;
|
||||
@@ -65,7 +57,8 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
|
||||
class IntroduceeEngine
|
||||
implements ProtocolEngine<BdfDictionary, IntroduceeSessionState, BdfDictionary> {
|
||||
implements
|
||||
ProtocolEngine<BdfDictionary, IntroduceeSessionState, BdfDictionary> {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(IntroduceeEngine.class.getName());
|
||||
@@ -79,8 +72,8 @@ class IntroduceeEngine
|
||||
int type = localAction.getLong(TYPE).intValue();
|
||||
IntroduceeAction action;
|
||||
// FIXME: discuss? used to be: if has key ACCEPT:
|
||||
if (localState.wasAccepted()) action = IntroduceeAction
|
||||
.getLocal(type, localState.getAccept());
|
||||
if (localState.wasLocallyAcceptedOrDeclined()) action = IntroduceeAction
|
||||
.getLocal(type, localState.wasLocallyAccepted());
|
||||
else action = IntroduceeAction.getLocal(type);
|
||||
IntroduceeProtocolState nextState = currentState.next(action);
|
||||
|
||||
@@ -106,8 +99,8 @@ class IntroduceeEngine
|
||||
msg.put(TYPE, TYPE_RESPONSE);
|
||||
msg.put(GROUP_ID, localState.getIntroductionGroupId());
|
||||
msg.put(SESSION_ID, localState.getSessionId());
|
||||
msg.put(ACCEPT, localState.getAccept());
|
||||
if (localState.getAccept()) {
|
||||
msg.put(ACCEPT, localState.wasLocallyAccepted());
|
||||
if (localState.wasLocallyAccepted()) {
|
||||
msg.put(TIME, localState.getOurTime());
|
||||
msg.put(E_PUBLIC_KEY, localState.getOurPublicKey());
|
||||
msg.put(TRANSPORT, localAction.getDictionary(TRANSPORT));
|
||||
@@ -181,8 +174,6 @@ class IntroduceeEngine
|
||||
addResponseData(localState, msg);
|
||||
if (nextState == AWAIT_ACK) {
|
||||
localState.setTask(TASK_ADD_CONTACT);
|
||||
// messages = Collections
|
||||
// .singletonList(getAckMessage(localState));
|
||||
}
|
||||
messages = Collections.emptyList();
|
||||
events = Collections.emptyList();
|
||||
@@ -197,7 +188,8 @@ class IntroduceeEngine
|
||||
}
|
||||
// we are done (probably declined response), ignore & delete message
|
||||
else if (currentState == FINISHED) {
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(true,
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(
|
||||
true,
|
||||
false, localState,
|
||||
Collections.<BdfDictionary>emptyList(),
|
||||
Collections.<Event>emptyList());
|
||||
@@ -206,7 +198,7 @@ class IntroduceeEngine
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(false,
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(false,
|
||||
false, localState, messages, events);
|
||||
} catch (FormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
@@ -216,7 +208,7 @@ class IntroduceeEngine
|
||||
private void addRequestData(IntroduceeSessionState localState,
|
||||
BdfDictionary msg) throws FormatException {
|
||||
|
||||
localState.setName(msg.getString(NAME));
|
||||
localState.setIntroducedName(msg.getString(NAME));
|
||||
localState.setIntroducedPublicKey(msg.getRaw(PUBLIC_KEY));
|
||||
if (msg.containsKey(MSG)) {
|
||||
localState.setMessage(msg.getString(MSG));
|
||||
@@ -227,16 +219,17 @@ class IntroduceeEngine
|
||||
BdfDictionary msg) throws FormatException {
|
||||
|
||||
localState.setAccept(msg.getBoolean(ACCEPT));
|
||||
localState.setOtherResponseId(msg.getRaw(MESSAGE_ID));
|
||||
localState.setTheirResponseId(msg.getRaw(MESSAGE_ID));
|
||||
|
||||
if (msg.getBoolean(ACCEPT)) {
|
||||
localState.setTheirTime(msg.getLong(TIME));
|
||||
localState.setEPublicKey(msg.getRaw(E_PUBLIC_KEY));
|
||||
localState.setTransport(msg.getDictionary(TRANSPORT));
|
||||
localState.setTheirEphemeralPublicKey(msg.getRaw(E_PUBLIC_KEY));
|
||||
localState.setOurTransportProperties(msg.getDictionary(TRANSPORT));
|
||||
}
|
||||
}
|
||||
|
||||
private void addAckData(IntroduceeSessionState localState, BdfDictionary msg)
|
||||
private void addAckData(IntroduceeSessionState localState,
|
||||
BdfDictionary msg)
|
||||
throws FormatException {
|
||||
|
||||
localState.setMac(msg.getRaw(MAC));
|
||||
@@ -256,7 +249,7 @@ class IntroduceeEngine
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Sending ACK " + " to " +
|
||||
localState.getIntroducerName() + " for " +
|
||||
localState.getName() +
|
||||
localState.getIntroducedName() +
|
||||
" with session ID " +
|
||||
Arrays.hashCode(m.getRaw(SESSION_ID)) + " in group " +
|
||||
Arrays.hashCode(m.getRaw(GROUP_ID)));
|
||||
@@ -271,10 +264,10 @@ class IntroduceeEngine
|
||||
|
||||
try {
|
||||
LOG.info("Sending " +
|
||||
(localState.getAccept() ? "accept " : "decline ") +
|
||||
(localState.wasLocallyAccepted() ? "accept " : "decline ") +
|
||||
"response in state " + state.name() +
|
||||
" to " + localState.getName() +
|
||||
" for " + localState.getIntroducerName() +
|
||||
" to " + localState.getIntroducerName() +
|
||||
" for " + localState.getIntroducedName() +
|
||||
" with session ID " +
|
||||
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
|
||||
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
|
||||
@@ -287,7 +280,7 @@ class IntroduceeEngine
|
||||
}
|
||||
|
||||
private void logMessageReceived(IntroduceeProtocolState currentState,
|
||||
IntroduceeProtocolState nextState,
|
||||
IntroduceeProtocolState nextState,
|
||||
IntroduceeSessionState localState, int type, BdfDictionary msg) {
|
||||
|
||||
if (!LOG.isLoggable(INFO)) return;
|
||||
@@ -301,8 +294,9 @@ class IntroduceeEngine
|
||||
|
||||
LOG.info("Received " + t + " in state " + currentState.name() +
|
||||
" from " + localState.getIntroducerName() +
|
||||
(localState.getName() != null ?
|
||||
" related to " + localState.getName() : "") +
|
||||
(localState.getIntroducedName() != null ?
|
||||
" related to " + localState.getIntroducedName() :
|
||||
"") +
|
||||
" with session ID " +
|
||||
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
|
||||
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
|
||||
@@ -344,14 +338,14 @@ class IntroduceeEngine
|
||||
}
|
||||
|
||||
private StateUpdate<IntroduceeSessionState, BdfDictionary> abortSession(
|
||||
IntroduceeProtocolState currentState,
|
||||
IntroduceeProtocolState currentState,
|
||||
IntroduceeSessionState localState) throws FormatException {
|
||||
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Aborting protocol session " +
|
||||
Arrays.hashCode(localState.getSessionId().getBytes()) +
|
||||
localState.getSessionId().hashCode() +
|
||||
" in state " + currentState.name()
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
localState.setState(ERROR);
|
||||
@@ -368,14 +362,15 @@ class IntroduceeEngine
|
||||
Event event = new IntroductionAbortedEvent(contactId, sessionId);
|
||||
List<Event> events = Collections.singletonList(event);
|
||||
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(false,
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(false,
|
||||
false, localState, messages, events);
|
||||
}
|
||||
|
||||
private StateUpdate<IntroduceeSessionState, BdfDictionary> noUpdate(
|
||||
IntroduceeSessionState localState) throws FormatException {
|
||||
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(false, false,
|
||||
return new StateUpdate<IntroduceeSessionState, BdfDictionary>(false,
|
||||
false,
|
||||
localState, Collections.<BdfDictionary>emptyList(),
|
||||
Collections.<Event>emptyList());
|
||||
}
|
||||
|
||||
@@ -45,42 +45,13 @@ import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.data.BdfDictionary.NULL_VALUE;
|
||||
import static org.briarproject.api.introduction.IntroduceeProtocolState.AWAIT_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.EXISTS;
|
||||
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.INTRODUCER;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.LOCAL_AUTHOR_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MAC;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MAC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NONCE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_MAC;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_PRIVATE_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_SIGNATURE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_TRANSPORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_IS_US;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCEE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SIGNATURE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STORAGE_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NO_TASK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK_ACTIVATE_CONTACT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK_ADD_CONTACT;
|
||||
@@ -148,10 +119,12 @@ class IntroduceeManager {
|
||||
new ContactId(gd.getLong(CONTACT).intValue());
|
||||
Contact introducer = db.getContact(txn, introducerId);
|
||||
|
||||
IntroduceeSessionState localState = new IntroduceeSessionState(storageId,
|
||||
sessionId, groupId, introducer.getId(),
|
||||
introducer.getAuthor().getId(), introducer.getAuthor().getName(),
|
||||
introducer.getLocalAuthorId(), AWAIT_REQUEST);
|
||||
IntroduceeSessionState localState =
|
||||
new IntroduceeSessionState(storageId,
|
||||
sessionId, groupId, introducer.getId(),
|
||||
introducer.getAuthor().getId(),
|
||||
introducer.getAuthor().getName(),
|
||||
introducer.getLocalAuthorId(), AWAIT_REQUEST);
|
||||
|
||||
// check if the contact we are introduced to does already exist
|
||||
AuthorId remoteAuthorId = authorFactory
|
||||
@@ -161,11 +134,10 @@ class IntroduceeManager {
|
||||
introducer.getLocalAuthorId());
|
||||
localState.setContactExists(exists);
|
||||
localState.setRemoteAuthorId(remoteAuthorId);
|
||||
localState.setLocalAuthorId((introducer.getLocalAuthorId()));
|
||||
localState.setName(message.getString(NAME));
|
||||
localState.setIntroducedPublicKey(message.getRaw(PUBLIC_KEY));
|
||||
|
||||
// check if someone is trying to introduce us to ourselves
|
||||
if(remoteAuthorId.equals(introducer.getLocalAuthorId())) {
|
||||
if (remoteAuthorId.equals(introducer.getLocalAuthorId())) {
|
||||
LOG.warning("Received Introduction Request to Ourselves");
|
||||
throw new FormatException();
|
||||
}
|
||||
@@ -186,7 +158,8 @@ class IntroduceeManager {
|
||||
BdfDictionary message) throws DbException, FormatException {
|
||||
|
||||
IntroduceeEngine engine = new IntroduceeEngine();
|
||||
processStateUpdate(txn, message, engine.onMessageReceived(state, message));
|
||||
processStateUpdate(txn, message,
|
||||
engine.onMessageReceived(state, message));
|
||||
}
|
||||
|
||||
void acceptIntroduction(Transaction txn,
|
||||
@@ -205,7 +178,7 @@ class IntroduceeManager {
|
||||
state.setOurTime(now);
|
||||
state.setOurPrivateKey(keyPair.getPrivate().getEncoded());
|
||||
state.setOurPublicKey(keyPair.getPublic().getEncoded());
|
||||
state.setOurTransport(tp);
|
||||
state.setOurTransport(tp);
|
||||
|
||||
// define action
|
||||
BdfDictionary localAction = new BdfDictionary();
|
||||
@@ -245,7 +218,7 @@ class IntroduceeManager {
|
||||
|
||||
// save new local state
|
||||
MessageId storageId = result.localState.getStorageId();
|
||||
clientHelper.mergeMessageMetadata(txn, storageId,
|
||||
clientHelper.mergeMessageMetadata(txn, storageId,
|
||||
result.localState.toBdfDictionary());
|
||||
|
||||
// send messages
|
||||
@@ -269,7 +242,7 @@ class IntroduceeManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void performTasks(Transaction txn,
|
||||
private void performTasks(Transaction txn,
|
||||
IntroduceeSessionState localState)
|
||||
throws FormatException, DbException {
|
||||
|
||||
@@ -308,7 +281,7 @@ class IntroduceeManager {
|
||||
|
||||
KeyPair ourEphemeralKeyPair;
|
||||
ourEphemeralKeyPair = new KeyPair(publicKey, privateKey);
|
||||
byte[] theirEphemeralKey = localState.getEPublicKey();
|
||||
byte[] theirEphemeralKey = localState.getTheirEphemeralPublicKey();
|
||||
|
||||
// figure out who takes which role by comparing public keys
|
||||
int comp = new Bytes(publicKeyBytes).compareTo(
|
||||
@@ -337,8 +310,8 @@ class IntroduceeManager {
|
||||
cryptoComponent.deriveMacKey(secretKey, !alice);
|
||||
|
||||
// Save the other nonce and MAC key for the verification
|
||||
localState.setNonce(theirNonce);
|
||||
localState.setMacKey(theirMacKey.getBytes());
|
||||
localState.setTheirNonce(theirNonce);
|
||||
localState.setTheirMacKey(theirMacKey.getBytes());
|
||||
|
||||
// Sign our nonce with our long-term identity public key
|
||||
AuthorId localAuthorId = localState.getLocalAuthorId();
|
||||
@@ -377,7 +350,7 @@ class IntroduceeManager {
|
||||
|
||||
// Add the contact to the database as inactive
|
||||
Author remoteAuthor = authorFactory
|
||||
.createAuthor(localState.getName(),
|
||||
.createAuthor(localState.getIntroducedName(),
|
||||
localState.getIntroducedPublicKey());
|
||||
ContactId contactId = contactManager
|
||||
.addContact(txn, remoteAuthor, localAuthorId, secretKey,
|
||||
@@ -409,17 +382,19 @@ class IntroduceeManager {
|
||||
|
||||
// we sent and received an ACK, so activate contact
|
||||
if (task == TASK_ACTIVATE_CONTACT) {
|
||||
if (!localState.getContactExists() && localState.getIntroducedId() != null) {
|
||||
if (!localState.getContactExists() &&
|
||||
localState.getIntroducedId() != null) {
|
||||
|
||||
LOG.info("Verifying Signature...");
|
||||
|
||||
byte[] nonce = localState.getNonce();
|
||||
byte[] nonce = localState.getTheirNonce();
|
||||
byte[] sig = localState.getSignature();
|
||||
byte[] keyBytes = localState.getIntroducedPublicKey();
|
||||
byte[] introducedPubKey = localState.getIntroducedPublicKey();
|
||||
try {
|
||||
// Parse the public key
|
||||
KeyParser keyParser = cryptoComponent.getSignatureKeyParser();
|
||||
PublicKey key = keyParser.parsePublicKey(keyBytes);
|
||||
KeyParser keyParser =
|
||||
cryptoComponent.getSignatureKeyParser();
|
||||
PublicKey key = keyParser.parsePublicKey(introducedPubKey);
|
||||
// Verify the signature
|
||||
Signature signature = cryptoComponent.getSignature();
|
||||
signature.initVerify(key);
|
||||
@@ -439,15 +414,15 @@ class IntroduceeManager {
|
||||
|
||||
// get MAC and MAC key from session state
|
||||
byte[] mac = localState.getMac();
|
||||
byte[] macKeyBytes = localState.getMacKey();
|
||||
byte[] macKeyBytes = localState.getTheirMacKey();
|
||||
SecretKey macKey = new SecretKey(macKeyBytes);
|
||||
|
||||
// get MAC data and calculate a new MAC with stored key
|
||||
byte[] pubKey = localState.getIntroducedPublicKey();
|
||||
byte[] ePubKey = localState.getEPublicKey();
|
||||
BdfDictionary tp = localState.getTransport();
|
||||
byte[] ePubKey = localState.getTheirEphemeralPublicKey();
|
||||
BdfDictionary tp = localState.getOurTransportProperties();
|
||||
long timestamp = localState.getTheirTime();
|
||||
BdfList toSignList = BdfList.of(pubKey, ePubKey, tp, timestamp);
|
||||
BdfList toSignList = BdfList.of(introducedPubKey, ePubKey, tp,
|
||||
timestamp);
|
||||
byte[] toSign = clientHelper.toByteArray(toSignList);
|
||||
byte[] calculatedMac = cryptoComponent.mac(macKey, toSign);
|
||||
if (!Arrays.equals(mac, calculatedMac)) {
|
||||
|
||||
@@ -15,7 +15,6 @@ import static org.briarproject.api.introduction.IntroductionConstants.ANSWERED;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.AUTHOR_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.AUTHOR_ID_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.E_PUBLIC_KEY;
|
||||
@@ -26,7 +25,6 @@ import static org.briarproject.api.introduction.IntroductionConstants.SIGNATURE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MAC;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_IS_US;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TASK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.INTRODUCER;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.LOCAL_AUTHOR_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
@@ -50,7 +48,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.OUR_SIGNAT
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_MAC;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MAC_KEY;
|
||||
|
||||
|
||||
// This class is not thread-safe
|
||||
class IntroduceeSessionState extends IntroductionState {
|
||||
|
||||
private IntroduceeProtocolState state;
|
||||
@@ -67,20 +65,21 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
private byte[] ourPrivateKey;
|
||||
private byte[] ourPublicKey;
|
||||
private byte[] introducedPublicKey;
|
||||
private byte[] ePublicKey;
|
||||
private byte[] theirEphemeralPublicKey;
|
||||
|
||||
private byte[] mac;
|
||||
private byte[] signature;
|
||||
private byte[] ourMac;
|
||||
private byte[] ourSignature;
|
||||
private BdfDictionary ourTransport;
|
||||
private byte[] nonce;
|
||||
private byte[] macKey;
|
||||
private byte[] theirNonce;
|
||||
private byte[] theirMacKey;
|
||||
|
||||
private int task;
|
||||
|
||||
private String message;
|
||||
private BdfDictionary transport; // FIXME should not be a dictionary
|
||||
private BdfDictionary ourTransportProperties;
|
||||
// FIXME should not be a dictionary
|
||||
|
||||
private boolean answered;
|
||||
private boolean accept;
|
||||
@@ -93,17 +92,17 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
private AuthorId remoteAuthorId;
|
||||
private boolean remoteAuthorIsUs;
|
||||
|
||||
private String name;
|
||||
private String introducedName;
|
||||
private GroupId introductionGroupId;
|
||||
private ContactId introducedId;
|
||||
private String introducedName;
|
||||
// private String introducedName;
|
||||
private AuthorId introducedAuthorId;
|
||||
|
||||
IntroduceeSessionState(MessageId storageId, SessionId sessionId,
|
||||
GroupId groupId,
|
||||
ContactId introducerId, AuthorId introducerAuthorId,
|
||||
String introducerName, AuthorId introducerLocalAuthorId,
|
||||
IntroduceeProtocolState state){
|
||||
String introducerName, AuthorId introducerLocalAuthorId,
|
||||
IntroduceeProtocolState state) {
|
||||
|
||||
super(sessionId, storageId);
|
||||
|
||||
@@ -116,32 +115,15 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
this.answered = false;
|
||||
this.accept = false;
|
||||
this.accepted = false;
|
||||
this.contactAlreadyExists= false;
|
||||
this.contactAlreadyExists = false;
|
||||
this.otherResponseId = null;
|
||||
this.task = NO_TASK;
|
||||
this.transport = null;
|
||||
this.ourTransportProperties = null;
|
||||
this.introductionGroupId = groupId;
|
||||
|
||||
// these are not set during initialization, so we default them to null
|
||||
this.introducedName = null;
|
||||
this.introducedAuthorId = null;
|
||||
this.introducedId = null;
|
||||
this.introducedPublicKey = null;
|
||||
this.ourPublicKey = null;
|
||||
this.ourPrivateKey = null;
|
||||
this.ePublicKey = null;
|
||||
this.introducedPublicKey = null;
|
||||
this.message = null;
|
||||
this.mac = null;
|
||||
this.signature = null;
|
||||
this.ourMac = null;
|
||||
this.ourSignature = null;
|
||||
this.ourTransport = null;
|
||||
this.nonce = null;
|
||||
this.macKey = null;
|
||||
}
|
||||
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = super.toBdfDictionary();
|
||||
d.put(ROLE, ROLE_INTRODUCEE);
|
||||
d.put(STATE, getState().getValue());
|
||||
@@ -158,7 +140,6 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
if (introducedId != null)
|
||||
d.put(ADDED_CONTACT_ID, introducedId.getInt());
|
||||
|
||||
d.put(GROUP_ID_1, introductionGroupId);
|
||||
d.put(GROUP_ID, introductionGroupId);
|
||||
|
||||
d.put(AUTHOR_ID_1, introducerAuthorId);
|
||||
@@ -167,33 +148,36 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
|
||||
if (introducedAuthorId != null) {
|
||||
d.put(AUTHOR_ID_2, introducedAuthorId);
|
||||
d.put(CONTACT_2, introducedName);
|
||||
d.put(CONTACT_ID_2, introducedId);
|
||||
}
|
||||
// TODO check if we really need three names and what this name refers to
|
||||
if (name != null) d.put(NAME, name);
|
||||
// TODO check if we really need three names and what this introducedName refers to
|
||||
if (introducedName != null) d.put(NAME, introducedName);
|
||||
|
||||
if (remoteAuthorId != null)
|
||||
d.put(REMOTE_AUTHOR_ID, remoteAuthorId);
|
||||
|
||||
d.put(LOCAL_AUTHOR_ID, localAuthorId);
|
||||
|
||||
if (transport != null)
|
||||
d.put(TRANSPORT, transport);
|
||||
if (ourTransportProperties != null)
|
||||
d.put(TRANSPORT, ourTransportProperties);
|
||||
|
||||
if (ourPublicKey != null)
|
||||
d.put(OUR_PUBLIC_KEY, ourPublicKey);
|
||||
|
||||
if (ourPrivateKey != null)
|
||||
d.put(OUR_PRIVATE_KEY, ourPrivateKey);
|
||||
else
|
||||
d.put(OUR_PRIVATE_KEY, BdfDictionary.NULL_VALUE);
|
||||
|
||||
if (ePublicKey != null)
|
||||
d.put(E_PUBLIC_KEY, ePublicKey);
|
||||
if (theirEphemeralPublicKey != null)
|
||||
d.put(E_PUBLIC_KEY, theirEphemeralPublicKey);
|
||||
else
|
||||
d.put(E_PUBLIC_KEY, BdfDictionary.NULL_VALUE);
|
||||
|
||||
if (introducedPublicKey != null)
|
||||
d.put(PUBLIC_KEY, introducedPublicKey);
|
||||
|
||||
if (otherResponseId != null)
|
||||
if (otherResponseId != null)
|
||||
d.put(NOT_OUR_RESPONSE, getOtherResponseId());
|
||||
|
||||
if (mac != null)
|
||||
@@ -211,13 +195,12 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
if (ourTransport != null)
|
||||
d.put(OUR_TRANSPORT, ourTransport);
|
||||
|
||||
if (nonce != null)
|
||||
d.put(NONCE, nonce);
|
||||
if (theirNonce != null)
|
||||
d.put(NONCE, theirNonce);
|
||||
|
||||
if (theirMacKey != null)
|
||||
d.put(MAC_KEY, theirMacKey);
|
||||
|
||||
if (macKey != null) {
|
||||
d.put(MAC_KEY, macKey);
|
||||
}
|
||||
|
||||
d.put(TIME, theirTime);
|
||||
d.put(OUR_TIME, ourTime);
|
||||
d.put(EXISTS, contactAlreadyExists);
|
||||
@@ -226,8 +209,8 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
return d;
|
||||
}
|
||||
|
||||
public static IntroduceeSessionState fromBdfDictionary(BdfDictionary d)
|
||||
throws FormatException{
|
||||
static IntroduceeSessionState fromBdfDictionary(BdfDictionary d)
|
||||
throws FormatException {
|
||||
|
||||
if (d.getLong(ROLE).intValue() != ROLE_INTRODUCEE)
|
||||
throw new FormatException();
|
||||
@@ -235,23 +218,25 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
MessageId storageId = new MessageId(d.getRaw(STORAGE_ID));
|
||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||
|
||||
// FIXME: do we need both GROUP_ID and GROUP_ID_1?
|
||||
GroupId groupId = new GroupId(d.getRaw(GROUP_ID_1));
|
||||
GroupId groupId = new GroupId(d.getRaw(GROUP_ID));
|
||||
|
||||
AuthorId iaid = new AuthorId(d.getRaw(AUTHOR_ID_1));
|
||||
String iname = d.getString(INTRODUCER);
|
||||
ContactId iid = new ContactId(d.getLong(CONTACT_ID_1).intValue());
|
||||
AuthorId liaid = new AuthorId(d.getRaw(LOCAL_AUTHOR_ID));
|
||||
AuthorId authorId1 = new AuthorId(d.getRaw(AUTHOR_ID_1));
|
||||
String introducerName = d.getString(INTRODUCER);
|
||||
ContactId introducerId =
|
||||
new ContactId(d.getLong(CONTACT_ID_1).intValue());
|
||||
AuthorId introducerLocalAuthorId =
|
||||
new AuthorId(d.getRaw(LOCAL_AUTHOR_ID));
|
||||
|
||||
int stateno = d.getLong(STATE).intValue();
|
||||
int stateNumber = d.getLong(STATE).intValue();
|
||||
IntroduceeProtocolState state =
|
||||
IntroduceeProtocolState.fromValue(stateno);
|
||||
IntroduceeProtocolState.fromValue(stateNumber);
|
||||
|
||||
IntroduceeSessionState sessionState = new IntroduceeSessionState(storageId,
|
||||
sessionId, groupId, iid, iaid, iname, liaid, state);
|
||||
IntroduceeSessionState sessionState =
|
||||
new IntroduceeSessionState(storageId,
|
||||
sessionId, groupId, introducerId, authorId1,
|
||||
introducerName, introducerLocalAuthorId, state);
|
||||
|
||||
if (d.containsKey(CONTACT_2)) {
|
||||
sessionState.setIntroducedName(d.getString(CONTACT_2));
|
||||
if (d.containsKey(AUTHOR_ID_2)) {
|
||||
sessionState
|
||||
.setIntroducedAuthorId(new AuthorId(d.getRaw(AUTHOR_ID_2)));
|
||||
sessionState.setIntroducedId(
|
||||
@@ -259,19 +244,22 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
}
|
||||
|
||||
if (d.containsKey(REMOTE_AUTHOR_ID))
|
||||
sessionState.setRemoteAuthorId(new AuthorId(d.getRaw(REMOTE_AUTHOR_ID)));
|
||||
sessionState.setRemoteAuthorId(
|
||||
new AuthorId(d.getRaw(REMOTE_AUTHOR_ID)));
|
||||
|
||||
if (d.containsKey(TRANSPORT))
|
||||
sessionState.setTransport(d.getDictionary(TRANSPORT));
|
||||
sessionState.setOurTransportProperties(d.getDictionary(TRANSPORT));
|
||||
|
||||
if (d.containsKey(OUR_PUBLIC_KEY))
|
||||
sessionState.ourPublicKey = d.getRaw(OUR_PUBLIC_KEY);
|
||||
|
||||
if (d.containsKey(OUR_PRIVATE_KEY))
|
||||
if (d.containsKey(OUR_PRIVATE_KEY)&&
|
||||
d.get(OUR_PRIVATE_KEY) != BdfDictionary.NULL_VALUE)
|
||||
sessionState.ourPrivateKey = d.getRaw(OUR_PRIVATE_KEY);
|
||||
|
||||
if (d.containsKey(E_PUBLIC_KEY))
|
||||
sessionState.ePublicKey = d.getRaw(E_PUBLIC_KEY);
|
||||
if (d.containsKey(E_PUBLIC_KEY) &&
|
||||
d.get(E_PUBLIC_KEY) != BdfDictionary.NULL_VALUE)
|
||||
sessionState.theirEphemeralPublicKey = d.getRaw(E_PUBLIC_KEY);
|
||||
|
||||
if (d.containsKey(PUBLIC_KEY))
|
||||
sessionState.setIntroducedPublicKey(d.getRaw(PUBLIC_KEY));
|
||||
@@ -280,7 +268,7 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
sessionState.setAccept(d.getBoolean(ACCEPT));
|
||||
|
||||
if (d.containsKey(NOT_OUR_RESPONSE))
|
||||
sessionState.setOtherResponseId(d.getRaw(NOT_OUR_RESPONSE));
|
||||
sessionState.setTheirResponseId(d.getRaw(NOT_OUR_RESPONSE));
|
||||
|
||||
if (d.containsKey(MAC))
|
||||
sessionState.setMac(d.getRaw(MAC));
|
||||
@@ -293,7 +281,10 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
|
||||
sessionState.setTheirTime(d.getLong(TIME));
|
||||
sessionState.setOurTime(d.getLong(OUR_TIME));
|
||||
sessionState.setName(d.getString(NAME));
|
||||
|
||||
if (d.containsKey(NAME))
|
||||
sessionState.setIntroducedName(d.getString(NAME));
|
||||
|
||||
sessionState.setContactExists(d.getBoolean(EXISTS));
|
||||
sessionState.setTask(d.getLong(TASK).intValue());
|
||||
sessionState.setRemoteAuthorIsUs(d.getBoolean(REMOTE_AUTHOR_IS_US));
|
||||
@@ -305,16 +296,16 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
}
|
||||
|
||||
if (d.containsKey(ANSWERED))
|
||||
sessionState.setAnswered(d.getBoolean(ANSWERED));
|
||||
sessionState.setAnswered(d.getBoolean(ANSWERED));
|
||||
|
||||
if (d.containsKey(MSG))
|
||||
sessionState.setMessage(d.getString(MSG));
|
||||
|
||||
if (d.containsKey(NONCE))
|
||||
sessionState.setNonce(d.getRaw(NONCE));
|
||||
sessionState.setTheirNonce(d.getRaw(NONCE));
|
||||
|
||||
if (d.containsKey(MAC_KEY))
|
||||
sessionState.setMacKey(d.getRaw(MAC_KEY));
|
||||
sessionState.setTheirMacKey(d.getRaw(MAC_KEY));
|
||||
|
||||
if (d.containsKey(OUR_MAC)) {
|
||||
sessionState.setOurMac(d.getRaw(OUR_MAC));
|
||||
@@ -326,21 +317,21 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
|
||||
return sessionState;
|
||||
}
|
||||
|
||||
|
||||
public IntroduceeProtocolState getState() {
|
||||
|
||||
IntroduceeProtocolState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(IntroduceeProtocolState state) {
|
||||
void setState(IntroduceeProtocolState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean getAccept() {
|
||||
boolean wasLocallyAccepted() {
|
||||
return accept;
|
||||
}
|
||||
|
||||
public void setAccept(boolean accept) {
|
||||
void setAccept(boolean accept) {
|
||||
if (accepted) {
|
||||
this.accept &= accept;
|
||||
} else {
|
||||
@@ -377,16 +368,16 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
byte[] getEPublicKey() {
|
||||
return ePublicKey;
|
||||
byte[] getTheirEphemeralPublicKey() {
|
||||
return theirEphemeralPublicKey;
|
||||
}
|
||||
|
||||
void setEPublicKey(byte[] ePublicKey) {
|
||||
this.ePublicKey = ePublicKey;
|
||||
void setTheirEphemeralPublicKey(byte[] theirEphemeralPublicKey) {
|
||||
this.theirEphemeralPublicKey = theirEphemeralPublicKey;
|
||||
}
|
||||
|
||||
public void setTransport(BdfDictionary transport) {
|
||||
this.transport = transport;
|
||||
void setOurTransportProperties(BdfDictionary ourTransportProperties) {
|
||||
this.ourTransportProperties = ourTransportProperties;
|
||||
}
|
||||
|
||||
boolean getContactExists() {
|
||||
@@ -422,163 +413,151 @@ class IntroduceeSessionState extends IntroductionState {
|
||||
return this.otherResponseId;
|
||||
}
|
||||
|
||||
void setOtherResponseId(byte[] otherResponse) {
|
||||
void setTheirResponseId(byte[] otherResponse) {
|
||||
this.otherResponseId = otherResponse;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setTask(int task) {
|
||||
void setTask(int task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public int getTask() {
|
||||
int getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
boolean wasAccepted() {
|
||||
boolean wasLocallyAcceptedOrDeclined() {
|
||||
return accepted;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getIntroducerName() {
|
||||
return introducerName;
|
||||
}
|
||||
|
||||
public byte[] getOurPublicKey() {
|
||||
return ourPublicKey;
|
||||
}
|
||||
|
||||
public void setOurPublicKey(byte[] ourPublicKey) {
|
||||
this.ourPublicKey = ourPublicKey;
|
||||
}
|
||||
|
||||
public byte[] getOurPrivateKey() {
|
||||
return ourPrivateKey;
|
||||
}
|
||||
|
||||
public void setOurPrivateKey(byte[] ourPrivateKey) {
|
||||
this.ourPrivateKey = ourPrivateKey;
|
||||
}
|
||||
|
||||
public GroupId getIntroductionGroupId() {
|
||||
return introductionGroupId;
|
||||
}
|
||||
|
||||
public void setIntroductionGroupId(
|
||||
GroupId introductionGroupId) {
|
||||
this.introductionGroupId = introductionGroupId;
|
||||
}
|
||||
|
||||
public byte[] getIntroducedPublicKey() {
|
||||
return introducedPublicKey;
|
||||
}
|
||||
|
||||
public void setIntroducedPublicKey(byte[] introducedPublicKey) {
|
||||
this.introducedPublicKey = introducedPublicKey;
|
||||
}
|
||||
|
||||
public String getIntroducedName() {
|
||||
return introducedName;
|
||||
}
|
||||
|
||||
public void setIntroducedName(String introducedName) {
|
||||
void setIntroducedName(String introducedName) {
|
||||
this.introducedName = introducedName;
|
||||
}
|
||||
|
||||
public ContactId getIntroducedId() {
|
||||
String getIntroducedName() {
|
||||
return introducedName;
|
||||
}
|
||||
|
||||
byte[] getOurPublicKey() {
|
||||
return ourPublicKey;
|
||||
}
|
||||
|
||||
void setOurPublicKey(byte[] ourPublicKey) {
|
||||
this.ourPublicKey = ourPublicKey;
|
||||
}
|
||||
|
||||
byte[] getOurPrivateKey() {
|
||||
return ourPrivateKey;
|
||||
}
|
||||
|
||||
void setOurPrivateKey(byte[] ourPrivateKey) {
|
||||
this.ourPrivateKey = ourPrivateKey;
|
||||
}
|
||||
|
||||
GroupId getIntroductionGroupId() {
|
||||
return introductionGroupId;
|
||||
}
|
||||
|
||||
byte[] getIntroducedPublicKey() {
|
||||
return introducedPublicKey;
|
||||
}
|
||||
|
||||
void setIntroducedPublicKey(byte[] introducedPublicKey) {
|
||||
this.introducedPublicKey = introducedPublicKey;
|
||||
}
|
||||
|
||||
|
||||
ContactId getIntroducedId() {
|
||||
return introducedId;
|
||||
}
|
||||
|
||||
public void setIntroducedId(
|
||||
void setIntroducedId(
|
||||
ContactId introducedId) {
|
||||
this.introducedId = introducedId;
|
||||
}
|
||||
|
||||
public void setIntroducedAuthorId(
|
||||
void setIntroducedAuthorId(
|
||||
AuthorId introducedAuthorId) {
|
||||
this.introducedAuthorId = introducedAuthorId;
|
||||
}
|
||||
|
||||
public AuthorId getLocalAuthorId() {
|
||||
AuthorId getLocalAuthorId() {
|
||||
return localAuthorId;
|
||||
}
|
||||
|
||||
public void setLocalAuthorId(
|
||||
void setLocalAuthorId(
|
||||
AuthorId localAuthorId) {
|
||||
this.localAuthorId = localAuthorId;
|
||||
}
|
||||
|
||||
public ContactId getIntroducerId() {
|
||||
ContactId getIntroducerId() {
|
||||
return introducerId;
|
||||
}
|
||||
|
||||
public void setMac(byte[] mac) {
|
||||
void setMac(byte[] mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
public byte[] getMac() {
|
||||
byte[] getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
public void setSignature(byte[] signature) {
|
||||
void setSignature(byte[] signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public byte[] getSignature() {
|
||||
byte[] getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public void setOurMac(byte[] ourMac) {
|
||||
void setOurMac(byte[] ourMac) {
|
||||
this.ourMac = ourMac;
|
||||
}
|
||||
|
||||
public byte[] getOurMac() {
|
||||
byte[] getOurMac() {
|
||||
return ourMac;
|
||||
}
|
||||
|
||||
public void setOurSignature(byte[] ourSignature) {
|
||||
void setOurSignature(byte[] ourSignature) {
|
||||
this.ourSignature = ourSignature;
|
||||
}
|
||||
|
||||
public byte[] getOurSignature() {
|
||||
byte[] getOurSignature() {
|
||||
return ourSignature;
|
||||
}
|
||||
|
||||
public void setOurTransport(BdfDictionary ourTransport) {
|
||||
void setOurTransport(BdfDictionary ourTransport) {
|
||||
this.ourTransport = ourTransport;
|
||||
}
|
||||
|
||||
public BdfDictionary getOurTransport() {
|
||||
BdfDictionary getOurTransport() {
|
||||
return ourTransport;
|
||||
}
|
||||
|
||||
public void setNonce(byte[] nonce) {
|
||||
this.nonce = nonce;
|
||||
void setTheirNonce(byte[] theirNonce) {
|
||||
this.theirNonce = theirNonce;
|
||||
}
|
||||
|
||||
public byte[] getNonce() {
|
||||
return nonce;
|
||||
byte[] getTheirNonce() {
|
||||
return theirNonce;
|
||||
}
|
||||
|
||||
public void setMacKey(byte[] macKey) {
|
||||
this.macKey = macKey;
|
||||
void setTheirMacKey(byte[] theirMacKey) {
|
||||
this.theirMacKey = theirMacKey;
|
||||
}
|
||||
|
||||
public byte[] getMacKey() {
|
||||
return this.macKey;
|
||||
byte[] getTheirMacKey() {
|
||||
return this.theirMacKey;
|
||||
}
|
||||
|
||||
public BdfDictionary getTransport() {
|
||||
return transport;
|
||||
BdfDictionary getOurTransportProperties() {
|
||||
return ourTransportProperties;
|
||||
}
|
||||
|
||||
String getIntroducerName() {
|
||||
return introducerName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,8 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
|
||||
public class IntroducerEngine
|
||||
implements ProtocolEngine<BdfDictionary, IntroducerSessionState, BdfDictionary> {
|
||||
implements
|
||||
ProtocolEngine<BdfDictionary, IntroducerSessionState, BdfDictionary> {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(IntroducerEngine.class.getName());
|
||||
@@ -100,8 +101,8 @@ public class IntroducerEngine
|
||||
List<BdfDictionary> messages = new ArrayList<BdfDictionary>(2);
|
||||
BdfDictionary msg1 = new BdfDictionary();
|
||||
msg1.put(TYPE, TYPE_REQUEST);
|
||||
msg1.put(SESSION_ID, localState.getSessionId().getBytes());
|
||||
msg1.put(GROUP_ID, localState.getGroup1Id().getBytes());
|
||||
msg1.put(SESSION_ID, localState.getSessionId());
|
||||
msg1.put(GROUP_ID, localState.getGroup1Id());
|
||||
msg1.put(NAME, localState.getContact2Name());
|
||||
msg1.put(PUBLIC_KEY, localAction.getRaw(PUBLIC_KEY2));
|
||||
if (localAction.containsKey(MSG)) {
|
||||
@@ -112,8 +113,8 @@ public class IntroducerEngine
|
||||
logLocalAction(currentState, localState, msg1);
|
||||
BdfDictionary msg2 = new BdfDictionary();
|
||||
msg2.put(TYPE, TYPE_REQUEST);
|
||||
msg2.put(SESSION_ID, localState.getSessionId().getBytes());
|
||||
msg2.put(GROUP_ID, localState.getGroup2Id().getBytes());
|
||||
msg2.put(SESSION_ID, localState.getSessionId());
|
||||
msg2.put(GROUP_ID, localState.getGroup2Id());
|
||||
msg2.put(NAME, localState.getContact1Name());
|
||||
msg2.put(PUBLIC_KEY, localAction.getRaw(PUBLIC_KEY1));
|
||||
if (localAction.containsKey(MSG)) {
|
||||
@@ -125,7 +126,7 @@ public class IntroducerEngine
|
||||
|
||||
List<Event> events = Collections.emptyList();
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(
|
||||
false, false,localState, messages, events);
|
||||
false, false, localState, messages, events);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Local Action");
|
||||
}
|
||||
@@ -187,19 +188,23 @@ public class IntroducerEngine
|
||||
else if (currentState == FINISHED) {
|
||||
// if it was a response store it to be found later
|
||||
if (action == REMOTE_ACCEPT_1 || action == REMOTE_DECLINE_1) {
|
||||
localState.setResponse1(new MessageId(msg.getRaw(MESSAGE_ID)));
|
||||
localState.setResponse1(
|
||||
new MessageId(msg.getRaw(MESSAGE_ID)));
|
||||
messages = Collections.emptyList();
|
||||
events = Collections.singletonList(getEvent(localState, msg));
|
||||
events = Collections
|
||||
.singletonList(getEvent(localState, msg));
|
||||
} else if (action == REMOTE_ACCEPT_2 ||
|
||||
action == REMOTE_DECLINE_2) {
|
||||
localState.setResponse2(new MessageId(msg.getRaw(MESSAGE_ID)));
|
||||
localState.setResponse2(
|
||||
new MessageId(msg.getRaw(MESSAGE_ID)));
|
||||
messages = Collections.emptyList();
|
||||
events = Collections.singletonList(getEvent(localState, msg));
|
||||
events = Collections
|
||||
.singletonList(getEvent(localState, msg));
|
||||
} else return noUpdate(localState);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad state");
|
||||
}
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(false,
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(false,
|
||||
false, localState, messages, events);
|
||||
} catch (FormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
@@ -240,7 +245,8 @@ public class IntroducerEngine
|
||||
String from = getMessagePartner(localState, msg);
|
||||
String to = getOtherContact(localState, msg);
|
||||
|
||||
LOG.info("Received " + t + " in state " + currentState.name() + " from " +
|
||||
LOG.info("Received " + t + " in state " + currentState.name() +
|
||||
" from " +
|
||||
from + " to " + to + " with session ID " +
|
||||
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
|
||||
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
|
||||
@@ -251,7 +257,8 @@ public class IntroducerEngine
|
||||
}
|
||||
}
|
||||
|
||||
private List<BdfDictionary> forwardMessage(IntroducerSessionState localState,
|
||||
private List<BdfDictionary> forwardMessage(
|
||||
IntroducerSessionState localState,
|
||||
BdfDictionary message) throws FormatException {
|
||||
|
||||
// clone the message here, because we still need the original
|
||||
@@ -275,20 +282,19 @@ public class IntroducerEngine
|
||||
IntroducerSessionState localState, BdfDictionary delivered) {
|
||||
try {
|
||||
return noUpdate(localState);
|
||||
}
|
||||
catch (FormatException e) {
|
||||
} catch (FormatException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Event getEvent(IntroducerSessionState localState,
|
||||
private Event getEvent(IntroducerSessionState localState,
|
||||
BdfDictionary msg) throws FormatException {
|
||||
|
||||
ContactId contactId = localState.getContact1Id();
|
||||
AuthorId authorId = localState.getContact1AuthorId();
|
||||
if (Arrays.equals(msg.getRaw(GROUP_ID),
|
||||
localState.getGroup2Id().getBytes())) {
|
||||
if (Arrays.equals(msg.getRaw(GROUP_ID),
|
||||
localState.getGroup2Id().getBytes())) {
|
||||
contactId = localState.getContact2Id();
|
||||
authorId = localState.getContact2AuthorId();
|
||||
}
|
||||
@@ -306,7 +312,7 @@ public class IntroducerEngine
|
||||
return new IntroductionResponseReceivedEvent(contactId, ir);
|
||||
}
|
||||
|
||||
private boolean isContact1(IntroducerSessionState localState,
|
||||
private boolean isContact1(IntroducerSessionState localState,
|
||||
BdfDictionary msg) throws FormatException {
|
||||
|
||||
byte[] group = msg.getRaw(GROUP_ID);
|
||||
@@ -326,31 +332,31 @@ public class IntroducerEngine
|
||||
BdfDictionary msg) throws FormatException {
|
||||
|
||||
String from = localState.getContact1Name();
|
||||
if (Arrays.equals(msg.getRaw(GROUP_ID),
|
||||
localState.getGroup2Id().getBytes())) {
|
||||
if (Arrays.equals(msg.getRaw(GROUP_ID),
|
||||
localState.getGroup2Id().getBytes())) {
|
||||
from = localState.getContact2Name();
|
||||
}
|
||||
return from;
|
||||
}
|
||||
|
||||
private String getOtherContact(IntroducerSessionState localState,
|
||||
private String getOtherContact(IntroducerSessionState localState,
|
||||
BdfDictionary msg) throws FormatException {
|
||||
|
||||
String to = localState.getContact2Name();
|
||||
if (Arrays.equals(msg.getRaw(GROUP_ID),
|
||||
localState.getGroup2Id().getBytes())) {
|
||||
if (Arrays.equals(msg.getRaw(GROUP_ID),
|
||||
localState.getGroup2Id().getBytes())) {
|
||||
to = localState.getContact1Name();
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
private StateUpdate<IntroducerSessionState, BdfDictionary> abortSession(
|
||||
IntroducerProtocolState currentState,
|
||||
IntroducerProtocolState currentState,
|
||||
IntroducerSessionState localState) throws FormatException {
|
||||
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Aborting protocol session " +
|
||||
Arrays.hashCode(localState.getSessionId().getBytes()) +
|
||||
localState.getSessionId().hashCode() +
|
||||
" in state " + currentState.name());
|
||||
}
|
||||
|
||||
@@ -377,14 +383,15 @@ public class IntroducerEngine
|
||||
Event event2 = new IntroductionAbortedEvent(contactId2, sessionId);
|
||||
events.add(event2);
|
||||
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(false,
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(false,
|
||||
false, localState, messages, events);
|
||||
}
|
||||
|
||||
private StateUpdate<IntroducerSessionState, BdfDictionary> noUpdate(
|
||||
IntroducerSessionState localState) throws FormatException {
|
||||
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(false, false,
|
||||
return new StateUpdate<IntroducerSessionState, BdfDictionary>(false,
|
||||
false,
|
||||
localState, Collections.<BdfDictionary>emptyList(),
|
||||
Collections.<Event>emptyList());
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
|
||||
class IntroducerManager {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(IntroducerManager.class.getName());
|
||||
Logger.getLogger(IntroducerManager.class.getName());
|
||||
|
||||
private final MessageSender messageSender;
|
||||
private final ClientHelper clientHelper;
|
||||
@@ -71,10 +71,15 @@ class IntroducerManager {
|
||||
|
||||
Group g1 = introductionGroupFactory.createIntroductionGroup(c1);
|
||||
Group g2 = introductionGroupFactory.createIntroductionGroup(c2);
|
||||
IntroducerProtocolState state_value = IntroducerProtocolState.PREPARE_REQUESTS;
|
||||
IntroducerProtocolState stateValue =
|
||||
IntroducerProtocolState.PREPARE_REQUESTS;
|
||||
IntroducerSessionState state = new IntroducerSessionState(m.getId(),
|
||||
sessionId, g1.getId(), g2.getId(), c1.getId(), c1.getAuthor().getId(), c1.getAuthor().getName(),
|
||||
c2.getId(), c2.getAuthor().getId(), c2.getAuthor().getName(), state_value);
|
||||
sessionId, g1.getId(), g2.getId(), c1.getId(),
|
||||
c1.getAuthor().getId(), c1.getAuthor().getName(),
|
||||
c2.getId(), c2.getAuthor().getId(), c2.getAuthor().getName(),
|
||||
stateValue);
|
||||
state.setPublicKey1(c1.getAuthor().getPublicKey());
|
||||
state.setPublicKey2(c2.getAuthor().getPublicKey());
|
||||
|
||||
BdfDictionary d = state.toBdfDictionary();
|
||||
|
||||
@@ -122,7 +127,7 @@ class IntroducerManager {
|
||||
|
||||
// save new local state
|
||||
MessageId storageId = result.localState.getStorageId();
|
||||
clientHelper.mergeMessageMetadata(txn, storageId,
|
||||
clientHelper.mergeMessageMetadata(txn, storageId,
|
||||
result.localState.toBdfDictionary());
|
||||
|
||||
// send messages
|
||||
|
||||
@@ -27,6 +27,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STORAGE_ID;
|
||||
|
||||
// This class is not thread-safe
|
||||
class IntroducerSessionState extends IntroductionState {
|
||||
|
||||
private IntroducerProtocolState state;
|
||||
@@ -45,12 +46,12 @@ class IntroducerSessionState extends IntroductionState {
|
||||
private final AuthorId contact2AuthorId;
|
||||
private final String contact2Name;
|
||||
|
||||
|
||||
IntroducerSessionState(MessageId storageId, SessionId sessionId,
|
||||
GroupId group1Id, GroupId group2Id, ContactId contact1Id,
|
||||
AuthorId contact1AuthorId, String contact1Name,
|
||||
ContactId contact2Id, AuthorId contact2AuthorId, String contact2Name,
|
||||
IntroducerProtocolState state){
|
||||
ContactId contact2Id, AuthorId contact2AuthorId,
|
||||
String contact2Name,
|
||||
IntroducerProtocolState state) {
|
||||
|
||||
super(sessionId, storageId);
|
||||
|
||||
@@ -74,7 +75,7 @@ class IntroducerSessionState extends IntroductionState {
|
||||
|
||||
}
|
||||
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = super.toBdfDictionary();
|
||||
d.put(ROLE, ROLE_INTRODUCER);
|
||||
|
||||
@@ -93,6 +94,7 @@ class IntroducerSessionState extends IntroductionState {
|
||||
|
||||
if (publicKey1 != null)
|
||||
d.put(PUBLIC_KEY1, publicKey1);
|
||||
|
||||
if (publicKey2 != null)
|
||||
d.put(PUBLIC_KEY2, publicKey2);
|
||||
|
||||
@@ -104,53 +106,58 @@ class IntroducerSessionState extends IntroductionState {
|
||||
return d;
|
||||
}
|
||||
|
||||
public static IntroducerSessionState fromBdfDictionary(BdfDictionary d)
|
||||
throws FormatException{
|
||||
static IntroducerSessionState fromBdfDictionary(BdfDictionary d)
|
||||
throws FormatException {
|
||||
|
||||
MessageId storageId = new MessageId(d.getRaw(STORAGE_ID));
|
||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||
|
||||
AuthorId aid1 = new AuthorId(d.getRaw(AUTHOR_ID_1));
|
||||
AuthorId aid2 = new AuthorId(d.getRaw(AUTHOR_ID_2));
|
||||
AuthorId authorId1 = new AuthorId(d.getRaw(AUTHOR_ID_1));
|
||||
AuthorId authorId2 = new AuthorId(d.getRaw(AUTHOR_ID_2));
|
||||
|
||||
String author1 = d.getString(CONTACT_1);
|
||||
String author2 = d.getString(CONTACT_2);
|
||||
ContactId cid1 = new ContactId(d.getLong(CONTACT_ID_1).intValue());
|
||||
ContactId cid2 = new ContactId(d.getLong(CONTACT_ID_2).intValue());
|
||||
ContactId contactId1 =
|
||||
new ContactId(d.getLong(CONTACT_ID_1).intValue());
|
||||
ContactId contactId2 =
|
||||
new ContactId(d.getLong(CONTACT_ID_2).intValue());
|
||||
|
||||
GroupId group1Id = new GroupId(d.getRaw(GROUP_ID_1));
|
||||
GroupId group2Id = new GroupId(d.getRaw(GROUP_ID_2));
|
||||
|
||||
|
||||
int stateno = d.getLong(STATE).intValue();
|
||||
IntroducerProtocolState state = IntroducerProtocolState.fromValue(stateno);
|
||||
IntroducerSessionState newstate = new IntroducerSessionState(storageId,
|
||||
sessionId, group1Id, group2Id, cid1, aid1, author1, cid2, aid2,
|
||||
int stateNumber = d.getLong(STATE).intValue();
|
||||
IntroducerProtocolState state = IntroducerProtocolState.fromValue(
|
||||
stateNumber);
|
||||
IntroducerSessionState newState = new IntroducerSessionState(storageId,
|
||||
sessionId, group1Id, group2Id, contactId1, authorId1, author1,
|
||||
contactId2,
|
||||
authorId2,
|
||||
author2, state);
|
||||
|
||||
if (d.containsKey(PUBLIC_KEY1))
|
||||
newstate.setPublicKey1(d.getRaw(PUBLIC_KEY1));
|
||||
newState.setPublicKey1(d.getRaw(PUBLIC_KEY1));
|
||||
|
||||
if (d.containsKey(PUBLIC_KEY2))
|
||||
newstate.setPublicKey2(d.getRaw(PUBLIC_KEY2));
|
||||
newState.setPublicKey2(d.getRaw(PUBLIC_KEY2));
|
||||
|
||||
if (d.containsKey(RESPONSE_1))
|
||||
newstate.setResponse1(new MessageId(d.getRaw(RESPONSE_1)));
|
||||
newState.setResponse1(new MessageId(d.getRaw(RESPONSE_1)));
|
||||
if (d.containsKey(RESPONSE_2))
|
||||
newstate.setResponse2(new MessageId(d.getRaw(RESPONSE_2)));
|
||||
newState.setResponse2(new MessageId(d.getRaw(RESPONSE_2)));
|
||||
|
||||
return newstate;
|
||||
return newState;
|
||||
}
|
||||
|
||||
GroupId getGroup2Id() {
|
||||
return group2Id;
|
||||
}
|
||||
|
||||
public IntroducerProtocolState getState() {
|
||||
IntroducerProtocolState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(IntroducerProtocolState state) {
|
||||
void setState(IntroducerProtocolState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@@ -170,41 +177,43 @@ class IntroducerSessionState extends IntroductionState {
|
||||
this.response2 = response2;
|
||||
}
|
||||
|
||||
public void setPublicKey1(byte[] publicKey1) {
|
||||
void setPublicKey1(byte[] publicKey1) {
|
||||
this.publicKey1 = publicKey1;
|
||||
}
|
||||
|
||||
public void setPublicKey2(byte[] publicKey2) {
|
||||
void setPublicKey2(byte[] publicKey2) {
|
||||
this.publicKey2 = publicKey2;
|
||||
}
|
||||
|
||||
public GroupId getGroup1Id() {
|
||||
GroupId getGroup1Id() {
|
||||
return this.group1Id;
|
||||
}
|
||||
public ContactId getContact2Id() {
|
||||
|
||||
ContactId getContact2Id() {
|
||||
return contact2Id;
|
||||
}
|
||||
|
||||
public AuthorId getContact2AuthorId() {
|
||||
AuthorId getContact2AuthorId() {
|
||||
return contact2AuthorId;
|
||||
}
|
||||
|
||||
public String getContact2Name() {
|
||||
String getContact2Name() {
|
||||
return contact2Name;
|
||||
}
|
||||
|
||||
public String getContact1Name() {
|
||||
String getContact1Name() {
|
||||
return contact1Name;
|
||||
}
|
||||
|
||||
public ContactId getContact1Id() {
|
||||
ContactId getContact1Id() {
|
||||
return contact1Id;
|
||||
}
|
||||
|
||||
public AuthorId getContact1AuthorId() {
|
||||
AuthorId getContact1AuthorId() {
|
||||
return contact1AuthorId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.introduction.IntroducerProtocolState;
|
||||
import org.briarproject.introduction.IntroducerSessionState;
|
||||
import org.briarproject.api.introduction.IntroductionManager;
|
||||
import org.briarproject.api.introduction.IntroductionMessage;
|
||||
import org.briarproject.api.introduction.IntroductionRequest;
|
||||
@@ -193,7 +194,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
*/
|
||||
@Override
|
||||
protected void incomingMessage(Transaction txn, Message m, BdfList body,
|
||||
BdfDictionary message) throws DbException {
|
||||
BdfDictionary message) throws DbException, FormatException{
|
||||
|
||||
// Get message data and type
|
||||
GroupId groupId = m.getGroupId();
|
||||
@@ -204,13 +205,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
boolean stateExists = true;
|
||||
SessionId sessionId;
|
||||
IntroduceeSessionState state;
|
||||
try {
|
||||
sessionId = new SessionId(message.getRaw(SESSION_ID));
|
||||
} catch (FormatException e) {
|
||||
LOG.warning("Introduction without SessionId received.");
|
||||
deleteMessage(txn, m.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
getSessionState(txn, groupId, sessionId.getBytes(), false);
|
||||
} catch (FormatException e) {
|
||||
@@ -256,7 +252,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
(IntroducerSessionState)state, message);
|
||||
} else if (state instanceof IntroduceeSessionState) {
|
||||
introduceeManager.incomingMessage(txn,
|
||||
(IntroduceeSessionState)state, message);
|
||||
(IntroduceeSessionState) state, message);
|
||||
} else {
|
||||
if(LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Unknown role '"
|
||||
@@ -264,6 +260,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
+ "'. Deleting message...");
|
||||
deleteMessage(txn, m.getId());
|
||||
}
|
||||
throw new RuntimeException("Unknown role" +
|
||||
state.getClass().getName());
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
@@ -271,13 +269,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
introducerManager.abort(txn,
|
||||
(IntroducerSessionState)state);
|
||||
else introduceeManager.abort(txn,
|
||||
(IntroduceeSessionState)state);
|
||||
(IntroduceeSessionState) state);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (state instanceof IntroducerSessionState)
|
||||
introducerManager.abort(txn, (IntroducerSessionState)state);
|
||||
else introduceeManager.abort(txn,
|
||||
(IntroduceeSessionState)state);
|
||||
(IntroduceeSessionState) state);
|
||||
}
|
||||
} else {
|
||||
// the message has been validated, so this should not happen
|
||||
@@ -311,7 +309,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
Contact c = db.getContact(txn, contactId);
|
||||
Group g = introductionGroupFactory.createIntroductionGroup(c);
|
||||
IntroduceeSessionState state =
|
||||
(IntroduceeSessionState)getSessionState(txn, g.getId(),
|
||||
(IntroduceeSessionState) getSessionState(txn, g.getId(),
|
||||
sessionId.getBytes());
|
||||
|
||||
introduceeManager.acceptIntroduction(txn, state, timestamp);
|
||||
@@ -334,7 +332,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
getSessionState(txn, g.getId(), sessionId.getBytes());
|
||||
|
||||
introduceeManager.declineIntroduction(txn,
|
||||
(IntroduceeSessionState)state, timestamp);
|
||||
(IntroduceeSessionState) state, timestamp);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
@@ -401,7 +399,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
name = getNameForIntroducer(contactId, iss);
|
||||
} else {
|
||||
IntroduceeSessionState iss =
|
||||
(IntroduceeSessionState)state;
|
||||
(IntroduceeSessionState) state;
|
||||
if (Arrays.equals(iss.getOtherResponseId(),
|
||||
messageId.getBytes())) {
|
||||
// this response is not ours,
|
||||
@@ -417,7 +415,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
}
|
||||
|
||||
authorId = iss.getRemoteAuthorId();
|
||||
name = iss.getName();
|
||||
name = iss.getIntroducedName();
|
||||
}
|
||||
IntroductionResponse ir = new IntroductionResponse(
|
||||
sessionId, messageId, role, time, local,
|
||||
@@ -439,10 +437,10 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
introducesOtherIdentity = false;
|
||||
} else {
|
||||
IntroduceeSessionState iss =
|
||||
(IntroduceeSessionState)state;
|
||||
(IntroduceeSessionState) state;
|
||||
local = false;
|
||||
authorId = iss.getRemoteAuthorId();
|
||||
name = iss.getName();
|
||||
name = iss.getIntroducedName();
|
||||
message = iss.getMessage();
|
||||
boolean finished = iss.getState() == FINISHED;
|
||||
answered = finished || iss.getAnswered();
|
||||
|
||||
@@ -27,7 +27,7 @@ abstract class IntroductionState {
|
||||
this.storageId = storageId;
|
||||
}
|
||||
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
d.put(SESSION_ID, sessionId);
|
||||
d.put(STORAGE_ID, getStorageId());
|
||||
@@ -35,12 +35,12 @@ abstract class IntroductionState {
|
||||
}
|
||||
|
||||
static IntroductionState fromBdfDictionary(BdfDictionary state)
|
||||
throws FormatException {
|
||||
throws FormatException {
|
||||
|
||||
int role = state.getLong(ROLE).intValue();
|
||||
if (role == ROLE_INTRODUCER) {
|
||||
return IntroducerSessionState.fromBdfDictionary(state);
|
||||
} else if(role == ROLE_INTRODUCEE) {
|
||||
} else if (role == ROLE_INTRODUCEE) {
|
||||
return IntroduceeSessionState.fromBdfDictionary(state);
|
||||
} else {
|
||||
throw new FormatException();
|
||||
|
||||
@@ -171,11 +171,11 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
final IntroduceeSessionState state =
|
||||
initializeSessionState(txn, sessionId,
|
||||
introductionGroup1.getId(), msg);
|
||||
state.setIntroducedName(msg.getString(NAME));
|
||||
state.setIntroducedPublicKey(msg.getRaw(PUBLIC_KEY));
|
||||
|
||||
final BdfDictionary statedict = state.toBdfDictionary();
|
||||
statedict.put(STATE, AWAIT_RESPONSES.getValue());
|
||||
statedict.put(SESSION_ID, sessionId);
|
||||
statedict.put(PUBLIC_KEY, msg.getRaw(PUBLIC_KEY));
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).mergeMessageMetadata(txn,
|
||||
@@ -207,7 +207,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
initializeSessionState(txn, sessionId,
|
||||
introductionGroup1.getId(), msg);
|
||||
state.setTheirTime(time);
|
||||
state.setTransport(new BdfDictionary());
|
||||
state.setOurTransportProperties(new BdfDictionary());
|
||||
final BdfDictionary statedict = state.toBdfDictionary();
|
||||
state.setState(AWAIT_RESPONSES);
|
||||
statedict.put(STATE, AWAIT_LOCAL_RESPONSE.getValue());
|
||||
@@ -242,7 +242,6 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
|
||||
BdfDictionary statedict = state.toBdfDictionary();
|
||||
assertEquals(statedict, fromBdfDictionary(statedict).toBdfDictionary());
|
||||
// assertEquals(state, fromBdfDictionary(statedict));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -257,24 +256,23 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
state.setOurTime(-1L);
|
||||
state.setTheirTime(-2L);
|
||||
state.setMessage("");
|
||||
state.setEPublicKey(TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
state.setTransport(new BdfDictionary());
|
||||
state.setTheirEphemeralPublicKey(TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
state.setOurTransportProperties(new BdfDictionary());
|
||||
state.setContactExists(false);
|
||||
state.setRemoteAuthorId(new AuthorId(TestUtils.getRandomId()));
|
||||
state.setRemoteAuthorIsUs(false);
|
||||
state.setOtherResponseId(TestUtils.getRandomId());
|
||||
state.setTheirResponseId(TestUtils.getRandomId());
|
||||
state.setTask(-1);
|
||||
state.setName(TestUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH));
|
||||
state.setIntroducedName(TestUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH));
|
||||
state.setOurPublicKey(TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
state.setOurPrivateKey(TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
state.setIntroducedPublicKey(TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
state.setIntroducedName(TestUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH));
|
||||
state.setMac(TestUtils.getRandomBytes(MAC_LENGTH));
|
||||
state.setSignature(TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH));
|
||||
state.setOurSignature(TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH));
|
||||
state.setOurTransport(new BdfDictionary());
|
||||
state.setNonce(TestUtils.getRandomBytes(32));
|
||||
state.setMacKey(TestUtils.getRandomBytes(32));
|
||||
state.setTheirNonce(TestUtils.getRandomBytes(32));
|
||||
state.setTheirMacKey(TestUtils.getRandomBytes(32));
|
||||
|
||||
BdfDictionary statedict = state.toBdfDictionary();
|
||||
assertEquals(statedict, fromBdfDictionary(statedict).toBdfDictionary());
|
||||
@@ -312,10 +310,10 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
introducer.getAuthor().getId(), introducer.getAuthor().getName(),
|
||||
introducer.getLocalAuthorId(), AWAIT_REQUEST);
|
||||
|
||||
state.setName(msg.getString(NAME));
|
||||
state.setContactExists(true);
|
||||
state.setRemoteAuthorIsUs(false);
|
||||
state.setRemoteAuthorId(introducee2.getAuthor().getId());
|
||||
state.setIntroducedPublicKey(introducee2.getAuthor().getPublicKey());
|
||||
final BdfDictionary statedict = state.toBdfDictionary();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
|
||||
@@ -43,6 +43,8 @@ import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCER;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
@@ -124,6 +126,9 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
final IntroducerSessionState state =
|
||||
getState(msg, introducee1, introducee2);
|
||||
|
||||
state.setPublicKey1(introducee1.getAuthor().getPublicKey());
|
||||
state.setPublicKey2(introducee2.getAuthor().getPublicKey());
|
||||
|
||||
checkInitialisation(time, salt, msg, txn, state);
|
||||
|
||||
IntroducerSessionState result = introducerManager.initialize(txn,
|
||||
@@ -145,6 +150,9 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
final IntroducerSessionState state =
|
||||
getState(msg, introducee1, introducee2);
|
||||
|
||||
state.setPublicKey1(introducee1.getAuthor().getPublicKey());
|
||||
state.setPublicKey2(introducee2.getAuthor().getPublicKey());
|
||||
|
||||
checkInitialisation(time, salt, msg, txn, state);
|
||||
|
||||
final IntroducerSessionState state2 = state;
|
||||
@@ -152,8 +160,8 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
|
||||
final BdfDictionary msg1 = new BdfDictionary();
|
||||
msg1.put(TYPE, TYPE_REQUEST);
|
||||
msg1.put(SESSION_ID, state.getSessionId().getBytes());
|
||||
msg1.put(GROUP_ID, state.getGroup1Id().getBytes());
|
||||
msg1.put(SESSION_ID, state.getSessionId());
|
||||
msg1.put(GROUP_ID, state.getGroup1Id());
|
||||
msg1.put(NAME, state.getContact2Name());
|
||||
msg1.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
|
||||
final BdfDictionary msg1send = (BdfDictionary) msg1.clone();
|
||||
@@ -161,8 +169,8 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
|
||||
final BdfDictionary msg2 = new BdfDictionary();
|
||||
msg2.put(TYPE, TYPE_REQUEST);
|
||||
msg2.put(SESSION_ID, state.getSessionId().getBytes());
|
||||
msg2.put(GROUP_ID, state.getGroup2Id().getBytes());
|
||||
msg2.put(SESSION_ID, state.getSessionId());
|
||||
msg2.put(GROUP_ID, state.getGroup2Id());
|
||||
msg2.put(NAME, state.getContact1Name());
|
||||
msg2.put(PUBLIC_KEY, introducee1.getAuthor().getPublicKey());
|
||||
final BdfDictionary msg2send = (BdfDictionary) msg2.clone();
|
||||
@@ -184,8 +192,13 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
assertFalse(txn.isComplete());
|
||||
}
|
||||
|
||||
private IntroducerSessionState getState(Message msg, Contact c1, Contact c2)
|
||||
throws FormatException {
|
||||
@Test
|
||||
public void testFullSerialization() throws FormatException {
|
||||
|
||||
final Message msg = new Message(new MessageId(TestUtils.getRandomId()),
|
||||
localGroup0.getId(), 0L, TestUtils.getRandomBytes(64));
|
||||
|
||||
IntroducerSessionState state = getState(msg, introducee1, introducee2);
|
||||
|
||||
final BdfDictionary d = new BdfDictionary();
|
||||
d.put(SESSION_ID, new SessionId(msg.getId().getBytes()));
|
||||
@@ -201,10 +214,20 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
d.put(AUTHOR_ID_1, introducee1.getAuthor().getId());
|
||||
d.put(AUTHOR_ID_2, introducee2.getAuthor().getId());
|
||||
|
||||
IntroducerSessionState state =
|
||||
IntroducerSessionState.fromBdfDictionary(d);
|
||||
|
||||
assertEquals(d, state.toBdfDictionary());
|
||||
}
|
||||
|
||||
|
||||
private IntroducerSessionState getState(Message msg, Contact c1, Contact c2)
|
||||
throws FormatException {
|
||||
|
||||
IntroducerSessionState state = new IntroducerSessionState(msg.getId(),
|
||||
new SessionId(msg.getId().getBytes()),
|
||||
introductionGroup1.getId(),
|
||||
introductionGroup2.getId(), c1.getId(), c1.getAuthor().getId(),
|
||||
c1.getAuthor().getName(), c2.getId(), c2.getAuthor().getId(),
|
||||
c2.getAuthor().getName(), PREPARE_REQUESTS);
|
||||
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -235,10 +258,6 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
|
||||
oneOf(clientHelper).addLocalMessage(txn, msg,
|
||||
state.toBdfDictionary(), false);
|
||||
// send message
|
||||
//// oneOf(clientHelper).mergeMessageMetadata(txn, msg.getId(), state2);
|
||||
//// oneOf(messageSender).sendMessage(txn, msg1send);
|
||||
//// oneOf(messageSender).sendMessage(txn, msg2send);
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.LOCAL_AUTHOR_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_IS_US;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCEE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCER;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STORAGE_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
@@ -165,29 +165,32 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
assertTrue(txn.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testAcceptIntroduction() throws DbException, FormatException {
|
||||
final BdfDictionary state = BdfDictionary.of(
|
||||
new BdfEntry(ROLE, ROLE_INTRODUCEE),
|
||||
new BdfEntry(GROUP_ID, introductionGroup1.getId()),
|
||||
new BdfEntry(GROUP_ID_1, introductionGroup1.getId()),
|
||||
// FIXME: GROUP_ID, GROUP_ID_2 and GROUP_ID_1 are needed to
|
||||
// FIXME: deserialize an *introducee*. Why is this?
|
||||
new BdfEntry(GROUP_ID_2, introductionGroup2.getId()),
|
||||
new BdfEntry(SESSION_ID, sessionId),
|
||||
new BdfEntry(STORAGE_ID, sessionId),
|
||||
new BdfEntry(AUTHOR_ID_1,introducee1.getAuthor().getId()),
|
||||
new BdfEntry(AUTHOR_ID_1, introducee1.getAuthor().getId()),
|
||||
new BdfEntry(CONTACT_1, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(CONTACT_ID_1, introducee1.getId().getInt()),
|
||||
new BdfEntry(AUTHOR_ID_2,introducee2.getAuthor().getId() ),
|
||||
new BdfEntry(AUTHOR_ID_2, introducee2.getAuthor().getId()),
|
||||
new BdfEntry(CONTACT_2, introducee2.getAuthor().getName()),
|
||||
new BdfEntry(CONTACT_ID_2, introducee2.getId().getInt()),
|
||||
new BdfEntry(STATE, AWAIT_REQUEST.getValue()),
|
||||
new BdfEntry(TIME, time),
|
||||
new BdfEntry(OUR_TIME, time),
|
||||
new BdfEntry(NAME, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(OUR_TIME, time),
|
||||
new BdfEntry(NAME, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(LOCAL_AUTHOR_ID, introducee1.getLocalAuthorId()),
|
||||
new BdfEntry(INTRODUCER, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(EXISTS, false),
|
||||
new BdfEntry(TASK, NO_TASK),
|
||||
new BdfEntry(REMOTE_AUTHOR_IS_US, false)
|
||||
new BdfEntry(INTRODUCER, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(EXISTS, false),
|
||||
new BdfEntry(TASK, NO_TASK),
|
||||
new BdfEntry(REMOTE_AUTHOR_IS_US, false)
|
||||
);
|
||||
txn = new Transaction(null, false);
|
||||
|
||||
@@ -197,7 +200,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContact(txn, introducee1.getId());
|
||||
will(returnValue(introducee1));
|
||||
oneOf(introductionGroupFactory).createIntroductionGroup(introducee1);
|
||||
oneOf(introductionGroupFactory)
|
||||
.createIntroductionGroup(introducee1);
|
||||
will(returnValue(introductionGroup1));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
|
||||
will(returnValue(state));
|
||||
@@ -218,19 +222,20 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
final BdfDictionary state = BdfDictionary.of(
|
||||
new BdfEntry(ROLE, ROLE_INTRODUCEE),
|
||||
new BdfEntry(GROUP_ID_1, introductionGroup1.getId()),
|
||||
new BdfEntry(GROUP_ID, introductionGroup1.getId()),
|
||||
new BdfEntry(GROUP_ID_2, introductionGroup2.getId()),
|
||||
new BdfEntry(SESSION_ID, sessionId),
|
||||
new BdfEntry(STORAGE_ID, sessionId),
|
||||
new BdfEntry(AUTHOR_ID_1,introducee1.getAuthor().getId()),
|
||||
new BdfEntry(AUTHOR_ID_1, introducee1.getAuthor().getId()),
|
||||
new BdfEntry(CONTACT_1, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(CONTACT_ID_1, introducee1.getId().getInt()),
|
||||
new BdfEntry(AUTHOR_ID_2,introducee2.getAuthor().getId() ),
|
||||
new BdfEntry(AUTHOR_ID_2, introducee2.getAuthor().getId()),
|
||||
new BdfEntry(CONTACT_2, introducee2.getAuthor().getName()),
|
||||
new BdfEntry(CONTACT_ID_2, introducee2.getId().getInt()),
|
||||
new BdfEntry(STATE, AWAIT_REQUEST.getValue()),
|
||||
new BdfEntry(TIME, time),
|
||||
new BdfEntry(OUR_TIME, time),
|
||||
new BdfEntry(NAME, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(OUR_TIME, time),
|
||||
new BdfEntry(NAME, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(LOCAL_AUTHOR_ID, introducee1.getLocalAuthorId()),
|
||||
new BdfEntry(INTRODUCER, introducee1.getAuthor().getName()),
|
||||
new BdfEntry(EXISTS, false),
|
||||
@@ -244,7 +249,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContact(txn, introducee1.getId());
|
||||
will(returnValue(introducee1));
|
||||
oneOf(introductionGroupFactory).createIntroductionGroup(introducee1);
|
||||
oneOf(introductionGroupFactory)
|
||||
.createIntroductionGroup(introducee1);
|
||||
will(returnValue(introductionGroup1));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
|
||||
will(returnValue(state));
|
||||
@@ -273,7 +279,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContact(txn, introducee1.getId());
|
||||
will(returnValue(introducee1));
|
||||
oneOf(introductionGroupFactory).createIntroductionGroup(introducee1);
|
||||
oneOf(introductionGroupFactory)
|
||||
.createIntroductionGroup(introducee1);
|
||||
will(returnValue(introductionGroup1));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
introductionGroup1.getId());
|
||||
@@ -330,9 +337,6 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
|
||||
final IntroducerSessionState sessionState = initializeIntroducerSS();
|
||||
final BdfDictionary state = sessionState.toBdfDictionary();
|
||||
state.put(ROLE, ROLE_INTRODUCER);
|
||||
state.put(GROUP_ID_1, introductionGroup1.getId());
|
||||
state.put(GROUP_ID_2, introductionGroup2.getId());
|
||||
|
||||
txn = new Transaction(null, false);
|
||||
|
||||
@@ -359,7 +363,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
final Contact introducer = new Contact(cid, author, aid, true, false);
|
||||
final IntroduceeSessionState state = new IntroduceeSessionState(
|
||||
new MessageId(TestUtils.getRandomId()),
|
||||
new SessionId(TestUtils.getRandomId()),
|
||||
new SessionId(TestUtils.getRandomId()),
|
||||
new GroupId(TestUtils.getRandomId()),
|
||||
introducer.getId(), introducer.getAuthor().getId(),
|
||||
introducer.getAuthor().getName(), introducer.getLocalAuthorId(),
|
||||
@@ -368,9 +372,9 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
state.setContactExists(true);
|
||||
state.setRemoteAuthorIsUs(false);
|
||||
state.setRemoteAuthorId(introducee2.getAuthor().getId());
|
||||
state.setName(introducee2.getAuthor().getName());
|
||||
|
||||
return state;
|
||||
state.setIntroducedName(introducee2.getAuthor().getName());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
private IntroducerSessionState initializeIntroducerSS() {
|
||||
@@ -382,10 +386,12 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
return new IntroducerSessionState(
|
||||
new MessageId(TestUtils.getRandomId()),
|
||||
new SessionId(TestUtils.getRandomId()),
|
||||
new GroupId(TestUtils.getRandomId()),
|
||||
new GroupId(TestUtils.getRandomId()),
|
||||
introducer.getId(), introducer.getAuthor().getId(), introducer.getAuthor().getName(),
|
||||
introducer.getId(), introducer.getAuthor().getId(), introducer.getAuthor().getName(),
|
||||
introductionGroup1.getId(),
|
||||
introductionGroup2.getId(),
|
||||
introducer.getId(), introducer.getAuthor().getId(),
|
||||
introducer.getAuthor().getName(),
|
||||
introducer.getId(), introducer.getAuthor().getId(),
|
||||
introducer.getAuthor().getName(),
|
||||
IntroducerProtocolState.AWAIT_RESPONSES);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user