allow fingerprint verification via context menu

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/OmemoActivity.java             | 48 
src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java | 21 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java    | 18 
src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java      | 27 
src/main/res/menu/omemo_key_context.xml                             |  4 
src/main/res/values/ids.xml                                         |  1 
src/main/res/values/strings.xml                                     |  1 
7 files changed, 100 insertions(+), 20 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/OmemoActivity.java πŸ”—

@@ -2,6 +2,7 @@ package eu.siacs.conversations;
 
 import android.app.AlertDialog;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.os.Bundle;
 import android.view.ContextMenu;
 import android.view.MenuItem;
@@ -12,14 +13,20 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
 import java.security.cert.X509Certificate;
+import java.util.Arrays;
 
 import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
 import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
 import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.ui.TrustKeysActivity;
 import eu.siacs.conversations.ui.XmppActivity;
 import eu.siacs.conversations.ui.widget.Switch;
 import eu.siacs.conversations.utils.CryptoHelper;
+import eu.siacs.conversations.utils.XmppUri;
 
 
 public abstract class OmemoActivity extends XmppActivity {
@@ -27,13 +34,32 @@ public abstract class OmemoActivity extends XmppActivity {
     private Account mSelectedAccount;
     private String mSelectedFingerprint;
 
+    protected XmppUri mPendingFingerprintVerificationUri = null;
+
     @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
         super.onCreateContextMenu(menu,v,menuInfo);
         Object account = v.getTag(R.id.TAG_ACCOUNT);
         Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT);
-        if (account != null && fingerprint != null && account instanceof Account && fingerprint instanceof String) {
+        Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS);;
+        if (account != null
+                && fingerprint != null
+                && account instanceof Account
+                && fingerprintStatus != null
+                && fingerprint instanceof String
+                && fingerprintStatus instanceof FingerprintStatus) {
             getMenuInflater().inflate(R.menu.omemo_key_context, menu);
+            MenuItem purgeItem = menu.findItem(R.id.purge_omemo_key);
+            MenuItem verifyScan = menu.findItem(R.id.verify_scan);
+            if (this instanceof TrustKeysActivity) {
+                purgeItem.setVisible(false);
+                verifyScan.setVisible(false);
+            } else {
+                FingerprintStatus status = (FingerprintStatus) fingerprintStatus;
+                if (!status.isActive() || status.isVerified()) {
+                    verifyScan.setVisible(false);
+                }
+            }
             this.mSelectedAccount = (Account) account;
             this.mSelectedFingerprint = (String) fingerprint;
         }
@@ -48,10 +74,29 @@ public abstract class OmemoActivity extends XmppActivity {
             case R.id.copy_omemo_key:
                 copyOmemoFingerprint(mSelectedFingerprint);
                 break;
+            case R.id.verify_scan:
+                new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE"));
+                break;
         }
         return true;
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+        if (scanResult != null && scanResult.getFormatName() != null) {
+            String data = scanResult.getContents();
+            XmppUri uri = new XmppUri(data);
+            if (xmppConnectionServiceBound) {
+                processFingerprintVerification(uri);
+            } else {
+                this.mPendingFingerprintVerificationUri =uri;
+            }
+        }
+    }
+
+    protected abstract void processFingerprintVerification(XmppUri uri);
+
     protected void copyOmemoFingerprint(String fingerprint) {
         if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) {
             Toast.makeText(
@@ -106,6 +151,7 @@ public abstract class OmemoActivity extends XmppActivity {
         registerForContextMenu(view);
         view.setTag(R.id.TAG_ACCOUNT,account);
         view.setTag(R.id.TAG_FINGERPRINT,fingerprint);
+        view.setTag(R.id.TAG_FINGERPRINT_STATUS,status);
         boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509;
         final View.OnClickListener toast;
         trustToggle.setChecked(status.isTrusted(), false);

src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java πŸ”—

@@ -49,6 +49,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
 import eu.siacs.conversations.utils.CryptoHelper;
 import eu.siacs.conversations.utils.UIHelper;
+import eu.siacs.conversations.utils.XmppUri;
 import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
 import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
 import eu.siacs.conversations.xmpp.XmppConnection;
@@ -528,13 +529,16 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
 	}
 
 	public void onBackendConnected() {
-		if ((accountJid != null) && (contactJid != null)) {
-			Account account = xmppConnectionService
-				.findAccountByJid(accountJid);
+		if (accountJid != null && contactJid != null) {
+			Account account = xmppConnectionService.findAccountByJid(accountJid);
 			if (account == null) {
 				return;
 			}
 			this.contact = account.getRoster().getContact(contactJid);
+			if (mPendingFingerprintVerificationUri != null) {
+				processFingerprintVerification(mPendingFingerprintVerificationUri);
+				mPendingFingerprintVerificationUri = null;
+			}
 			populateView();
 		}
 	}
@@ -543,4 +547,15 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
 	public void onKeyStatusUpdated(AxolotlService.FetchStatus report) {
 		refreshUi();
 	}
+
+	@Override
+	protected void processFingerprintVerification(XmppUri uri) {
+		if (contact != null && contact.getJid().toBareJid().equals(uri.getJid()) && uri.hasFingerprints()) {
+			if (xmppConnectionService.verifyFingerprints(contact,uri.getFingerprints())) {
+				Toast.makeText(this,R.string.verified_fingerprints,Toast.LENGTH_SHORT).show();
+			}
+		} else {
+			Toast.makeText(this,R.string.invalid_barcode,Toast.LENGTH_SHORT).show();
+		}
+	}
 }

src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java πŸ”—

@@ -53,6 +53,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
 import eu.siacs.conversations.utils.CryptoHelper;
 import eu.siacs.conversations.utils.UIHelper;
+import eu.siacs.conversations.utils.XmppUri;
 import eu.siacs.conversations.xml.Element;
 import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
 import eu.siacs.conversations.xmpp.XmppConnection;
@@ -376,13 +377,24 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 	}
 
 	@Override
-	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+	public void onActivityResult(int requestCode, int resultCode, Intent data) {
 		super.onActivityResult(requestCode, resultCode, data);
 		if (requestCode == REQUEST_BATTERY_OP || requestCode == REQUEST_DATA_SAVER) {
 			updateAccountInformation(mAccount == null);
 		}
 	}
 
+	@Override
+	protected void processFingerprintVerification(XmppUri uri) {
+		if (mAccount != null && mAccount.getJid().toBareJid().equals(uri.getJid()) && uri.hasFingerprints()) {
+			if (xmppConnectionService.verifyFingerprints(mAccount,uri.getFingerprints())) {
+				Toast.makeText(this,R.string.verified_fingerprints,Toast.LENGTH_SHORT).show();
+			}
+		} else {
+			Toast.makeText(this,R.string.invalid_barcode,Toast.LENGTH_SHORT).show();
+		}
+	}
+
 	protected void updateSaveButton() {
 		boolean accountInfoEdited = accountInfoEdited();
 
@@ -664,6 +676,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 					this.mPassword.requestFocus();
 				}
 			}
+			if (mPendingFingerprintVerificationUri != null) {
+				processFingerprintVerification(mPendingFingerprintVerificationUri);
+				mPendingFingerprintVerificationUri = null;
+			}
 			updateAccountInformation(init);
 		}
 

src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java πŸ”—

@@ -73,7 +73,6 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
 			finish();
 		}
 	};
-	private XmppUri mPendingFingerprintVerificationUri = null;
 	private Toast mUseCameraHintToast = null;
 
 	@Override
@@ -138,21 +137,15 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
 	}
 
 	@Override
-	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
-		IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
-		if (scanResult != null && scanResult.getFormatName() != null) {
-			String data = scanResult.getContents();
-			XmppUri uri = new XmppUri(data);
-			if (xmppConnectionServiceBound) {
-				processFingerprintVerification(uri);
-				populateView();
-			} else {
-				this.mPendingFingerprintVerificationUri =uri;
-			}
+	protected void onStop() {
+		super.onStop();
+		if (mUseCameraHintToast != null) {
+			mUseCameraHintToast.cancel();
 		}
 	}
 
-	private void processFingerprintVerification(XmppUri uri) {
+	@Override
+	protected void processFingerprintVerification(XmppUri uri) {
 		if (mConversation != null
 				&& mAccount != null
 				&& uri.hasFingerprints()
@@ -162,13 +155,16 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
 			if (performedVerification && !keys && !hasNoOtherTrustedKeys() && !hasPendingKeyFetches()) {
 				Toast.makeText(this,R.string.all_omemo_keys_have_been_verified, Toast.LENGTH_SHORT).show();
 				finishOk();
+				return;
 			} else if (performedVerification) {
 				Toast.makeText(this,R.string.verified_fingerprints,Toast.LENGTH_SHORT).show();
 			}
 		} else {
+			reloadFingerprints();
 			Log.d(Config.LOGTAG,"xmpp uri was: "+uri.getJid()+" has Fingerprints: "+Boolean.toString(uri.hasFingerprints()));
 			Toast.makeText(this,R.string.barcode_does_not_contain_fingerprints_for_this_conversation,Toast.LENGTH_SHORT).show();
 		}
+		populateView();
 	}
 
 	private void populateView() {
@@ -288,9 +284,10 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
 			if (this.mPendingFingerprintVerificationUri != null) {
 				processFingerprintVerification(this.mPendingFingerprintVerificationUri);
 				this.mPendingFingerprintVerificationUri = null;
+			} else {
+				reloadFingerprints();
+				populateView();
 			}
-			reloadFingerprints();
-			populateView();
 		}
 	}
 

src/main/res/menu/omemo_key_context.xml πŸ”—

@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/verify_scan"
+        android:title="@string/scan_qr_code"
+        />
     <item
         android:id="@+id/purge_omemo_key"
         android:title="@string/purge_key"/>

src/main/res/values/ids.xml πŸ”—

@@ -2,4 +2,5 @@
 <resources>
     <item type="id" name="TAG_ACCOUNT"/>
     <item type="id" name="TAG_FINGERPRINT"/>
+    <item type="id" name="TAG_FINGERPRINT_STATUS"/>
 </resources>

src/main/res/values/strings.xml πŸ”—

@@ -714,4 +714,5 @@
 	<string name="pref_blind_trust_before_verification_summary">Automatically trust all new devices of contacts that haven’t been verified before, and prompt for manual confirmation each time a verified contact adds a new device.</string>
 	<string name="blindly_trusted_omemo_keys">Blindly trusted OMEMO keys</string>
 	<string name="not_trusted">Untrusted</string>
+	<string name="invalid_barcode">Invalid 2D barcode</string>
 </resources>