From a95c451f1e6ee69fbf3b0072d672c3609a4b1e7d Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sun, 6 Sep 2015 15:08:42 +0200 Subject: [PATCH] Only show that have sessions in fingerprint list Doesn't access database directly anymore but goes through AxolotlService now to obtain list of fingerprints associated with an Account/Contact. This should prevent orphaned keys littering the UI which previously couldn't be removed through the Clear Devices function. Together with 1c79982da84964c1d81179a0927d9cd1eadf53de this fixes #1393 --- .../crypto/axolotl/AxolotlService.java | 24 ++++++++++--- .../crypto/axolotl/XmppAxolotlSession.java | 2 +- .../services/XmppConnectionService.java | 4 +-- .../ui/ContactDetailsActivity.java | 8 ++--- .../conversations/ui/EditAccountActivity.java | 15 ++++---- .../conversations/ui/TrustKeysActivity.java | 36 +++++++++---------- .../siacs/conversations/ui/XmppActivity.java | 19 +++++----- 7 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index e4c49e7c..a8e414f0 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -190,8 +190,8 @@ public class AxolotlService { this.executor = new SerialSingleThreadExecutor(); } - public IdentityKey getOwnPublicKey() { - return axolotlStore.getIdentityKeyPair().getPublicKey(); + public String getOwnFingerprint() { + return axolotlStore.getIdentityKeyPair().getPublicKey().getFingerprint().replaceAll("\\s", ""); } public Set getKeysWithTrust(XmppAxolotlSession.Trust trust) { @@ -222,6 +222,22 @@ public class AxolotlService { return sessions; } + public Set getFingerprintsForOwnSessions() { + Set fingerprints = new HashSet<>(); + for (XmppAxolotlSession session : findOwnSessions()) { + fingerprints.add(session.getFingerprint()); + } + return fingerprints; + } + + public Set getFingerprintsForContact(final Contact contact) { + Set fingerprints = new HashSet<>(); + for (XmppAxolotlSession session : findSessionsforContact(contact)) { + fingerprints.add(session.getFingerprint()); + } + return fingerprints; + } + private boolean hasAny(Contact contact) { AxolotlAddress contactAddress = getAddressForJid(contact.getJid()); return sessions.hasAny(contactAddress); @@ -310,8 +326,8 @@ public class AxolotlService { }); } - public void purgeKey(IdentityKey identityKey) { - axolotlStore.setFingerprintTrust(identityKey.getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED); + public void purgeKey(final String fingerprint) { + axolotlStore.setFingerprintTrust(fingerprint.replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED); } public void publishOwnDeviceIdIfNeeded() { diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java index c4053854..d582db40 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java @@ -91,7 +91,7 @@ public class XmppAxolotlSession { public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, String fingerprint) { this(account, store, remoteAddress); - this.fingerprint = fingerprint; + this.fingerprint = fingerprint.replaceAll("\\s",""); } public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 08d40fcb..1168e040 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -754,7 +754,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } break; case Message.ENCRYPTION_AXOLOTL: - message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); + message.setAxolotlFingerprint(account.getAxolotlService().getOwnFingerprint()); if (message.needsUploading()) { if (account.httpUploadAvailable() || message.fixCounterpart()) { this.sendFileMessage(message,delay); @@ -799,7 +799,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } break; case Message.ENCRYPTION_AXOLOTL: - message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); + message.setAxolotlFingerprint(account.getAxolotlService().getOwnFingerprint()); break; } } diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index d98e9164..c21be899 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -29,7 +29,6 @@ import android.widget.QuickContactBadge; import android.widget.TextView; import org.openintents.openpgp.util.OpenPgpUtils; -import org.whispersystems.libaxolotl.IdentityKey; import java.util.List; @@ -392,10 +391,9 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } }); } - for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys( - contact.getAccount(), contact.getJid().toBareJid().toString())) { - boolean highlight = identityKey.getFingerprint().replaceAll("\\s", "").equals(messageFingerprint); - hasKeys |= addFingerprintRow(keys, contact.getAccount(), identityKey, highlight); + for (final String fingerprint : contact.getAccount().getAxolotlService().getFingerprintsForContact(contact)) { + boolean highlight = fingerprint.equals(messageFingerprint); + hasKeys |= addFingerprintRow(keys, contact.getAccount(), fingerprint, highlight); } if (contact.getPgpKeyId() != 0) { hasKeys = true; diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 02b1d873..7b5dc9ab 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -25,8 +25,6 @@ import android.widget.TableLayout; import android.widget.TextView; import android.widget.Toast; -import org.whispersystems.libaxolotl.IdentityKey; - import java.util.Set; import eu.siacs.conversations.Config; @@ -572,7 +570,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } else { this.mOtrFingerprintBox.setVisibility(View.GONE); } - final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnPublicKey().getFingerprint(); + final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnFingerprint(); if (axolotlFingerprint != null) { this.mAxolotlFingerprintBox.setVisibility(View.VISIBLE); this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(axolotlFingerprint)); @@ -607,16 +605,15 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } else { this.mAxolotlFingerprintBox.setVisibility(View.GONE); } - final IdentityKey ownKey = mAccount.getAxolotlService().getOwnPublicKey(); + final String ownFingerprint = mAccount.getAxolotlService().getOwnFingerprint(); boolean hasKeys = false; keys.removeAllViews(); - for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys( - mAccount, mAccount.getJid().toBareJid().toString())) { - if(ownKey.equals(identityKey)) { + for (final String fingerprint : mAccount.getAxolotlService().getFingerprintsForOwnSessions()) { + if(ownFingerprint.equals(fingerprint)) { continue; } - boolean highlight = identityKey.getFingerprint().replaceAll("\\s", "").equals(messageFingerprint); - hasKeys |= addFingerprintRow(keys, mAccount, identityKey, highlight); + boolean highlight = fingerprint.equals(messageFingerprint); + hasKeys |= addFingerprintRow(keys, mAccount, fingerprint, highlight); } if (hasKeys) { keysCard.setVisibility(View.VISIBLE); diff --git a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java index 0e685c3e..ab313074 100644 --- a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java @@ -43,8 +43,8 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate private Button mSaveButton; private Button mCancelButton; - private final Map ownKeysToTrust = new HashMap<>(); - private final Map foreignKeysToTrust = new HashMap<>(); + private final Map ownKeysToTrust = new HashMap<>(); + private final Map foreignKeysToTrust = new HashMap<>(); private final OnClickListener mSaveButtonListener = new OnClickListener() { @Override @@ -120,28 +120,28 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate foreignKeys.removeAllViews(); boolean hasOwnKeys = false; boolean hasForeignKeys = false; - for(final IdentityKey identityKey : ownKeysToTrust.keySet()) { + for(final String fingerprint : ownKeysToTrust.keySet()) { hasOwnKeys = true; - addFingerprintRowWithListeners(ownKeys, contact.getAccount(), identityKey, false, - XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(identityKey)), false, + addFingerprintRowWithListeners(ownKeys, contact.getAccount(), fingerprint, false, + XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint)), false, new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - ownKeysToTrust.put(identityKey, isChecked); + ownKeysToTrust.put(fingerprint, isChecked); // own fingerprints have no impact on locked status. } }, null ); } - for(final IdentityKey identityKey : foreignKeysToTrust.keySet()) { + for(final String fingerprint : foreignKeysToTrust.keySet()) { hasForeignKeys = true; - addFingerprintRowWithListeners(foreignKeys, contact.getAccount(), identityKey, false, - XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(identityKey)), false, + addFingerprintRowWithListeners(foreignKeys, contact.getAccount(), fingerprint, false, + XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(fingerprint)), false, new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - foreignKeysToTrust.put(identityKey, isChecked); + foreignKeysToTrust.put(fingerprint, isChecked); lockOrUnlockAsNeeded(); } }, @@ -181,12 +181,12 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate } for(final IdentityKey identityKey : ownKeysSet) { if(!ownKeysToTrust.containsKey(identityKey)) { - ownKeysToTrust.put(identityKey, false); + ownKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); } } for(final IdentityKey identityKey : foreignKeysSet) { if(!foreignKeysToTrust.containsKey(identityKey)) { - foreignKeysToTrust.put(identityKey, false); + foreignKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); } } } @@ -225,15 +225,15 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate } private void commitTrusts() { - for(IdentityKey identityKey:ownKeysToTrust.keySet()) { + for(final String fingerprint :ownKeysToTrust.keySet()) { contact.getAccount().getAxolotlService().setFingerprintTrust( - identityKey.getFingerprint().replaceAll("\\s", ""), - XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(identityKey))); + fingerprint, + XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint))); } - for(IdentityKey identityKey:foreignKeysToTrust.keySet()) { + for(final String fingerprint:foreignKeysToTrust.keySet()) { contact.getAccount().getAxolotlService().setFingerprintTrust( - identityKey.getFingerprint().replaceAll("\\s", ""), - XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(identityKey))); + fingerprint, + XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(fingerprint))); } } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index aa5812b6..967efec9 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -59,8 +59,6 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import net.java.otr4j.session.SessionID; -import org.whispersystems.libaxolotl.IdentityKey; - import java.io.FileNotFoundException; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -613,11 +611,10 @@ public abstract class XmppActivity extends Activity { builder.create().show(); } - protected boolean addFingerprintRow(LinearLayout keys, final Account account, IdentityKey identityKey, boolean highlight) { - final String fingerprint = identityKey.getFingerprint().replaceAll("\\s", ""); + protected boolean addFingerprintRow(LinearLayout keys, final Account account, final String fingerprint, boolean highlight) { final XmppAxolotlSession.Trust trust = account.getAxolotlService() .getFingerprintTrust(fingerprint); - return addFingerprintRowWithListeners(keys, account, identityKey, highlight, trust, true, + return addFingerprintRowWithListeners(keys, account, fingerprint, highlight, trust, true, new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -639,7 +636,7 @@ public abstract class XmppActivity extends Activity { } protected boolean addFingerprintRowWithListeners(LinearLayout keys, final Account account, - final IdentityKey identityKey, + final String fingerprint, boolean highlight, XmppAxolotlSession.Trust trust, boolean showTag, @@ -659,7 +656,7 @@ public abstract class XmppActivity extends Activity { view.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - showPurgeKeyDialog(account, identityKey); + showPurgeKeyDialog(account, fingerprint); return true; } }); @@ -707,24 +704,24 @@ public abstract class XmppActivity extends Activity { keyType.setText(getString(R.string.omemo_fingerprint)); } - key.setText(CryptoHelper.prettifyFingerprint(identityKey.getFingerprint())); + key.setText(CryptoHelper.prettifyFingerprint(fingerprint)); keys.addView(view); return true; } - public void showPurgeKeyDialog(final Account account, final IdentityKey identityKey) { + public void showPurgeKeyDialog(final Account account, final String fingerprint) { Builder builder = new Builder(this); builder.setTitle(getString(R.string.purge_key)); builder.setIconAttribute(android.R.attr.alertDialogIcon); builder.setMessage(getString(R.string.purge_key_desc_part1) - + "\n\n" + CryptoHelper.prettifyFingerprint(identityKey.getFingerprint()) + + "\n\n" + CryptoHelper.prettifyFingerprint(fingerprint) + "\n\n" + getString(R.string.purge_key_desc_part2)); builder.setNegativeButton(getString(R.string.cancel), null); builder.setPositiveButton(getString(R.string.accept), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - account.getAxolotlService().purgeKey(identityKey); + account.getAxolotlService().purgeKey(fingerprint); refreshUi(); } });