improved error reporting in trust keys activity

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java  | 26 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  4 
src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java      |  3 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java         |  2 
src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java           | 30 
src/main/java/eu/siacs/conversations/xmpp/OnKeyStatusUpdated.java        |  4 
src/main/res/values/strings.xml                                          |  2 
7 files changed, 49 insertions(+), 22 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java 🔗

@@ -175,9 +175,10 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		}
 	}
 
-	private enum FetchStatus {
+	public enum FetchStatus {
 		PENDING,
 		SUCCESS,
+		SUCCESS_VERIFIED,
 		ERROR
 	}
 
@@ -321,7 +322,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNTRUSTED,
 				XmppAxolotlSession.Trust.UNTRUSTED);
 		this.deviceIds.put(jid, deviceIds);
-		mXmppConnectionService.keyStatusUpdated();
+		mXmppConnectionService.keyStatusUpdated(null);
 	}
 
 	public void wipeOtherPepDevices() {
@@ -588,8 +589,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 							if (verifier.verify(verification.second)) {
 								try {
 									mXmppConnectionService.getMemorizingTrustManager().getNonInteractive().checkClientTrusted(verification.first, "RSA");
-									Log.d(Config.LOGTAG, "verified session with x.509 signature");
+									Log.d(Config.LOGTAG, "verified session with x.509 signature. fingerprint was: "+session.getFingerprint());
 									setFingerprintTrust(session.getFingerprint(), XmppAxolotlSession.Trust.TRUSTED);
+									fetchStatusMap.put(address, FetchStatus.SUCCESS_VERIFIED);
+									finishBuildingSessionsFromPEP(address);
+									return;
 								} catch (Exception e) {
 									Log.d(Config.LOGTAG,"could not verify certificate");
 								}
@@ -597,13 +601,13 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 						} catch (Exception e) {
 							Log.d(Config.LOGTAG, "error during verification " + e.getMessage());
 						}
-					} else {
-						Log.d(Config.LOGTAG, " unable to parse verification");
 					}
+					fetchStatusMap.put(address, FetchStatus.SUCCESS);
 					finishBuildingSessionsFromPEP(address);
 				}
 			});
 		} catch (InvalidJidException e) {
+			fetchStatusMap.put(address, FetchStatus.SUCCESS);
 			finishBuildingSessionsFromPEP(address);
 		}
 	}
@@ -612,7 +616,15 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), 0);
 		if (!fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING)
 				&& !fetchStatusMap.getAll(address).containsValue(FetchStatus.PENDING)) {
-			mXmppConnectionService.keyStatusUpdated();
+			FetchStatus report = null;
+			if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.SUCCESS_VERIFIED)
+					| fetchStatusMap.getAll(address).containsValue(FetchStatus.SUCCESS_VERIFIED)) {
+				report = FetchStatus.SUCCESS_VERIFIED;
+			} else if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.ERROR)
+					|| fetchStatusMap.getAll(address).containsValue(FetchStatus.ERROR)) {
+				report = FetchStatus.ERROR;
+			}
+			mXmppConnectionService.keyStatusUpdated(report);
 		}
 	}
 
@@ -660,10 +672,10 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 							builder.process(preKeyBundle);
 							XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey().getFingerprint().replaceAll("\\s", ""));
 							sessions.put(address, session);
-							fetchStatusMap.put(address, FetchStatus.SUCCESS);
 							if (Config.X509_VERIFICATION) {
 								verifySessionWithPEP(session, bundle.getIdentityKey());
 							} else {
+								fetchStatusMap.put(address, FetchStatus.SUCCESS);
 								finishBuildingSessionsFromPEP(address);
 							}
 						} catch (UntrustedIdentityException | InvalidKeyException e) {

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -2558,9 +2558,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		}
 	}
 
-	public void keyStatusUpdated() {
+	public void keyStatusUpdated(AxolotlService.FetchStatus report) {
 		if (mOnKeyStatusUpdated != null) {
-			mOnKeyStatusUpdated.onKeyStatusUpdated();
+			mOnKeyStatusUpdated.onKeyStatusUpdated(report);
 		}
 	}
 

src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java 🔗

@@ -35,6 +35,7 @@ import java.util.List;
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.crypto.PgpEngine;
+import eu.siacs.conversations.crypto.axolotl.AxolotlService;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.ListItem;
@@ -479,7 +480,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
 	}
 
 	@Override
-	public void onKeyStatusUpdated() {
+	public void onKeyStatusUpdated(AxolotlService.FetchStatus report) {
 		refreshUi();
 	}
 }

src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java 🔗

@@ -21,7 +21,6 @@ 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.entities.Conversation;
 import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
 import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 import eu.siacs.conversations.xmpp.jid.Jid;
@@ -30,8 +29,6 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
 	private Jid accountJid;
 	private Jid contactJid;
 
-	private boolean hasNoTrustedKeys = true;
-
 	private Contact contact;
 	private Account mAccount;
 	private TextView keyErrorMessage;
@@ -91,7 +88,6 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
 			this.contactJid = Jid.fromString(getIntent().getExtras().getString("contact"));
 		} catch (final InvalidJidException ignored) {
 		}
-		hasNoTrustedKeys = getIntent().getBooleanExtra("has_no_trusted", false);
 
 		keyErrorMessageCard = (LinearLayout) findViewById(R.id.key_error_message_card);
 		keyErrorMessage = (TextView) findViewById(R.id.key_error_message);
@@ -172,11 +168,12 @@ 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 (hasNoTrustedKeys) {
-			ownKeysSet.addAll(service.getKeysWithTrust(XmppAxolotlSession.Trust.UNTRUSTED));
+		if (hasNoOtherTrustedKeys() && ownKeysSet.size() == 0) {
 			foreignKeysSet.addAll(service.getKeysWithTrust(XmppAxolotlSession.Trust.UNTRUSTED, contact));
 		}
 		for(final IdentityKey identityKey : ownKeysSet) {
@@ -200,8 +197,6 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
 				return;
 			}
 			this.contact = this.mAccount.getRoster().getContact(contactJid);
-			ownKeysToTrust.clear();
-			foreignKeysToTrust.clear();
 			reloadFingerprints();
 			populateView();
 		}
@@ -217,7 +212,23 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
 
 
 	@Override
-	public void onKeyStatusUpdated() {
+	public void onKeyStatusUpdated(final AxolotlService.FetchStatus report) {
+		if (report != null) {
+			runOnUiThread(new Runnable() {
+				@Override
+				public void run() {
+					switch (report) {
+						case ERROR:
+							Toast.makeText(TrustKeysActivity.this,R.string.error_fetching_omemo_key,Toast.LENGTH_SHORT).show();
+							break;
+						case SUCCESS_VERIFIED:
+							Toast.makeText(TrustKeysActivity.this,R.string.verified_omemo_key_with_certificate,Toast.LENGTH_LONG).show();
+							break;
+					}
+				}
+			});
+
+		}
 		boolean keysToTrust = reloadFingerprints();
 		if (keysToTrust || hasPendingKeyFetches() || hasNoOtherTrustedKeys()) {
 			refreshUi();
@@ -225,7 +236,6 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
 			runOnUiThread(new Runnable() {
 				@Override
 				public void run() {
-					Toast.makeText(TrustKeysActivity.this, "Nothing to do", Toast.LENGTH_SHORT).show();
 					finishOk();
 				}
 			});

src/main/res/values/strings.xml 🔗

@@ -533,4 +533,6 @@
 	<string name="certificate_chain_is_not_trusted">Certificate chain is not trusted</string>
 	<string name="jid_does_not_match_certificate">Jabber ID does not match certificate</string>
 	<string name="action_renew_certificate">Renew certificate</string>
+	<string name="error_fetching_omemo_key">Error fetching OMEMO key!</string>
+	<string name="verified_omemo_key_with_certificate">Verified OMEMO key with certificate!</string>
 </resources>