diff options
author | Daniel Gultsch <daniel@gultsch.de> | 2016-02-29 13:18:07 +0100 |
---|---|---|
committer | Daniel Gultsch <daniel@gultsch.de> | 2016-02-29 13:18:07 +0100 |
commit | 9e0466d1e643c07d1c3de088ddf2e5655899a50c (patch) | |
tree | 8b77dc7bce5f8aeadac51124a3275465ca6f3c9e /src/main/java/eu/siacs/conversations/ui | |
parent | 199ae3a4d8253fb00cdef5556763a46a319a2d46 (diff) |
refactored omemo to take multiple recipients
Diffstat (limited to '')
-rw-r--r-- | src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 21 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java | 156 |
2 files changed, 100 insertions, 77 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 55a12710..e4ffb3e4 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -408,7 +408,7 @@ public class ConversationActivity extends XmppActivity menuContactDetails.setVisible(false); menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable() && getSelectedConversation().getMucOptions().participating()); menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite()); - menuSecure.setVisible(Config.supportOpenPgp() && Config.multipleEncryptionChoices()); //only if pgp is supported we have a choice + menuSecure.setVisible((Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices()); //only if pgp is supported we have a choice } else { menuMucDetails.setVisible(false); menuSecure.setVisible(Config.multipleEncryptionChoices()); @@ -856,8 +856,8 @@ public class ConversationActivity extends XmppActivity axolotl.setVisible(Config.supportOmemo()); if (conversation.getMode() == Conversation.MODE_MULTI) { otr.setVisible(false); - axolotl.setVisible(false); - } else if (!conversation.getAccount().getAxolotlService().isContactAxolotlCapable(conversation.getContact())) { + } + if (!conversation.getAccount().getAxolotlService().isConversationAxolotlCapable(conversation)) { axolotl.setEnabled(false); } switch (conversation.getNextEncryption()) { @@ -1530,18 +1530,21 @@ public class ConversationActivity extends XmppActivity protected boolean trustKeysIfNeeded(int requestCode, int attachmentChoice) { AxolotlService axolotlService = mSelectedConversation.getAccount().getAxolotlService(); - Contact contact = mSelectedConversation.getContact(); + final List<Jid> targets = axolotlService.getCryptoTargets(mSelectedConversation); boolean hasUndecidedOwn = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED).isEmpty(); - boolean hasUndecidedContact = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED,contact).isEmpty(); + boolean hasUndecidedContacts = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED, targets).isEmpty(); boolean hasPendingKeys = !axolotlService.findDevicesWithoutSession(mSelectedConversation).isEmpty(); - boolean hasNoTrustedKeys = axolotlService.getNumTrustedKeys(mSelectedConversation.getContact()) == 0; - if(hasUndecidedOwn || hasUndecidedContact || hasPendingKeys || hasNoTrustedKeys) { + boolean hasNoTrustedKeys = axolotlService.anyTargetHasNoTrustedKeys(targets); + if(hasUndecidedOwn || hasUndecidedContacts || hasPendingKeys || hasNoTrustedKeys) { axolotlService.createSessionsIfNeeded(mSelectedConversation); Intent intent = new Intent(getApplicationContext(), TrustKeysActivity.class); - intent.putExtra("contact", mSelectedConversation.getContact().getJid().toBareJid().toString()); + String[] contacts = new String[targets.size()]; + for(int i = 0; i < contacts.length; ++i) { + contacts[i] = targets.get(i).toString(); + } + intent.putExtra("contacts", contacts); intent.putExtra(EXTRA_ACCOUNT, mSelectedConversation.getAccount().getJid().toBareJid().toString()); intent.putExtra("choice", attachmentChoice); - intent.putExtra("has_no_trusted", hasNoTrustedKeys); startActivityForResult(intent, requestCode); return true; } else { diff --git a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java index eec30798..8919ac79 100644 --- a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java @@ -12,7 +12,9 @@ import android.widget.Toast; import org.whispersystems.libaxolotl.IdentityKey; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -20,32 +22,28 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdated { private Jid accountJid; - private Jid contactJid; + private List<Jid> contactJids; - private Contact contact; private Account mAccount; private TextView keyErrorMessage; private LinearLayout keyErrorMessageCard; private TextView ownKeysTitle; private LinearLayout ownKeys; private LinearLayout ownKeysCard; - private TextView foreignKeysTitle; private LinearLayout foreignKeys; - private LinearLayout foreignKeysCard; private Button mSaveButton; private Button mCancelButton; private AxolotlService.FetchStatus lastFetchReport = AxolotlService.FetchStatus.SUCCESS; private final Map<String, Boolean> ownKeysToTrust = new HashMap<>(); - private final Map<String, Boolean> foreignKeysToTrust = new HashMap<>(); + private final Map<Jid,Map<String, Boolean>> foreignKeysToTrust = new HashMap<>(); private final OnClickListener mSaveButtonListener = new OnClickListener() { @Override @@ -70,15 +68,6 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate } @Override - protected String getShareableUri() { - if (contact != null) { - return contact.getShareableUri(); - } else { - return ""; - } - } - - @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_trust_keys); @@ -86,9 +75,13 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate this.accountJid = Jid.fromString(getIntent().getExtras().getString(EXTRA_ACCOUNT)); } catch (final InvalidJidException ignored) { } - try { - this.contactJid = Jid.fromString(getIntent().getExtras().getString("contact")); - } catch (final InvalidJidException ignored) { + this.contactJids = new ArrayList<>(); + for(String jid : getIntent().getStringArrayExtra("contacts")) { + try { + this.contactJids.add(Jid.fromString(jid)); + } catch (InvalidJidException e) { + e.printStackTrace(); + } } keyErrorMessageCard = (LinearLayout) findViewById(R.id.key_error_message_card); @@ -96,9 +89,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate ownKeysTitle = (TextView) findViewById(R.id.own_keys_title); ownKeys = (LinearLayout) findViewById(R.id.own_keys_details); ownKeysCard = (LinearLayout) findViewById(R.id.own_keys_card); - foreignKeysTitle = (TextView) findViewById(R.id.foreign_keys_title); - foreignKeys = (LinearLayout) findViewById(R.id.foreign_keys_details); - foreignKeysCard = (LinearLayout) findViewById(R.id.foreign_keys_card); + foreignKeys = (LinearLayout) findViewById(R.id.foreign_keys); mCancelButton = (Button) findViewById(R.id.cancel_button); mCancelButton.setOnClickListener(mCancelButtonListener); mSaveButton = (Button) findViewById(R.id.save_button); @@ -119,7 +110,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate boolean hasForeignKeys = false; for(final String fingerprint : ownKeysToTrust.keySet()) { hasOwnKeys = true; - addFingerprintRowWithListeners(ownKeys, contact.getAccount(), fingerprint, false, + addFingerprintRowWithListeners(ownKeys, mAccount, fingerprint, false, XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint)), false, new CompoundButton.OnCheckedChangeListener() { @Override @@ -132,30 +123,36 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate null ); } - for(final String fingerprint : foreignKeysToTrust.keySet()) { - hasForeignKeys = true; - 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(fingerprint, isChecked); - lockOrUnlockAsNeeded(); - } - }, - null, - null - ); - } - if(hasOwnKeys) { - ownKeysTitle.setText(accountJid.toString()); - ownKeysCard.setVisibility(View.VISIBLE); - } - if(hasForeignKeys) { - foreignKeysTitle.setText(contactJid.toString()); - foreignKeysCard.setVisibility(View.VISIBLE); + synchronized (this.foreignKeysToTrust) { + for (Map.Entry<Jid, Map<String, Boolean>> entry : foreignKeysToTrust.entrySet()) { + final LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.keys_card, foreignKeys, false); + final TextView header = (TextView) layout.findViewById(R.id.foreign_keys_title); + final LinearLayout keysContainer = (LinearLayout) layout.findViewById(R.id.foreign_keys_details); + header.setText(entry.getKey().toString()); + final Map<String, Boolean> fingerprints = entry.getValue(); + for (final String fingerprint : fingerprints.keySet()) { + hasForeignKeys = true; + addFingerprintRowWithListeners(keysContainer, mAccount, fingerprint, false, + XmppAxolotlSession.Trust.fromBoolean(fingerprints.get(fingerprint)), false, + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + fingerprints.put(fingerprint, isChecked); + lockOrUnlockAsNeeded(); + } + }, + null, + null + ); + } + foreignKeys.addView(layout); + } } + + ownKeysTitle.setText(accountJid.toString()); + ownKeysCard.setVisibility(hasOwnKeys ? View.VISIBLE : View.GONE); + foreignKeys.setVisibility(hasForeignKeys ? View.VISIBLE : View.GONE); if(hasPendingKeyFetches()) { setFetching(); lock(); @@ -163,13 +160,15 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate if (!hasForeignKeys && hasNoOtherTrustedKeys()) { keyErrorMessageCard.setVisibility(View.VISIBLE); if (lastFetchReport == AxolotlService.FetchStatus.ERROR - || contact.getAccount().getAxolotlService().fetchMapHasErrors(contact)) { + || mAccount.getAxolotlService().fetchMapHasErrors(contactJids)) { keyErrorMessage.setText(R.string.error_no_keys_to_trust_server_error); } else { keyErrorMessage.setText(R.string.error_no_keys_to_trust); } - ownKeys.removeAllViews(); ownKeysCard.setVisibility(View.GONE); - foreignKeys.removeAllViews(); foreignKeysCard.setVisibility(View.GONE); + ownKeys.removeAllViews(); + ownKeysCard.setVisibility(View.GONE); + foreignKeys.removeAllViews(); + foreignKeys.setVisibility(View.GONE); } lockOrUnlockAsNeeded(); setDone(); @@ -178,45 +177,56 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate private boolean reloadFingerprints() { ownKeysToTrust.clear(); - foreignKeysToTrust.clear(); AxolotlService service = this.mAccount.getAxolotlService(); Set<IdentityKey> ownKeysSet = service.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED); - Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED, contact); - if (hasNoOtherTrustedKeys() && ownKeysSet.size() == 0) { - foreignKeysSet.addAll(service.getKeysWithTrust(XmppAxolotlSession.Trust.UNTRUSTED, contact)); - } for(final IdentityKey identityKey : ownKeysSet) { if(!ownKeysToTrust.containsKey(identityKey)) { ownKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); } } - for(final IdentityKey identityKey : foreignKeysSet) { - if(!foreignKeysToTrust.containsKey(identityKey)) { - foreignKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); + synchronized (this.foreignKeysToTrust) { + foreignKeysToTrust.clear(); + for (Jid jid : contactJids) { + Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED, jid); + if (hasNoOtherTrustedKeys(jid) && ownKeysSet.size() == 0) { + foreignKeysSet.addAll(service.getKeysWithTrust(XmppAxolotlSession.Trust.UNTRUSTED, jid)); + } + Map<String, Boolean> foreignFingerprints = new HashMap<>(); + for (final IdentityKey identityKey : foreignKeysSet) { + if (!foreignFingerprints.containsKey(identityKey)) { + foreignFingerprints.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); + } + } + if (foreignFingerprints.size() > 0) { + foreignKeysToTrust.put(jid, foreignFingerprints); + } } } - return ownKeysSet.size() + foreignKeysSet.size() > 0; + return ownKeysSet.size() + foreignKeysToTrust.size() > 0; } @Override public void onBackendConnected() { - if ((accountJid != null) && (contactJid != null)) { + if (accountJid != null) { this.mAccount = xmppConnectionService.findAccountByJid(accountJid); if (this.mAccount == null) { return; } - this.contact = this.mAccount.getRoster().getContact(contactJid); reloadFingerprints(); populateView(); } } private boolean hasNoOtherTrustedKeys() { + return mAccount == null || mAccount.getAxolotlService().anyTargetHasNoTrustedKeys(contactJids); + } + + private boolean hasNoOtherTrustedKeys(Jid contact) { return mAccount == null || mAccount.getAxolotlService().getNumTrustedKeys(contact) == 0; } private boolean hasPendingKeyFetches() { - return mAccount != null && contact != null && mAccount.getAxolotlService().hasPendingKeyFetches(mAccount,contact); + return mAccount != null && mAccount.getAxolotlService().hasPendingKeyFetches(mAccount, contactJids); } @@ -262,14 +272,18 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate private void commitTrusts() { for(final String fingerprint :ownKeysToTrust.keySet()) { - contact.getAccount().getAxolotlService().setFingerprintTrust( + mAccount.getAxolotlService().setFingerprintTrust( fingerprint, XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint))); } - for(final String fingerprint:foreignKeysToTrust.keySet()) { - contact.getAccount().getAxolotlService().setFingerprintTrust( - fingerprint, - XmppAxolotlSession.Trust.fromBoolean(foreignKeysToTrust.get(fingerprint))); + synchronized (this.foreignKeysToTrust) { + for (Map<String, Boolean> value : foreignKeysToTrust.values()) { + for (final String fingerprint : value.keySet()) { + mAccount.getAxolotlService().setFingerprintTrust( + fingerprint, + XmppAxolotlSession.Trust.fromBoolean(value.get(fingerprint))); + } + } } } @@ -284,11 +298,17 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate } private void lockOrUnlockAsNeeded() { - if (hasNoOtherTrustedKeys() && !foreignKeysToTrust.values().contains(true)){ - lock(); - } else { - unlock(); + synchronized (this.foreignKeysToTrust) { + for (Jid jid : contactJids) { + Map<String, Boolean> fingerprints = foreignKeysToTrust.get(jid); + if (hasNoOtherTrustedKeys(jid) && (fingerprints == null || !fingerprints.values().contains(true))) { + lock(); + return; + } + } } + unlock(); + } private void setDone() { |