allow fingerprint verification via context menu

This commit is contained in:
Daniel Gultsch 2016-11-28 15:11:44 +01:00
parent bbe01c9a6a
commit 84a2fa0041
7 changed files with 100 additions and 20 deletions

View File

@ -2,6 +2,7 @@ package eu.siacs.conversations;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.MenuItem; import android.view.MenuItem;
@ -12,14 +13,20 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; 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.security.cert.X509Certificate;
import java.util.Arrays;
import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.ui.TrustKeysActivity;
import eu.siacs.conversations.ui.XmppActivity; import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.ui.widget.Switch; import eu.siacs.conversations.ui.widget.Switch;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.XmppUri;
public abstract class OmemoActivity extends XmppActivity { public abstract class OmemoActivity extends XmppActivity {
@ -27,13 +34,32 @@ public abstract class OmemoActivity extends XmppActivity {
private Account mSelectedAccount; private Account mSelectedAccount;
private String mSelectedFingerprint; private String mSelectedFingerprint;
protected XmppUri mPendingFingerprintVerificationUri = null;
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu,v,menuInfo); super.onCreateContextMenu(menu,v,menuInfo);
Object account = v.getTag(R.id.TAG_ACCOUNT); Object account = v.getTag(R.id.TAG_ACCOUNT);
Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT); 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); 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.mSelectedAccount = (Account) account;
this.mSelectedFingerprint = (String) fingerprint; this.mSelectedFingerprint = (String) fingerprint;
} }
@ -48,10 +74,29 @@ public abstract class OmemoActivity extends XmppActivity {
case R.id.copy_omemo_key: case R.id.copy_omemo_key:
copyOmemoFingerprint(mSelectedFingerprint); copyOmemoFingerprint(mSelectedFingerprint);
break; break;
case R.id.verify_scan:
new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE"));
break;
} }
return true; 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) { protected void copyOmemoFingerprint(String fingerprint) {
if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) { if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) {
Toast.makeText( Toast.makeText(
@ -106,6 +151,7 @@ public abstract class OmemoActivity extends XmppActivity {
registerForContextMenu(view); registerForContextMenu(view);
view.setTag(R.id.TAG_ACCOUNT,account); view.setTag(R.id.TAG_ACCOUNT,account);
view.setTag(R.id.TAG_FINGERPRINT,fingerprint); 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; boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509;
final View.OnClickListener toast; final View.OnClickListener toast;
trustToggle.setChecked(status.isTrusted(), false); trustToggle.setChecked(status.isTrusted(), false);

View File

@ -49,6 +49,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.XmppConnection;
@ -528,13 +529,16 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} }
public void onBackendConnected() { public void onBackendConnected() {
if ((accountJid != null) && (contactJid != null)) { if (accountJid != null && contactJid != null) {
Account account = xmppConnectionService Account account = xmppConnectionService.findAccountByJid(accountJid);
.findAccountByJid(accountJid);
if (account == null) { if (account == null) {
return; return;
} }
this.contact = account.getRoster().getContact(contactJid); this.contact = account.getRoster().getContact(contactJid);
if (mPendingFingerprintVerificationUri != null) {
processFingerprintVerification(mPendingFingerprintVerificationUri);
mPendingFingerprintVerificationUri = null;
}
populateView(); populateView();
} }
} }
@ -543,4 +547,15 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
public void onKeyStatusUpdated(AxolotlService.FetchStatus report) { public void onKeyStatusUpdated(AxolotlService.FetchStatus report) {
refreshUi(); 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();
}
}
} }

View File

@ -53,6 +53,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.XmppConnection;
@ -376,13 +377,24 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
} }
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_BATTERY_OP || requestCode == REQUEST_DATA_SAVER) { if (requestCode == REQUEST_BATTERY_OP || requestCode == REQUEST_DATA_SAVER) {
updateAccountInformation(mAccount == null); 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() { protected void updateSaveButton() {
boolean accountInfoEdited = accountInfoEdited(); boolean accountInfoEdited = accountInfoEdited();
@ -664,6 +676,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mPassword.requestFocus(); this.mPassword.requestFocus();
} }
} }
if (mPendingFingerprintVerificationUri != null) {
processFingerprintVerification(mPendingFingerprintVerificationUri);
mPendingFingerprintVerificationUri = null;
}
updateAccountInformation(init); updateAccountInformation(init);
} }

View File

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

View File

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

View File

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

View File

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