mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-27 12:19:04 +00:00
Switch to a more heavily TOFU model for identity keys.
1) There is no longer a concept of "verified" or "unverified." Only "what we saw last time" and "different from last time." 2) Let's eliminate "verify session," since we're all about identity keys now. 3) Mark manually processed key exchanges as processed.
This commit is contained in:
@@ -16,14 +16,19 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKey;
|
||||
import org.thoughtcrime.securesms.crypto.InvalidKeyException;
|
||||
import org.thoughtcrime.securesms.crypto.InvalidVersionException;
|
||||
import org.thoughtcrime.securesms.crypto.KeyExchangeMessage;
|
||||
@@ -42,36 +47,32 @@ import org.thoughtcrime.securesms.util.MemoryCleaner;
|
||||
public class ReceiveKeyActivity extends PassphraseRequiredSherlockActivity {
|
||||
|
||||
private TextView descriptionText;
|
||||
private TextView signatureText;
|
||||
|
||||
private Button confirmButton;
|
||||
private Button cancelButton;
|
||||
private Button verifySessionButton;
|
||||
private Button verifyIdentityButton;
|
||||
|
||||
private Recipient recipient;
|
||||
private long threadId;
|
||||
private long messageId;
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
private KeyExchangeMessage keyExchangeMessage;
|
||||
private KeyExchangeProcessor keyExchangeProcessor;
|
||||
|
||||
private boolean sent;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state) {
|
||||
super.onCreate(state);
|
||||
setContentView(R.layout.receive_key_activity);
|
||||
|
||||
initializeResources();
|
||||
|
||||
try {
|
||||
initializeKey();
|
||||
initializeText();
|
||||
} catch (InvalidKeyException ike) {
|
||||
Log.w("ReceiveKeyActivity", ike);
|
||||
initializeCorruptedKeyText();
|
||||
} catch (InvalidVersionException ive) {
|
||||
initializeBadVersionText();
|
||||
Log.w("ReceiveKeyActivity", ive);
|
||||
}
|
||||
initializeListeners();
|
||||
}
|
||||
@@ -83,64 +84,20 @@ public class ReceiveKeyActivity extends PassphraseRequiredSherlockActivity {
|
||||
}
|
||||
|
||||
private void initializeText() {
|
||||
if (keyExchangeProcessor.hasCompletedSession()) initializeTextForExistingSession();
|
||||
else initializeTextForNewSession();
|
||||
SpannableString spannableString = new SpannableString(descriptionText.getText() + " " +
|
||||
getString(R.string.ReceiveKeyActivity_you_may_wish_to_verify_this_contact));
|
||||
spannableString.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
Intent intent = new Intent(ReceiveKeyActivity.this, VerifyIdentityActivity.class);
|
||||
intent.putExtra("recipient", recipient);
|
||||
intent.putExtra("master_secret", masterSecret);
|
||||
startActivity(intent);
|
||||
}
|
||||
}, descriptionText.getText().length()+1, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
initializeSignatureText();
|
||||
}
|
||||
|
||||
private void initializeCorruptedKeyText() {
|
||||
descriptionText.setText(R.string.ReceiveKeyActivity_error_you_have_received_a_corrupted_public_key);
|
||||
confirmButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void initializeBadVersionText() {
|
||||
descriptionText.setText(R.string.ReceiveKeyActivity_error_you_have_received_a_public_key_from_an_unsupported_version_of_the_protocol);
|
||||
confirmButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void initializeSignatureText() {
|
||||
if (!keyExchangeMessage.hasIdentityKey()) {
|
||||
signatureText.setText(R.string.ReceiveKeyActivity_this_key_exchange_message_does_not_include_an_identity_signature);
|
||||
return;
|
||||
}
|
||||
|
||||
IdentityKey identityKey = keyExchangeMessage.getIdentityKey();
|
||||
String identityName = DatabaseFactory.getIdentityDatabase(this).getNameForIdentity(masterSecret, identityKey);
|
||||
|
||||
if (identityName == null) {
|
||||
signatureText.setText(R.string.ReceiveKeyActivity_this_key_exchange_message_includes_an_identity_signature_but_you_do_not_yet_trust_it);
|
||||
} else {
|
||||
signatureText.setText(String.format(getString(R.string.ReceiveKeyActivity_this_key_exchange_message_includes_an_identity_signature_which_you_trust_for_s), identityName));
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeTextForExistingSession() {
|
||||
if (keyExchangeProcessor.isRemoteKeyExchangeForExistingSession(keyExchangeMessage)) {
|
||||
descriptionText.setText(String.format(getString(R.string.ReceiveKeyActivity_this_is_the_key_that_you_sent_to_start_your_current_encrypted_session_with_s), recipient.toShortString()));
|
||||
this.confirmButton.setVisibility(View.GONE);
|
||||
this.verifySessionButton.setVisibility(View.VISIBLE);
|
||||
this.verifyIdentityButton.setVisibility(View.VISIBLE);
|
||||
} else if (keyExchangeProcessor.isLocalKeyExchangeForExistingSession(keyExchangeMessage)) {
|
||||
descriptionText.setText(String.format(getString(R.string.ReceiveKeyActivity_this_is_the_key_that_you_received_to_start_your_current_encrypted_session_with_s), recipient.toShortString()));
|
||||
this.confirmButton.setVisibility(View.GONE);
|
||||
this.verifySessionButton.setVisibility(View.VISIBLE);
|
||||
this.verifyIdentityButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
descriptionText.setText(String.format(getString(R.string.ReceiveKeyActivity_you_have_received_a_key_exchange_message_from_s_warning_you_already_have_an_encrypted_session), recipient.toShortString()));
|
||||
this.confirmButton.setVisibility(View.VISIBLE);
|
||||
this.verifyIdentityButton.setVisibility(View.GONE);
|
||||
this.verifySessionButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeTextForNewSession() {
|
||||
if (keyExchangeProcessor.hasInitiatedSession() && !this.sent)
|
||||
descriptionText.setText(String.format(getString(R.string.ReceiveKeyActivity_you_have_received_a_key_exchange_message_from_s_you_have_previously_initiated), recipient.toShortString()));
|
||||
else if (keyExchangeProcessor.hasInitiatedSession() && this.sent)
|
||||
descriptionText.setText(String.format(getString(R.string.ReceiveKeyActivity_you_have_initiated_a_key_exchange_message_with_s_but_have_not_yet_received_a_reply), recipient.toShortString()));
|
||||
else if (!keyExchangeProcessor.hasInitiatedSession() && !this.sent)
|
||||
descriptionText.setText(String.format(getString(R.string.ReceiveKeyActivity_you_have_received_a_key_exchange_message_from_s_you_have_no_existing_session), recipient.toShortString()));
|
||||
descriptionText.setText(spannableString);
|
||||
descriptionText.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
private void initializeKey() throws InvalidKeyException, InvalidVersionException {
|
||||
@@ -150,52 +107,46 @@ public class ReceiveKeyActivity extends PassphraseRequiredSherlockActivity {
|
||||
|
||||
private void initializeResources() {
|
||||
this.descriptionText = (TextView) findViewById(R.id.description_text);
|
||||
this.signatureText = (TextView) findViewById(R.id.signature_text);
|
||||
this.confirmButton = (Button) findViewById(R.id.ok_button);
|
||||
this.cancelButton = (Button) findViewById(R.id.cancel_button);
|
||||
this.verifyIdentityButton = (Button) findViewById(R.id.verify_identity_button);
|
||||
this.verifySessionButton = (Button) findViewById(R.id.verify_session_button);
|
||||
this.recipient = getIntent().getParcelableExtra("recipient");
|
||||
this.threadId = getIntent().getLongExtra("thread_id", -1);
|
||||
this.messageId = getIntent().getLongExtra("message_id", -1);
|
||||
this.masterSecret = (MasterSecret)getIntent().getParcelableExtra("master_secret");
|
||||
this.sent = getIntent().getBooleanExtra("sent", false);
|
||||
this.keyExchangeProcessor = new KeyExchangeProcessor(this, masterSecret, recipient);
|
||||
}
|
||||
|
||||
private void initializeListeners() {
|
||||
this.confirmButton.setOnClickListener(new OkListener());
|
||||
this.cancelButton.setOnClickListener(new CancelListener());
|
||||
this.verifyIdentityButton.setOnClickListener(new VerifyIdentityListener());
|
||||
this.verifySessionButton.setOnClickListener(new VerifySessionListener());
|
||||
}
|
||||
|
||||
private class VerifyIdentityListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(ReceiveKeyActivity.this, VerifyIdentityActivity.class);
|
||||
intent.putExtra("recipient", recipient);
|
||||
intent.putExtra("master_secret", masterSecret);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private class VerifySessionListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(ReceiveKeyActivity.this, VerifyKeysActivity.class);
|
||||
intent.putExtra("recipient", recipient);
|
||||
intent.putExtra("master_secret", masterSecret);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private class OkListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
keyExchangeProcessor.processKeyExchangeMessage(keyExchangeMessage, threadId);
|
||||
finish();
|
||||
new AsyncTask<Void, Void, Void> () {
|
||||
private ProgressDialog dialog;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
dialog = ProgressDialog.show(ReceiveKeyActivity.this, "Processing",
|
||||
"Processing key exchange...", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
keyExchangeProcessor.processKeyExchangeMessage(keyExchangeMessage, threadId);
|
||||
DatabaseFactory.getEncryptingSmsDatabase(ReceiveKeyActivity.this)
|
||||
.markAsProcessedKeyExchange(messageId);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
dialog.dismiss();
|
||||
finish();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,5 +156,4 @@ public class ReceiveKeyActivity extends PassphraseRequiredSherlockActivity {
|
||||
ReceiveKeyActivity.this.finish();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user