explicitly mark verified omemo keys in UI

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java     |  6 
src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java | 28 
src/main/java/eu/siacs/conversations/entities/Message.java                  |  4 
src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java       |  5 
src/main/java/eu/siacs/conversations/ui/XmppActivity.java                   | 17 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java         |  2 
src/main/res/values/strings.xml                                             |  2 
7 files changed, 48 insertions(+), 16 deletions(-)

Detailed changes

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

@@ -311,6 +311,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		expiredDevices.removeAll(deviceIds);
 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.TRUSTED,
 				XmppAxolotlSession.Trust.INACTIVE_TRUSTED);
+		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.TRUSTED_X509,
+				XmppAxolotlSession.Trust.INACTIVE_TRUSTED_X509);
 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.UNDECIDED,
 				XmppAxolotlSession.Trust.INACTIVE_UNDECIDED);
 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.UNTRUSTED,
@@ -318,6 +320,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		Set<Integer> newDevices = new HashSet<>(deviceIds);
 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_TRUSTED,
 				XmppAxolotlSession.Trust.TRUSTED);
+		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_TRUSTED_X509,
+				XmppAxolotlSession.Trust.TRUSTED_X509);
 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNDECIDED,
 				XmppAxolotlSession.Trust.UNDECIDED);
 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNTRUSTED,
@@ -592,7 +596,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 								try {
 									mXmppConnectionService.getMemorizingTrustManager().getNonInteractive().checkClientTrusted(verification.first, "RSA");
 									Log.d(Config.LOGTAG, "verified session with x.509 signature. fingerprint was: "+session.getFingerprint());
-									setFingerprintTrust(session.getFingerprint(), XmppAxolotlSession.Trust.TRUSTED);
+									setFingerprintTrust(session.getFingerprint(), XmppAxolotlSession.Trust.TRUSTED_X509);
 									fetchStatusMap.put(address, FetchStatus.SUCCESS_VERIFIED);
 									finishBuildingSessionsFromPEP(address);
 									return;

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

@@ -40,7 +40,9 @@ public class XmppAxolotlSession {
 		COMPROMISED(3),
 		INACTIVE_TRUSTED(4),
 		INACTIVE_UNDECIDED(5),
-		INACTIVE_UNTRUSTED(6);
+		INACTIVE_UNTRUSTED(6),
+		TRUSTED_X509(7),
+		INACTIVE_TRUSTED_X509(8);
 
 		private static final Map<Integer, Trust> trustsByValue = new HashMap<>();
 
@@ -74,6 +76,10 @@ public class XmppAxolotlSession {
 					return "Inactive (Undecided)" + getCode();
 				case INACTIVE_UNTRUSTED:
 					return "Inactive (Untrusted)" + getCode();
+				case TRUSTED_X509:
+					return "Trusted (X509) " + getCode();
+				case INACTIVE_TRUSTED_X509:
+					return "Inactive (Trusted (X509)) " + getCode();
 				case UNTRUSTED:
 				default:
 					return "Untrusted " + getCode();
@@ -87,6 +93,14 @@ public class XmppAxolotlSession {
 		public static Trust fromCode(int code) {
 			return trustsByValue.get(code);
 		}
+
+		public boolean trusted() {
+			return this == TRUSTED_X509 || this == TRUSTED;
+		}
+
+		public boolean trustedInactive() {
+			return this == INACTIVE_TRUSTED_X509 || this == INACTIVE_TRUSTED;
+		}
 	}
 
 	public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, String fingerprint) {
@@ -144,6 +158,8 @@ public class XmppAxolotlSession {
 			case UNDECIDED:
 			case UNTRUSTED:
 			case TRUSTED:
+			case INACTIVE_TRUSTED_X509:
+			case TRUSTED_X509:
 				try {
 					try {
 						PreKeyWhisperMessage message = new PreKeyWhisperMessage(encryptedKey);
@@ -169,8 +185,12 @@ public class XmppAxolotlSession {
 					Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error decrypting axolotl header, " + e.getClass().getName() + ": " + e.getMessage());
 				}
 
-				if (plaintext != null && trust == Trust.INACTIVE_TRUSTED) {
-					setTrust(Trust.TRUSTED);
+				if (plaintext != null) {
+					if (trust == Trust.INACTIVE_TRUSTED) {
+						setTrust(Trust.TRUSTED);
+					} else if (trust == Trust.INACTIVE_TRUSTED_X509) {
+						setTrust(Trust.TRUSTED_X509);
+					}
 				}
 
 				break;
@@ -186,7 +206,7 @@ public class XmppAxolotlSession {
 	@Nullable
 	public byte[] processSending(@NonNull byte[] outgoingMessage) {
 		Trust trust = getTrust();
-		if (trust == Trust.TRUSTED) {
+		if (trust.trusted()) {
 			CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage);
 			return ciphertextMessage.serialize();
 		} else {

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -716,8 +716,8 @@ public class Message extends AbstractEntity {
 	}
 
 	public boolean isTrusted() {
-		return conversation.getAccount().getAxolotlService().getFingerprintTrust(axolotlFingerprint)
-				== XmppAxolotlSession.Trust.TRUSTED;
+		XmppAxolotlSession.Trust t = conversation.getAccount().getAxolotlService().getFingerprintTrust(axolotlFingerprint);
+		return t != null && t.trusted();
 	}
 
 	private  int getPreviousEncryption() {

src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java 🔗

@@ -962,12 +962,13 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 		String[] args = {
 				account.getUuid(),
 				name,
-				String.valueOf(XmppAxolotlSession.Trust.TRUSTED.getCode())
+				String.valueOf(XmppAxolotlSession.Trust.TRUSTED.getCode()),
+				String.valueOf(XmppAxolotlSession.Trust.TRUSTED_X509.getCode())
 		};
 		return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME,
 				SQLiteAxolotlStore.ACCOUNT + " = ?"
 				+ " AND " + SQLiteAxolotlStore.NAME + " = ?"
-				+ " AND " + SQLiteAxolotlStore.TRUSTED + " = ?",
+				+ " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR "+SQLiteAxolotlStore.TRUSTED+ " = ?)",
 				args
 		);
 	}

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

@@ -674,12 +674,16 @@ public abstract class XmppActivity extends Activity {
 				return true;
 			}
 		});
-
+		boolean x509 = trust == XmppAxolotlSession.Trust.TRUSTED_X509 || trust == XmppAxolotlSession.Trust.INACTIVE_TRUSTED_X509;
 		switch (trust) {
 			case UNTRUSTED:
 			case TRUSTED:
-				trustToggle.setChecked(trust == XmppAxolotlSession.Trust.TRUSTED, false);
-				trustToggle.setEnabled(true);
+			case TRUSTED_X509:
+				trustToggle.setChecked(trust.trusted(), false);
+				trustToggle.setEnabled(trust != XmppAxolotlSession.Trust.TRUSTED_X509);
+				if (trust == XmppAxolotlSession.Trust.TRUSTED_X509) {
+					trustToggle.setOnClickListener(null);
+				}
 				key.setTextColor(getPrimaryTextColor());
 				keyType.setTextColor(getSecondaryTextColor());
 				break;
@@ -698,6 +702,7 @@ public abstract class XmppActivity extends Activity {
 				keyType.setTextColor(getTertiaryTextColor());
 				break;
 			case INACTIVE_TRUSTED:
+			case INACTIVE_TRUSTED_X509:
 				trustToggle.setOnClickListener(null);
 				trustToggle.setChecked(true, false);
 				trustToggle.setEnabled(false);
@@ -707,15 +712,15 @@ public abstract class XmppActivity extends Activity {
 		}
 
 		if (showTag) {
-			keyType.setText(getString(R.string.omemo_fingerprint));
+			keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
 		} else {
 			keyType.setVisibility(View.GONE);
 		}
 		if (highlight) {
 			keyType.setTextColor(getResources().getColor(R.color.accent));
-			keyType.setText(getString(R.string.omemo_fingerprint_selected_message));
+			keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message));
 		} else {
-			keyType.setText(getString(R.string.omemo_fingerprint));
+			keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
 		}
 
 		key.setText(CryptoHelper.prettifyFingerprint(fingerprint));

src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -185,7 +185,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 						.getAccount().getAxolotlService().getFingerprintTrust(
 								message.getAxolotlFingerprint());
 
-				if(trust == null || trust != XmppAxolotlSession.Trust.TRUSTED) {
+				if(trust == null || (!trust.trusted() && !trust.trustedInactive())) {
 					viewHolder.indicator.setColorFilter(activity.getWarningTextColor());
 					viewHolder.indicator.setAlpha(1.0f);
 				} else {

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

@@ -211,7 +211,9 @@
 	<string name="your_fingerprint">Your fingerprint</string>
 	<string name="otr_fingerprint">OTR fingerprint</string>
 	<string name="omemo_fingerprint">OMEMO fingerprint</string>
+	<string name="omemo_fingerprint_x509">OMEMO fingerprint (X509 verified)</string>
 	<string name="omemo_fingerprint_selected_message">OMEMO fingerprint of message</string>
+	<string name="omemo_fingerprint_x509_selected_message">OMEMO fingerprint (X509 verified) of message</string>
 	<string name="this_device_omemo_fingerprint">Own OMEMO fingerprint</string>
 	<string name="other_devices">Other devices</string>
 	<string name="trust_omemo_fingerprints">Trust OMEMO Fingerprints</string>