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
This commit is contained in:
Andreas Straub 2015-09-06 15:08:42 +02:00
parent 2bb033267b
commit a95c451f1e
7 changed files with 58 additions and 50 deletions

View File

@ -190,8 +190,8 @@ public class AxolotlService {
this.executor = new SerialSingleThreadExecutor(); this.executor = new SerialSingleThreadExecutor();
} }
public IdentityKey getOwnPublicKey() { public String getOwnFingerprint() {
return axolotlStore.getIdentityKeyPair().getPublicKey(); return axolotlStore.getIdentityKeyPair().getPublicKey().getFingerprint().replaceAll("\\s", "");
} }
public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust) { public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust) {
@ -222,6 +222,22 @@ public class AxolotlService {
return sessions; return sessions;
} }
public Set<String> getFingerprintsForOwnSessions() {
Set<String> fingerprints = new HashSet<>();
for (XmppAxolotlSession session : findOwnSessions()) {
fingerprints.add(session.getFingerprint());
}
return fingerprints;
}
public Set<String> getFingerprintsForContact(final Contact contact) {
Set<String> fingerprints = new HashSet<>();
for (XmppAxolotlSession session : findSessionsforContact(contact)) {
fingerprints.add(session.getFingerprint());
}
return fingerprints;
}
private boolean hasAny(Contact contact) { private boolean hasAny(Contact contact) {
AxolotlAddress contactAddress = getAddressForJid(contact.getJid()); AxolotlAddress contactAddress = getAddressForJid(contact.getJid());
return sessions.hasAny(contactAddress); return sessions.hasAny(contactAddress);
@ -310,8 +326,8 @@ public class AxolotlService {
}); });
} }
public void purgeKey(IdentityKey identityKey) { public void purgeKey(final String fingerprint) {
axolotlStore.setFingerprintTrust(identityKey.getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED); axolotlStore.setFingerprintTrust(fingerprint.replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED);
} }
public void publishOwnDeviceIdIfNeeded() { public void publishOwnDeviceIdIfNeeded() {

View File

@ -91,7 +91,7 @@ public class XmppAxolotlSession {
public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, String fingerprint) { public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, String fingerprint) {
this(account, store, remoteAddress); this(account, store, remoteAddress);
this.fingerprint = fingerprint; this.fingerprint = fingerprint.replaceAll("\\s","");
} }
public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress) { public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress) {

View File

@ -754,7 +754,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
break; break;
case Message.ENCRYPTION_AXOLOTL: case Message.ENCRYPTION_AXOLOTL:
message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); message.setAxolotlFingerprint(account.getAxolotlService().getOwnFingerprint());
if (message.needsUploading()) { if (message.needsUploading()) {
if (account.httpUploadAvailable() || message.fixCounterpart()) { if (account.httpUploadAvailable() || message.fixCounterpart()) {
this.sendFileMessage(message,delay); this.sendFileMessage(message,delay);
@ -799,7 +799,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
break; break;
case Message.ENCRYPTION_AXOLOTL: case Message.ENCRYPTION_AXOLOTL:
message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); message.setAxolotlFingerprint(account.getAxolotlService().getOwnFingerprint());
break; break;
} }
} }

View File

@ -29,7 +29,6 @@ import android.widget.QuickContactBadge;
import android.widget.TextView; import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpUtils; import org.openintents.openpgp.util.OpenPgpUtils;
import org.whispersystems.libaxolotl.IdentityKey;
import java.util.List; import java.util.List;
@ -392,10 +391,9 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
} }
}); });
} }
for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys( for (final String fingerprint : contact.getAccount().getAxolotlService().getFingerprintsForContact(contact)) {
contact.getAccount(), contact.getJid().toBareJid().toString())) { boolean highlight = fingerprint.equals(messageFingerprint);
boolean highlight = identityKey.getFingerprint().replaceAll("\\s", "").equals(messageFingerprint); hasKeys |= addFingerprintRow(keys, contact.getAccount(), fingerprint, highlight);
hasKeys |= addFingerprintRow(keys, contact.getAccount(), identityKey, highlight);
} }
if (contact.getPgpKeyId() != 0) { if (contact.getPgpKeyId() != 0) {
hasKeys = true; hasKeys = true;

View File

@ -25,8 +25,6 @@ import android.widget.TableLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.whispersystems.libaxolotl.IdentityKey;
import java.util.Set; import java.util.Set;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
@ -572,7 +570,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} else { } else {
this.mOtrFingerprintBox.setVisibility(View.GONE); this.mOtrFingerprintBox.setVisibility(View.GONE);
} }
final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnPublicKey().getFingerprint(); final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnFingerprint();
if (axolotlFingerprint != null) { if (axolotlFingerprint != null) {
this.mAxolotlFingerprintBox.setVisibility(View.VISIBLE); this.mAxolotlFingerprintBox.setVisibility(View.VISIBLE);
this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(axolotlFingerprint)); this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(axolotlFingerprint));
@ -607,16 +605,15 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} else { } else {
this.mAxolotlFingerprintBox.setVisibility(View.GONE); this.mAxolotlFingerprintBox.setVisibility(View.GONE);
} }
final IdentityKey ownKey = mAccount.getAxolotlService().getOwnPublicKey(); final String ownFingerprint = mAccount.getAxolotlService().getOwnFingerprint();
boolean hasKeys = false; boolean hasKeys = false;
keys.removeAllViews(); keys.removeAllViews();
for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys( for (final String fingerprint : mAccount.getAxolotlService().getFingerprintsForOwnSessions()) {
mAccount, mAccount.getJid().toBareJid().toString())) { if(ownFingerprint.equals(fingerprint)) {
if(ownKey.equals(identityKey)) {
continue; continue;
} }
boolean highlight = identityKey.getFingerprint().replaceAll("\\s", "").equals(messageFingerprint); boolean highlight = fingerprint.equals(messageFingerprint);
hasKeys |= addFingerprintRow(keys, mAccount, identityKey, highlight); hasKeys |= addFingerprintRow(keys, mAccount, fingerprint, highlight);
} }
if (hasKeys) { if (hasKeys) {
keysCard.setVisibility(View.VISIBLE); keysCard.setVisibility(View.VISIBLE);

View File

@ -43,8 +43,8 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
private Button mSaveButton; private Button mSaveButton;
private Button mCancelButton; private Button mCancelButton;
private final Map<IdentityKey, Boolean> ownKeysToTrust = new HashMap<>(); private final Map<String, Boolean> ownKeysToTrust = new HashMap<>();
private final Map<IdentityKey, Boolean> foreignKeysToTrust = new HashMap<>(); private final Map<String, Boolean> foreignKeysToTrust = new HashMap<>();
private final OnClickListener mSaveButtonListener = new OnClickListener() { private final OnClickListener mSaveButtonListener = new OnClickListener() {
@Override @Override
@ -120,28 +120,28 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
foreignKeys.removeAllViews(); foreignKeys.removeAllViews();
boolean hasOwnKeys = false; boolean hasOwnKeys = false;
boolean hasForeignKeys = false; boolean hasForeignKeys = false;
for(final IdentityKey identityKey : ownKeysToTrust.keySet()) { for(final String fingerprint : ownKeysToTrust.keySet()) {
hasOwnKeys = true; hasOwnKeys = true;
addFingerprintRowWithListeners(ownKeys, contact.getAccount(), identityKey, false, addFingerprintRowWithListeners(ownKeys, contact.getAccount(), fingerprint, false,
XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(identityKey)), false, XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint)), false,
new CompoundButton.OnCheckedChangeListener() { new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ownKeysToTrust.put(identityKey, isChecked); ownKeysToTrust.put(fingerprint, isChecked);
// own fingerprints have no impact on locked status. // own fingerprints have no impact on locked status.
} }
}, },
null null
); );
} }
for(final IdentityKey identityKey : foreignKeysToTrust.keySet()) { for(final String fingerprint : foreignKeysToTrust.keySet()) {
hasForeignKeys = true; hasForeignKeys = true;
addFingerprintRowWithListeners(foreignKeys, contact.getAccount(), identityKey, false, addFingerprintRowWithListeners(foreignKeys, contact.getAccount(), fingerprint, false,
XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(identityKey)), false, XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(fingerprint)), false,
new CompoundButton.OnCheckedChangeListener() { new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
foreignKeysToTrust.put(identityKey, isChecked); foreignKeysToTrust.put(fingerprint, isChecked);
lockOrUnlockAsNeeded(); lockOrUnlockAsNeeded();
} }
}, },
@ -181,12 +181,12 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
} }
for(final IdentityKey identityKey : ownKeysSet) { for(final IdentityKey identityKey : ownKeysSet) {
if(!ownKeysToTrust.containsKey(identityKey)) { if(!ownKeysToTrust.containsKey(identityKey)) {
ownKeysToTrust.put(identityKey, false); ownKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false);
} }
} }
for(final IdentityKey identityKey : foreignKeysSet) { for(final IdentityKey identityKey : foreignKeysSet) {
if(!foreignKeysToTrust.containsKey(identityKey)) { 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() { private void commitTrusts() {
for(IdentityKey identityKey:ownKeysToTrust.keySet()) { for(final String fingerprint :ownKeysToTrust.keySet()) {
contact.getAccount().getAxolotlService().setFingerprintTrust( contact.getAccount().getAxolotlService().setFingerprintTrust(
identityKey.getFingerprint().replaceAll("\\s", ""), fingerprint,
XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(identityKey))); XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint)));
} }
for(IdentityKey identityKey:foreignKeysToTrust.keySet()) { for(final String fingerprint:foreignKeysToTrust.keySet()) {
contact.getAccount().getAxolotlService().setFingerprintTrust( contact.getAccount().getAxolotlService().setFingerprintTrust(
identityKey.getFingerprint().replaceAll("\\s", ""), fingerprint,
XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(identityKey))); XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(fingerprint)));
} }
} }

View File

@ -59,8 +59,6 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import net.java.otr4j.session.SessionID; import net.java.otr4j.session.SessionID;
import org.whispersystems.libaxolotl.IdentityKey;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
@ -613,11 +611,10 @@ public abstract class XmppActivity extends Activity {
builder.create().show(); builder.create().show();
} }
protected boolean addFingerprintRow(LinearLayout keys, final Account account, IdentityKey identityKey, boolean highlight) { protected boolean addFingerprintRow(LinearLayout keys, final Account account, final String fingerprint, boolean highlight) {
final String fingerprint = identityKey.getFingerprint().replaceAll("\\s", "");
final XmppAxolotlSession.Trust trust = account.getAxolotlService() final XmppAxolotlSession.Trust trust = account.getAxolotlService()
.getFingerprintTrust(fingerprint); .getFingerprintTrust(fingerprint);
return addFingerprintRowWithListeners(keys, account, identityKey, highlight, trust, true, return addFingerprintRowWithListeners(keys, account, fingerprint, highlight, trust, true,
new CompoundButton.OnCheckedChangeListener() { new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 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, protected boolean addFingerprintRowWithListeners(LinearLayout keys, final Account account,
final IdentityKey identityKey, final String fingerprint,
boolean highlight, boolean highlight,
XmppAxolotlSession.Trust trust, XmppAxolotlSession.Trust trust,
boolean showTag, boolean showTag,
@ -659,7 +656,7 @@ public abstract class XmppActivity extends Activity {
view.setOnLongClickListener(new View.OnLongClickListener() { view.setOnLongClickListener(new View.OnLongClickListener() {
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
showPurgeKeyDialog(account, identityKey); showPurgeKeyDialog(account, fingerprint);
return true; return true;
} }
}); });
@ -707,24 +704,24 @@ public abstract class XmppActivity extends Activity {
keyType.setText(getString(R.string.omemo_fingerprint)); keyType.setText(getString(R.string.omemo_fingerprint));
} }
key.setText(CryptoHelper.prettifyFingerprint(identityKey.getFingerprint())); key.setText(CryptoHelper.prettifyFingerprint(fingerprint));
keys.addView(view); keys.addView(view);
return true; 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 builder = new Builder(this);
builder.setTitle(getString(R.string.purge_key)); builder.setTitle(getString(R.string.purge_key));
builder.setIconAttribute(android.R.attr.alertDialogIcon); builder.setIconAttribute(android.R.attr.alertDialogIcon);
builder.setMessage(getString(R.string.purge_key_desc_part1) 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)); + "\n\n" + getString(R.string.purge_key_desc_part2));
builder.setNegativeButton(getString(R.string.cancel), null); builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.accept), builder.setPositiveButton(getString(R.string.accept),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
account.getAxolotlService().purgeKey(identityKey); account.getAxolotlService().purgeKey(fingerprint);
refreshUi(); refreshUi();
} }
}); });