Replace old introduction client with new one

parent 1bc29fec
...@@ -11,7 +11,6 @@ import android.widget.ProgressBar; ...@@ -11,7 +11,6 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
...@@ -35,7 +34,7 @@ import static android.app.Activity.RESULT_OK; ...@@ -35,7 +34,7 @@ import static android.app.Activity.RESULT_OK;
import static android.view.View.GONE; import static android.view.View.GONE;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_MESSAGE_LENGTH; import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH;
public class IntroductionMessageFragment extends BaseFragment public class IntroductionMessageFragment extends BaseFragment
implements TextInputListener { implements TextInputListener {
...@@ -175,7 +174,7 @@ public class IntroductionMessageFragment extends BaseFragment ...@@ -175,7 +174,7 @@ public class IntroductionMessageFragment extends BaseFragment
ui.message.setSendButtonEnabled(false); ui.message.setSendButtonEnabled(false);
String msg = ui.message.getText().toString(); String msg = ui.message.getText().toString();
msg = StringUtils.truncateUtf8(msg, MAX_INTRODUCTION_MESSAGE_LENGTH); msg = StringUtils.truncateUtf8(msg, MAX_REQUEST_MESSAGE_LENGTH);
makeIntroduction(contact1, contact2, msg); makeIntroduction(contact1, contact2, msg);
// don't wait for the introduction to be made before finishing activity // don't wait for the introduction to be made before finishing activity
...@@ -190,7 +189,7 @@ public class IntroductionMessageFragment extends BaseFragment ...@@ -190,7 +189,7 @@ public class IntroductionMessageFragment extends BaseFragment
try { try {
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
introductionManager.makeIntroduction(c1, c2, msg, timestamp); introductionManager.makeIntroduction(c1, c2, msg, timestamp);
} catch (DbException | FormatException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
introductionError(); introductionError();
} }
......
package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_ABORT;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_ACK;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_RESPONSE;
@NotNullByDefault
public enum IntroduceeAction {
LOCAL_ACCEPT,
LOCAL_DECLINE,
LOCAL_ABORT,
REMOTE_REQUEST,
REMOTE_ACCEPT,
REMOTE_DECLINE,
REMOTE_ABORT,
ACK;
@Nullable
public static IntroduceeAction getRemote(int type, boolean accept) {
if (type == TYPE_REQUEST) return REMOTE_REQUEST;
if (type == TYPE_RESPONSE && accept) return REMOTE_ACCEPT;
if (type == TYPE_RESPONSE) return REMOTE_DECLINE;
if (type == TYPE_ACK) return ACK;
if (type == TYPE_ABORT) return REMOTE_ABORT;
return null;
}
@Nullable
public static IntroduceeAction getRemote(int type) {
return getRemote(type, true);
}
@Nullable
public static IntroduceeAction getLocal(int type, boolean accept) {
if (type == TYPE_RESPONSE && accept) return LOCAL_ACCEPT;
if (type == TYPE_RESPONSE) return LOCAL_DECLINE;
if (type == TYPE_ACK) return ACK;
if (type == TYPE_ABORT) return LOCAL_ABORT;
return null;
}
@Nullable
public static IntroduceeAction getLocal(int type) {
return getLocal(type, true);
}
}
package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.briar.api.introduction.IntroduceeAction.ACK;
import static org.briarproject.briar.api.introduction.IntroduceeAction.LOCAL_ACCEPT;
import static org.briarproject.briar.api.introduction.IntroduceeAction.LOCAL_DECLINE;
import static org.briarproject.briar.api.introduction.IntroduceeAction.REMOTE_ACCEPT;
import static org.briarproject.briar.api.introduction.IntroduceeAction.REMOTE_DECLINE;
import static org.briarproject.briar.api.introduction.IntroduceeAction.REMOTE_REQUEST;
@Immutable
@NotNullByDefault
public enum IntroduceeProtocolState {
ERROR(0),
AWAIT_REQUEST(1) {
@Override
public IntroduceeProtocolState next(IntroduceeAction a) {
if (a == REMOTE_REQUEST) return AWAIT_RESPONSES;
return ERROR;
}
},
AWAIT_RESPONSES(2) {
@Override
public IntroduceeProtocolState next(IntroduceeAction a) {
if (a == REMOTE_ACCEPT) return AWAIT_LOCAL_RESPONSE;
if (a == REMOTE_DECLINE) return FINISHED;
if (a == LOCAL_ACCEPT) return AWAIT_REMOTE_RESPONSE;
if (a == LOCAL_DECLINE) return FINISHED;
return ERROR;
}
},
AWAIT_REMOTE_RESPONSE(3) {
@Override
public IntroduceeProtocolState next(IntroduceeAction a) {
if (a == REMOTE_ACCEPT) return AWAIT_ACK;
if (a == REMOTE_DECLINE) return FINISHED;
return ERROR;
}
},
AWAIT_LOCAL_RESPONSE(4) {
@Override
public IntroduceeProtocolState next(IntroduceeAction a) {
if (a == LOCAL_ACCEPT) return AWAIT_ACK;
if (a == LOCAL_DECLINE) return FINISHED;
return ERROR;
}
},
AWAIT_ACK(5) {
@Override
public IntroduceeProtocolState next(IntroduceeAction a) {
if (a == ACK) return FINISHED;
return ERROR;
}
},
FINISHED(6);
private final int value;
IntroduceeProtocolState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static IntroduceeProtocolState fromValue(int value) {
for (IntroduceeProtocolState s : values()) {
if (s.value == value) return s;
}
throw new IllegalArgumentException();
}
public IntroduceeProtocolState next(IntroduceeAction a) {
return this;
}
}
package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_ABORT;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_ACK;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_RESPONSE;
@NotNullByDefault
public enum IntroducerAction {
LOCAL_REQUEST,
LOCAL_ABORT,
REMOTE_ACCEPT_1,
REMOTE_ACCEPT_2,
REMOTE_DECLINE_1,
REMOTE_DECLINE_2,
REMOTE_ABORT,
ACK_1,
ACK_2;
@Nullable
public static IntroducerAction getLocal(int type) {
if (type == TYPE_REQUEST) return LOCAL_REQUEST;
if (type == TYPE_ABORT) return LOCAL_ABORT;
return null;
}
@Nullable
public static IntroducerAction getRemote(int type, boolean one,
boolean accept) {
if (one) {
if (type == TYPE_RESPONSE && accept) return REMOTE_ACCEPT_1;
if (type == TYPE_RESPONSE) return REMOTE_DECLINE_1;
if (type == TYPE_ACK) return ACK_1;
} else {
if (type == TYPE_RESPONSE && accept) return REMOTE_ACCEPT_2;
if (type == TYPE_RESPONSE) return REMOTE_DECLINE_2;
if (type == TYPE_ACK) return ACK_2;
}
if (type == TYPE_ABORT) return REMOTE_ABORT;
return null;
}
@Nullable
public static IntroducerAction getRemote(int type, boolean one) {
return getRemote(type, one, true);
}
}
package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.briar.api.introduction.IntroducerAction.ACK_1;
import static org.briarproject.briar.api.introduction.IntroducerAction.ACK_2;
import static org.briarproject.briar.api.introduction.IntroducerAction.LOCAL_REQUEST;
import static org.briarproject.briar.api.introduction.IntroducerAction.REMOTE_ABORT;
import static org.briarproject.briar.api.introduction.IntroducerAction.REMOTE_ACCEPT_1;
import static org.briarproject.briar.api.introduction.IntroducerAction.REMOTE_ACCEPT_2;
import static org.briarproject.briar.api.introduction.IntroducerAction.REMOTE_DECLINE_1;
import static org.briarproject.briar.api.introduction.IntroducerAction.REMOTE_DECLINE_2;
@Immutable
@NotNullByDefault
public enum IntroducerProtocolState {
ERROR(0),
PREPARE_REQUESTS(1) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == LOCAL_REQUEST) return AWAIT_RESPONSES;
return ERROR;
}
},
AWAIT_RESPONSES(2) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == REMOTE_ACCEPT_1) return AWAIT_RESPONSE_2;
if (a == REMOTE_ACCEPT_2) return AWAIT_RESPONSE_1;
if (a == REMOTE_DECLINE_1) return FINISHED;
if (a == REMOTE_DECLINE_2) return FINISHED;
return ERROR;
}
},
AWAIT_RESPONSE_1(3) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == REMOTE_ACCEPT_1) return AWAIT_ACKS;
if (a == REMOTE_DECLINE_1) return FINISHED;
return ERROR;
}
},
AWAIT_RESPONSE_2(4) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == REMOTE_ACCEPT_2) return AWAIT_ACKS;
if (a == REMOTE_DECLINE_2) return FINISHED;
return ERROR;
}
},
AWAIT_ACKS(5) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == ACK_1) return AWAIT_ACK_2;
if (a == ACK_2) return AWAIT_ACK_1;
return ERROR;
}
},
AWAIT_ACK_1(6) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == ACK_1) return FINISHED;
return ERROR;
}
},
AWAIT_ACK_2(7) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == ACK_2) return FINISHED;
return ERROR;
}
},
FINISHED(8) {
@Override
public IntroducerProtocolState next(IntroducerAction a) {
if (a == REMOTE_ABORT) return ERROR;
return FINISHED;
}
};
private final int value;
IntroducerProtocolState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static IntroducerProtocolState fromValue(int value) {
for (IntroducerProtocolState s : values()) {
if (s.value == value) return s;
}
throw new IllegalArgumentException();
}
public static boolean isOngoing(IntroducerProtocolState state) {
return state != FINISHED && state != ERROR;
}
public IntroducerProtocolState next(IntroducerAction a) {
return this;
}
}
...@@ -4,126 +4,26 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_L ...@@ -4,126 +4,26 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_L
public interface IntroductionConstants { public interface IntroductionConstants {
/* Protocol roles */
int ROLE_INTRODUCER = 0;
int ROLE_INTRODUCEE = 1;
/* Message types */
int TYPE_REQUEST = 1;
int TYPE_RESPONSE = 2;
int TYPE_ACK = 3;
int TYPE_ABORT = 4;
/* Message Constants */
String TYPE = "type";
String GROUP_ID = "groupId";
String SESSION_ID = "sessionId";
String CONTACT = "contactId";
String NAME = "name";
String PUBLIC_KEY = "publicKey";
String E_PUBLIC_KEY = "ephemeralPublicKey";
String MSG = "msg";
String ACCEPT = "accept";
String TIME = "time";
String TRANSPORT = "transport";
String MESSAGE_ID = "messageId";
String MESSAGE_TIME = "timestamp";
String MAC = "mac";
String SIGNATURE = "signature";
/* Validation Constants */
/**
* The length of the message authentication code in bytes.
*/
int MAC_LENGTH = 32;
/** /**
* The maximum length of the introducer's optional message to the * The maximum length of the introducer's optional message to the
* introducees in UTF-8 bytes. * introducees in UTF-8 bytes.
*/ */
int MAX_INTRODUCTION_MESSAGE_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024; int MAX_REQUEST_MESSAGE_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
/* Introducer Local State Metadata */
String STATE = "state";
String ROLE = "role";
String GROUP_ID_1 = "groupId1";
String GROUP_ID_2 = "groupId2";
String CONTACT_1 = "contact1";
String CONTACT_2 = "contact2";
String AUTHOR_ID_1 = "authorId1";
String AUTHOR_ID_2 = "authorId2";
String CONTACT_ID_1 = "contactId1";
String CONTACT_ID_2 = "contactId2";
String RESPONSE_1 = "response1";
String RESPONSE_2 = "response2";
/* Introduction Request Action */
String PUBLIC_KEY1 = "publicKey1";
String PUBLIC_KEY2 = "publicKey2";
/* Introducee Local State Metadata (without those already defined) */
String STORAGE_ID = "storageId";
String INTRODUCER = "introducer";
String LOCAL_AUTHOR_ID = "localAuthorId";
String REMOTE_AUTHOR_ID = "remoteAuthorId";
String OUR_PUBLIC_KEY = "ourEphemeralPublicKey";
String OUR_PRIVATE_KEY = "ourEphemeralPrivateKey";
String OUR_TIME = "ourTime";
String ADDED_CONTACT_ID = "addedContactId";
String NOT_OUR_RESPONSE = "notOurResponse";
String EXISTS = "contactExists";
String REMOTE_AUTHOR_IS_US = "remoteAuthorIsUs";
String ANSWERED = "answered";
String NONCE = "nonce";
String MAC_KEY = "macKey";
String OUR_TRANSPORT = "ourTransport";
String OUR_MAC = "ourMac";
String OUR_SIGNATURE = "ourSignature";
String TASK = "task";
int TASK_ADD_CONTACT = 0;
int TASK_ACTIVATE_CONTACT = 1;
int TASK_ABORT = 2;
/**
* Label for deriving the shared secret.
*/
String SHARED_SECRET_LABEL =
"org.briarproject.briar.introduction/SHARED_SECRET";
/** String LABEL_SESSION_ID = "org.briarproject.briar.introduction/SESSION_ID";
* Label for deriving Alice's key binding nonce from the shared secret.
*/
String ALICE_NONCE_LABEL =
"org.briarproject.briar.introduction/ALICE_NONCE";
/** String LABEL_MASTER_KEY = "org.briarproject.briar.introduction/MASTER_KEY";
* Label for deriving Bob's key binding nonce from the shared secret.
*/
String BOB_NONCE_LABEL =
"org.briarproject.briar.introduction/BOB_NONCE";
/** String LABEL_ALICE_MAC_KEY =
* Label for deriving Alice's MAC key from the shared secret.
*/
String ALICE_MAC_KEY_LABEL =
"org.briarproject.briar.introduction/ALICE_MAC_KEY"; "org.briarproject.briar.introduction/ALICE_MAC_KEY";
/** String LABEL_BOB_MAC_KEY =
* Label for deriving Bob's MAC key from the shared secret.
*/
String BOB_MAC_KEY_LABEL =
"org.briarproject.briar.introduction/BOB_MAC_KEY"; "org.briarproject.briar.introduction/BOB_MAC_KEY";
/** String LABEL_AUTH_MAC = "org.briarproject.briar.introduction/AUTH_MAC";
* Label for signing the introduction response.
*/ String LABEL_AUTH_SIGN = "org.briarproject.briar.introduction/AUTH_SIGN";
String SIGNING_LABEL =
"org.briarproject.briar.introduction/RESPONSE_SIGNATURE"; String LABEL_AUTH_NONCE = "org.briarproject.briar.introduction/AUTH_NONCE";
/**
* Label for MACing the introduction response.
*/
String MAC_LABEL = "org.briarproject.briar.introduction/RESPONSE_MAC";
} }
package org.briarproject.briar.api.introduction; package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
...@@ -24,25 +23,25 @@ public interface IntroductionManager extends ConversationClient { ...@@ -24,25 +23,25 @@ public interface IntroductionManager extends ConversationClient {
/** /**
* The current version of the introduction client. * The current version of the introduction client.
*/ */
int CLIENT_VERSION = 0; int CLIENT_VERSION = 1;
/** /**
* Sends two initial introduction messages. * Sends two initial introduction messages.
*/ */
void makeIntroduction(Contact c1, Contact c2, @Nullable String msg, void makeIntroduction(Contact c1, Contact c2, @Nullable String msg,
long timestamp) throws DbException, FormatException; long timestamp) throws DbException;
/** /**
* Accepts an introduction. * Accepts an introduction.
*/ */
void acceptIntroduction(ContactId contactId, SessionId sessionId, void acceptIntroduction(ContactId contactId, SessionId sessionId,
long timestamp) throws DbException, FormatException; long timestamp) throws DbException;
/** /**
* Declines an introduction. * Declines an introduction.
*/ */
void declineIntroduction(ContactId contactId, SessionId sessionId, void declineIntroduction(ContactId contactId, SessionId sessionId,
long timestamp) throws DbException, FormatException; long timestamp) throws DbException;
/** /**
* Returns all introduction messages for the given contact. * Returns all introduction messages for the given contact.
......
...@@ -8,7 +8,7 @@ import org.briarproject.briar.api.client.SessionId; ...@@ -8,7 +8,7 @@ import org.briarproject.briar.api.client.SessionId;