refactore trust enum to be FingerprintStatus class with trust and active
This commit is contained in:
		
							parent
							
								
									6da8b50d95
								
							
						
					
					
						commit
						05fc15be3d
					
				| @ -256,18 +256,18 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		return axolotlStore.getIdentityKeyPair().getPublicKey().getFingerprint().replaceAll("\\s", ""); | 		return axolotlStore.getIdentityKeyPair().getPublicKey().getFingerprint().replaceAll("\\s", ""); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust) { | 	public Set<IdentityKey> getKeysWithTrust(FingerprintStatus status) { | ||||||
| 		return axolotlStore.getContactKeysWithTrust(account.getJid().toBareJid().toPreppedString(), trust); | 		return axolotlStore.getContactKeysWithTrust(account.getJid().toBareJid().toPreppedString(), status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Jid jid) { | 	public Set<IdentityKey> getKeysWithTrust(FingerprintStatus status, Jid jid) { | ||||||
| 		return axolotlStore.getContactKeysWithTrust(jid.toBareJid().toPreppedString(), trust); | 		return axolotlStore.getContactKeysWithTrust(jid.toBareJid().toPreppedString(), status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, List<Jid> jids) { | 	public Set<IdentityKey> getKeysWithTrust(FingerprintStatus status, List<Jid> jids) { | ||||||
| 		Set<IdentityKey> keys = new HashSet<>(); | 		Set<IdentityKey> keys = new HashSet<>(); | ||||||
| 		for(Jid jid : jids) { | 		for(Jid jid : jids) { | ||||||
| 			keys.addAll(axolotlStore.getContactKeysWithTrust(jid.toPreppedString(), trust)); | 			keys.addAll(axolotlStore.getContactKeysWithTrust(jid.toPreppedString(), status)); | ||||||
| 		} | 		} | ||||||
| 		return keys; | 		return keys; | ||||||
| 	} | 	} | ||||||
| @ -355,19 +355,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		return this.deviceIds.get(account.getJid().toBareJid()); | 		return this.deviceIds.get(account.getJid().toBareJid()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void setTrustOnSessions(final Jid jid, @NonNull final Set<Integer> deviceIds, |  | ||||||
| 	                                final XmppAxolotlSession.Trust from, |  | ||||||
| 	                                final XmppAxolotlSession.Trust to) { |  | ||||||
| 		for (Integer deviceId : deviceIds) { |  | ||||||
| 			AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId); |  | ||||||
| 			XmppAxolotlSession session = sessions.get(address); |  | ||||||
| 			if (session != null && session.getFingerprint() != null |  | ||||||
| 					&& session.getTrust() == from) { |  | ||||||
| 				session.setTrust(to); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) { | 	public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) { | ||||||
| 		if (jid.toBareJid().equals(account.getJid().toBareJid())) { | 		if (jid.toBareJid().equals(account.getJid().toBareJid())) { | ||||||
| 			if (!deviceIds.isEmpty()) { | 			if (!deviceIds.isEmpty()) { | ||||||
| @ -389,23 +376,25 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		} | 		} | ||||||
| 		Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString())); | 		Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString())); | ||||||
| 		expiredDevices.removeAll(deviceIds); | 		expiredDevices.removeAll(deviceIds); | ||||||
| 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.TRUSTED, | 		for (Integer deviceId : expiredDevices) { | ||||||
| 				XmppAxolotlSession.Trust.INACTIVE_TRUSTED); | 			AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId); | ||||||
| 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.TRUSTED_X509, | 			XmppAxolotlSession session = sessions.get(address); | ||||||
| 				XmppAxolotlSession.Trust.INACTIVE_TRUSTED_X509); | 			if (session != null && session.getFingerprint() != null) { | ||||||
| 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.UNDECIDED, | 				if (session.getTrust().isActive()) { | ||||||
| 				XmppAxolotlSession.Trust.INACTIVE_UNDECIDED); | 					session.setTrust(session.getTrust().toInactive()); | ||||||
| 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.UNTRUSTED, | 				} | ||||||
| 				XmppAxolotlSession.Trust.INACTIVE_UNTRUSTED); | 			} | ||||||
|  | 		} | ||||||
| 		Set<Integer> newDevices = new HashSet<>(deviceIds); | 		Set<Integer> newDevices = new HashSet<>(deviceIds); | ||||||
| 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_TRUSTED, | 		for (Integer deviceId : newDevices) { | ||||||
| 				XmppAxolotlSession.Trust.TRUSTED); | 			AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId); | ||||||
| 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_TRUSTED_X509, | 			XmppAxolotlSession session = sessions.get(address); | ||||||
| 				XmppAxolotlSession.Trust.TRUSTED_X509); | 			if (session != null && session.getFingerprint() != null) { | ||||||
| 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNDECIDED, | 				if (!session.getTrust().isActive()) { | ||||||
| 				XmppAxolotlSession.Trust.UNDECIDED); | 					session.setTrust(session.getTrust().toActive()); | ||||||
| 		setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNTRUSTED, | 				} | ||||||
| 				XmppAxolotlSession.Trust.UNTRUSTED); | 			} | ||||||
|  | 		} | ||||||
| 		this.deviceIds.put(jid, deviceIds); | 		this.deviceIds.put(jid, deviceIds); | ||||||
| 		mXmppConnectionService.keyStatusUpdated(null); | 		mXmppConnectionService.keyStatusUpdated(null); | ||||||
| 	} | 	} | ||||||
| @ -428,7 +417,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void purgeKey(final String fingerprint) { | 	public void purgeKey(final String fingerprint) { | ||||||
| 		axolotlStore.setFingerprintTrust(fingerprint.replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED); | 		axolotlStore.setFingerprintTrust(fingerprint.replaceAll("\\s", ""), FingerprintStatus.createCompromised()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void publishOwnDeviceIdIfNeeded() { | 	public void publishOwnDeviceIdIfNeeded() { | ||||||
| @ -692,16 +681,16 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		return jids; | 		return jids; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint) { | 	public FingerprintStatus getFingerprintTrust(String fingerprint) { | ||||||
| 		return axolotlStore.getFingerprintTrust(fingerprint); | 		return axolotlStore.getFingerprintStatus(fingerprint); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public X509Certificate getFingerprintCertificate(String fingerprint) { | 	public X509Certificate getFingerprintCertificate(String fingerprint) { | ||||||
| 		return axolotlStore.getFingerprintCertificate(fingerprint); | 		return axolotlStore.getFingerprintCertificate(fingerprint); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setFingerprintTrust(String fingerprint, XmppAxolotlSession.Trust trust) { | 	public void setFingerprintTrust(String fingerprint, FingerprintStatus status) { | ||||||
| 		axolotlStore.setFingerprintTrust(fingerprint, trust); | 		axolotlStore.setFingerprintTrust(fingerprint, status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void verifySessionWithPEP(final XmppAxolotlSession session) { | 	private void verifySessionWithPEP(final XmppAxolotlSession session) { | ||||||
| @ -724,7 +713,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 									mXmppConnectionService.getMemorizingTrustManager().getNonInteractive().checkClientTrusted(verification.first, "RSA"); | 									mXmppConnectionService.getMemorizingTrustManager().getNonInteractive().checkClientTrusted(verification.first, "RSA"); | ||||||
| 									String fingerprint = session.getFingerprint(); | 									String fingerprint = session.getFingerprint(); | ||||||
| 									Log.d(Config.LOGTAG, "verified session with x.509 signature. fingerprint was: "+fingerprint); | 									Log.d(Config.LOGTAG, "verified session with x.509 signature. fingerprint was: "+fingerprint); | ||||||
| 									setFingerprintTrust(fingerprint, XmppAxolotlSession.Trust.TRUSTED_X509); | 									setFingerprintTrust(fingerprint, FingerprintStatus.createActiveVerified(true)); | ||||||
| 									axolotlStore.setFingerprintCertificate(fingerprint, verification.first[0]); | 									axolotlStore.setFingerprintCertificate(fingerprint, verification.first[0]); | ||||||
| 									fetchStatusMap.put(address, FetchStatus.SUCCESS_VERIFIED); | 									fetchStatusMap.put(address, FetchStatus.SUCCESS_VERIFIED); | ||||||
| 									Bundle information = CryptoHelper.extractCertificateInformation(verification.first[0]); | 									Bundle information = CryptoHelper.extractCertificateInformation(verification.first[0]); | ||||||
| @ -921,8 +910,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		sessions.addAll(findOwnSessions()); | 		sessions.addAll(findOwnSessions()); | ||||||
| 		boolean verified = false; | 		boolean verified = false; | ||||||
| 		for(XmppAxolotlSession session : sessions) { | 		for(XmppAxolotlSession session : sessions) { | ||||||
| 			if (session.getTrust().trusted()) { | 			if (session.getTrust().isTrustedAndActive()) { | ||||||
| 				if (session.getTrust() == XmppAxolotlSession.Trust.TRUSTED_X509) { | 				if (session.getTrust().getTrust() == FingerprintStatus.Trust.VERIFIED_X509) { | ||||||
| 					verified = true; | 					verified = true; | ||||||
| 				} else { | 				} else { | ||||||
| 					return false; | 					return false; | ||||||
|  | |||||||
| @ -0,0 +1,122 @@ | |||||||
|  | package eu.siacs.conversations.crypto.axolotl; | ||||||
|  | 
 | ||||||
|  | import android.content.ContentValues; | ||||||
|  | import android.database.Cursor; | ||||||
|  | 
 | ||||||
|  | public class FingerprintStatus { | ||||||
|  | 
 | ||||||
|  |     private Trust trust = Trust.UNTRUSTED; | ||||||
|  |     private boolean active = false; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean equals(Object o) { | ||||||
|  |         if (this == o) return true; | ||||||
|  |         if (o == null || getClass() != o.getClass()) return false; | ||||||
|  | 
 | ||||||
|  |         FingerprintStatus that = (FingerprintStatus) o; | ||||||
|  | 
 | ||||||
|  |         return active == that.active && trust == that.trust; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public int hashCode() { | ||||||
|  |         int result = trust.hashCode(); | ||||||
|  |         result = 31 * result + (active ? 1 : 0); | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private FingerprintStatus() { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public ContentValues toContentValues() { | ||||||
|  |         final ContentValues contentValues = new ContentValues(); | ||||||
|  |         contentValues.put(SQLiteAxolotlStore.TRUST,trust.toString()); | ||||||
|  |         contentValues.put(SQLiteAxolotlStore.ACTIVE,active ? 1 : 0); | ||||||
|  |         return contentValues; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FingerprintStatus fromCursor(Cursor cursor) { | ||||||
|  |         final FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         try { | ||||||
|  |             status.trust = Trust.valueOf(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.TRUST))); | ||||||
|  |         } catch(IllegalArgumentException e) { | ||||||
|  |             status.trust = Trust.UNTRUSTED; | ||||||
|  |         } | ||||||
|  |         status.active = cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.ACTIVE)) > 0; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FingerprintStatus createActiveUndecided() { | ||||||
|  |         final FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.trust = Trust.UNDECIDED; | ||||||
|  |         status.active = true; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FingerprintStatus createActiveVerified(boolean x509) { | ||||||
|  |         final FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.trust = x509 ? Trust.VERIFIED_X509 : Trust.VERIFIED; | ||||||
|  |         status.active = true; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FingerprintStatus createActive(boolean trusted) { | ||||||
|  |         final FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.trust = trusted ? Trust.TRUSTED : Trust.UNTRUSTED; | ||||||
|  |         status.active = true; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isTrustedAndActive() { | ||||||
|  |         return active && isTrusted(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isTrusted() { | ||||||
|  |         return trust == Trust.TRUSTED || trust == Trust.VERIFIED || trust == Trust.VERIFIED_X509; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isCompromised() { | ||||||
|  |         return trust == Trust.COMPROMISED; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isActive() { | ||||||
|  |         return active; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public FingerprintStatus toActive() { | ||||||
|  |         FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.trust = trust; | ||||||
|  |         status.active = true; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public FingerprintStatus toInactive() { | ||||||
|  |         FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.trust = trust; | ||||||
|  |         status.active = false; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Trust getTrust() { | ||||||
|  |         return trust; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FingerprintStatus createCompromised() { | ||||||
|  |         FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.active = false; | ||||||
|  |         status.trust = Trust.COMPROMISED; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public enum Trust { | ||||||
|  |         COMPROMISED, | ||||||
|  |         UNDECIDED, | ||||||
|  |         UNTRUSTED, | ||||||
|  |         TRUSTED, | ||||||
|  |         VERIFIED, | ||||||
|  |         VERIFIED_X509 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -35,7 +35,9 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 	public static final String KEY = "key"; | 	public static final String KEY = "key"; | ||||||
| 	public static final String FINGERPRINT = "fingerprint"; | 	public static final String FINGERPRINT = "fingerprint"; | ||||||
| 	public static final String NAME = "name"; | 	public static final String NAME = "name"; | ||||||
| 	public static final String TRUSTED = "trusted"; | 	public static final String TRUSTED = "trusted"; //no longer used | ||||||
|  | 	public static final String TRUST = "trust"; | ||||||
|  | 	public static final String ACTIVE = "active"; | ||||||
| 	public static final String OWN = "ownkey"; | 	public static final String OWN = "ownkey"; | ||||||
| 	public static final String CERTIFICATE = "certificate"; | 	public static final String CERTIFICATE = "certificate"; | ||||||
| 
 | 
 | ||||||
| @ -51,11 +53,11 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 	private int localRegistrationId; | 	private int localRegistrationId; | ||||||
| 	private int currentPreKeyId = 0; | 	private int currentPreKeyId = 0; | ||||||
| 
 | 
 | ||||||
| 	private final LruCache<String, XmppAxolotlSession.Trust> trustCache = | 	private final LruCache<String, FingerprintStatus> trustCache = | ||||||
| 			new LruCache<String, XmppAxolotlSession.Trust>(NUM_TRUSTS_TO_CACHE) { | 			new LruCache<String, FingerprintStatus>(NUM_TRUSTS_TO_CACHE) { | ||||||
| 				@Override | 				@Override | ||||||
| 				protected XmppAxolotlSession.Trust create(String fingerprint) { | 				protected FingerprintStatus create(String fingerprint) { | ||||||
| 					return mXmppConnectionService.databaseBackend.isIdentityKeyTrusted(account, fingerprint); | 					return mXmppConnectionService.databaseBackend.getFingerprintStatus(account, fingerprint); | ||||||
| 				} | 				} | ||||||
| 			}; | 			}; | ||||||
| 
 | 
 | ||||||
| @ -208,12 +210,12 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint) { | 	public FingerprintStatus getFingerprintStatus(String fingerprint) { | ||||||
| 		return (fingerprint == null)? null : trustCache.get(fingerprint); | 		return (fingerprint == null)? null : trustCache.get(fingerprint); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setFingerprintTrust(String fingerprint, XmppAxolotlSession.Trust trust) { | 	public void setFingerprintTrust(String fingerprint, FingerprintStatus status) { | ||||||
| 		mXmppConnectionService.databaseBackend.setIdentityKeyTrust(account, fingerprint, trust); | 		mXmppConnectionService.databaseBackend.setIdentityKeyTrust(account, fingerprint, status); | ||||||
| 		trustCache.remove(fingerprint); | 		trustCache.remove(fingerprint); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -225,8 +227,8 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 		return mXmppConnectionService.databaseBackend.getIdentityKeyCertifcate(account, fingerprint); | 		return mXmppConnectionService.databaseBackend.getIdentityKeyCertifcate(account, fingerprint); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public Set<IdentityKey> getContactKeysWithTrust(String bareJid, XmppAxolotlSession.Trust trust) { | 	public Set<IdentityKey> getContactKeysWithTrust(String bareJid, FingerprintStatus status) { | ||||||
| 		return mXmppConnectionService.databaseBackend.loadIdentityKeys(account, bareJid, trust); | 		return mXmppConnectionService.databaseBackend.loadIdentityKeys(account, bareJid, status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public long getContactNumTrustedKeys(String bareJid) { | 	public long getContactNumTrustedKeys(String bareJid) { | ||||||
|  | |||||||
| @ -19,9 +19,6 @@ import org.whispersystems.libaxolotl.protocol.CiphertextMessage; | |||||||
| import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; | import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; | ||||||
| import org.whispersystems.libaxolotl.protocol.WhisperMessage; | import org.whispersystems.libaxolotl.protocol.WhisperMessage; | ||||||
| 
 | 
 | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Map; |  | ||||||
| 
 |  | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.entities.Account; | import eu.siacs.conversations.entities.Account; | ||||||
| 
 | 
 | ||||||
| @ -34,76 +31,6 @@ public class XmppAxolotlSession { | |||||||
| 	private Integer preKeyId = null; | 	private Integer preKeyId = null; | ||||||
| 	private boolean fresh = true; | 	private boolean fresh = true; | ||||||
| 
 | 
 | ||||||
| 	public enum Trust { |  | ||||||
| 		UNDECIDED(0), |  | ||||||
| 		TRUSTED(1), |  | ||||||
| 		UNTRUSTED(2), |  | ||||||
| 		COMPROMISED(3), |  | ||||||
| 		INACTIVE_TRUSTED(4), |  | ||||||
| 		INACTIVE_UNDECIDED(5), |  | ||||||
| 		INACTIVE_UNTRUSTED(6), |  | ||||||
| 		TRUSTED_X509(7), |  | ||||||
| 		INACTIVE_TRUSTED_X509(8); |  | ||||||
| 
 |  | ||||||
| 		private static final Map<Integer, Trust> trustsByValue = new HashMap<>(); |  | ||||||
| 
 |  | ||||||
| 		static { |  | ||||||
| 			for (Trust trust : Trust.values()) { |  | ||||||
| 				trustsByValue.put(trust.getCode(), trust); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private final int code; |  | ||||||
| 
 |  | ||||||
| 		Trust(int code) { |  | ||||||
| 			this.code = code; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public int getCode() { |  | ||||||
| 			return this.code; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public String toString() { |  | ||||||
| 			switch (this) { |  | ||||||
| 				case UNDECIDED: |  | ||||||
| 					return "Trust undecided " + getCode(); |  | ||||||
| 				case TRUSTED: |  | ||||||
| 					return "Trusted " + getCode(); |  | ||||||
| 				case COMPROMISED: |  | ||||||
| 					return "Compromised " + getCode(); |  | ||||||
| 				case INACTIVE_TRUSTED: |  | ||||||
| 					return "Inactive (Trusted)" + getCode(); |  | ||||||
| 				case INACTIVE_UNDECIDED: |  | ||||||
| 					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(); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public static Trust fromBoolean(Boolean trusted) { |  | ||||||
| 			return trusted ? TRUSTED : UNTRUSTED; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		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, IdentityKey identityKey) { | 	public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, IdentityKey identityKey) { | ||||||
| 		this(account, store, remoteAddress); | 		this(account, store, remoteAddress); | ||||||
| 		this.identityKey = identityKey; | 		this.identityKey = identityKey; | ||||||
| @ -145,32 +72,26 @@ public class XmppAxolotlSession { | |||||||
| 		this.fresh = false; | 		this.fresh = false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	protected void setTrust(Trust trust) { | 	protected void setTrust(FingerprintStatus status) { | ||||||
| 		sqLiteAxolotlStore.setFingerprintTrust(getFingerprint(), trust); | 		sqLiteAxolotlStore.setFingerprintTrust(getFingerprint(), status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	protected Trust getTrust() { | 	protected FingerprintStatus getTrust() { | ||||||
| 		Trust trust = sqLiteAxolotlStore.getFingerprintTrust(getFingerprint()); | 		FingerprintStatus status = sqLiteAxolotlStore.getFingerprintStatus(getFingerprint()); | ||||||
| 		return (trust == null) ? Trust.UNDECIDED : trust; | 		return (status == null) ? FingerprintStatus.createActiveUndecided() : status; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	public byte[] processReceiving(byte[] encryptedKey) { | 	public byte[] processReceiving(byte[] encryptedKey) { | ||||||
| 		byte[] plaintext = null; | 		byte[] plaintext = null; | ||||||
| 		Trust trust = getTrust(); | 		FingerprintStatus status = getTrust(); | ||||||
| 		switch (trust) { | 		if (!status.isCompromised()) { | ||||||
| 			case INACTIVE_TRUSTED: |  | ||||||
| 			case UNDECIDED: |  | ||||||
| 			case UNTRUSTED: |  | ||||||
| 			case TRUSTED: |  | ||||||
| 			case INACTIVE_TRUSTED_X509: |  | ||||||
| 			case TRUSTED_X509: |  | ||||||
| 			try { | 			try { | ||||||
| 				try { | 				try { | ||||||
| 					PreKeyWhisperMessage message = new PreKeyWhisperMessage(encryptedKey); | 					PreKeyWhisperMessage message = new PreKeyWhisperMessage(encryptedKey); | ||||||
| 					if (!message.getPreKeyId().isPresent()) { | 					if (!message.getPreKeyId().isPresent()) { | ||||||
| 						Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "PreKeyWhisperMessage did not contain a PreKeyId"); | 						Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "PreKeyWhisperMessage did not contain a PreKeyId"); | ||||||
| 							break; | 						return null; | ||||||
| 					} | 					} | ||||||
| 					Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "PreKeyWhisperMessage received, new session ID:" + message.getSignedPreKeyId() + "/" + message.getPreKeyId()); | 					Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "PreKeyWhisperMessage received, new session ID:" + message.getSignedPreKeyId() + "/" + message.getPreKeyId()); | ||||||
| 					IdentityKey msgIdentityKey = message.getIdentityKey(); | 					IdentityKey msgIdentityKey = message.getIdentityKey(); | ||||||
| @ -193,27 +114,18 @@ public class XmppAxolotlSession { | |||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (plaintext != null) { | 			if (plaintext != null) { | ||||||
| 					if (trust == Trust.INACTIVE_TRUSTED) { | 				if (!status.isActive()) { | ||||||
| 						setTrust(Trust.TRUSTED); | 					setTrust(status.toActive()); | ||||||
| 					} else if (trust == Trust.INACTIVE_TRUSTED_X509) { |  | ||||||
| 						setTrust(Trust.TRUSTED_X509); |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 				break; |  | ||||||
| 
 |  | ||||||
| 			case COMPROMISED: |  | ||||||
| 			default: |  | ||||||
| 				// ignore |  | ||||||
| 				break; |  | ||||||
| 		} | 		} | ||||||
| 		return plaintext; | 		return plaintext; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	public byte[] processSending(@NonNull byte[] outgoingMessage) { | 	public byte[] processSending(@NonNull byte[] outgoingMessage) { | ||||||
| 		Trust trust = getTrust(); | 		FingerprintStatus status = getTrust(); | ||||||
| 		if (trust.trusted()) { | 		if (status.isTrustedAndActive()) { | ||||||
| 			CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); | 			CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); | ||||||
| 			return ciphertextMessage.serialize(); | 			return ciphertextMessage.serialize(); | ||||||
| 		} else { | 		} else { | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import java.net.MalformedURLException; | |||||||
| import java.net.URL; | import java.net.URL; | ||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
|  | 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.utils.CryptoHelper; | import eu.siacs.conversations.utils.CryptoHelper; | ||||||
| import eu.siacs.conversations.utils.GeoHelper; | import eu.siacs.conversations.utils.GeoHelper; | ||||||
| @ -811,8 +812,8 @@ public class Message extends AbstractEntity { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public boolean isTrusted() { | 	public boolean isTrusted() { | ||||||
| 		XmppAxolotlSession.Trust t = conversation.getAccount().getAxolotlService().getFingerprintTrust(axolotlFingerprint); | 		FingerprintStatus s = conversation.getAccount().getAxolotlService().getFingerprintTrust(axolotlFingerprint); | ||||||
| 		return t != null && t.trusted(); | 		return s != null && s.isTrustedAndActive(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private  int getPreviousEncryption() { | 	private  int getPreviousEncryption() { | ||||||
|  | |||||||
| @ -27,17 +27,19 @@ import java.security.cert.CertificateException; | |||||||
| import java.security.cert.CertificateFactory; | import java.security.cert.CertificateFactory; | ||||||
| import java.security.cert.X509Certificate; | import java.security.cert.X509Certificate; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.concurrent.CopyOnWriteArrayList; | import java.util.concurrent.CopyOnWriteArrayList; | ||||||
| import org.json.JSONException; | import org.json.JSONException; | ||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.crypto.axolotl.AxolotlService; | import eu.siacs.conversations.crypto.axolotl.AxolotlService; | ||||||
|  | import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; | ||||||
| import eu.siacs.conversations.crypto.axolotl.SQLiteAxolotlStore; | import eu.siacs.conversations.crypto.axolotl.SQLiteAxolotlStore; | ||||||
| import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; |  | ||||||
| import eu.siacs.conversations.entities.Account; | import eu.siacs.conversations.entities.Account; | ||||||
| import eu.siacs.conversations.entities.Contact; | import eu.siacs.conversations.entities.Contact; | ||||||
| import eu.siacs.conversations.entities.Conversation; | import eu.siacs.conversations.entities.Conversation; | ||||||
| @ -45,7 +47,6 @@ import eu.siacs.conversations.entities.Message; | |||||||
| import eu.siacs.conversations.entities.PresenceTemplate; | import eu.siacs.conversations.entities.PresenceTemplate; | ||||||
| import eu.siacs.conversations.entities.Roster; | import eu.siacs.conversations.entities.Roster; | ||||||
| import eu.siacs.conversations.entities.ServiceDiscoveryResult; | import eu.siacs.conversations.entities.ServiceDiscoveryResult; | ||||||
| import eu.siacs.conversations.generator.AbstractGenerator; |  | ||||||
| import eu.siacs.conversations.xmpp.jid.InvalidJidException; | import eu.siacs.conversations.xmpp.jid.InvalidJidException; | ||||||
| import eu.siacs.conversations.xmpp.jid.Jid; | import eu.siacs.conversations.xmpp.jid.Jid; | ||||||
| 
 | 
 | ||||||
| @ -54,7 +55,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 	private static DatabaseBackend instance = null; | 	private static DatabaseBackend instance = null; | ||||||
| 
 | 
 | ||||||
| 	private static final String DATABASE_NAME = "history"; | 	private static final String DATABASE_NAME = "history"; | ||||||
| 	private static final int DATABASE_VERSION = 30; | 	private static final int DATABASE_VERSION = 31; | ||||||
| 
 | 
 | ||||||
| 	private static String CREATE_CONTATCS_STATEMENT = "create table " | 	private static String CREATE_CONTATCS_STATEMENT = "create table " | ||||||
| 			+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " | 			+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " | ||||||
| @ -129,7 +130,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 			+ SQLiteAxolotlStore.OWN + " INTEGER, " | 			+ SQLiteAxolotlStore.OWN + " INTEGER, " | ||||||
| 			+ SQLiteAxolotlStore.FINGERPRINT + " TEXT, " | 			+ SQLiteAxolotlStore.FINGERPRINT + " TEXT, " | ||||||
| 			+ SQLiteAxolotlStore.CERTIFICATE + " BLOB, " | 			+ SQLiteAxolotlStore.CERTIFICATE + " BLOB, " | ||||||
| 			+ SQLiteAxolotlStore.TRUSTED + " INTEGER, " | 			+ SQLiteAxolotlStore.TRUST + " TEXT, " | ||||||
|  | 			+ SQLiteAxolotlStore.ACTIVE + " NUMBER, " | ||||||
| 			+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" | 			+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" | ||||||
| 			+ SQLiteAxolotlStore.ACCOUNT | 			+ SQLiteAxolotlStore.ACCOUNT | ||||||
| 			+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " | 			+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " | ||||||
| @ -297,7 +299,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 				deleteSession(db, account, ownAddress); | 				deleteSession(db, account, ownAddress); | ||||||
| 				IdentityKeyPair identityKeyPair = loadOwnIdentityKeyPair(db, account); | 				IdentityKeyPair identityKeyPair = loadOwnIdentityKeyPair(db, account); | ||||||
| 				if (identityKeyPair != null) { | 				if (identityKeyPair != null) { | ||||||
| 					setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED); | 					String[] selectionArgs = { | ||||||
|  | 							account.getUuid(), | ||||||
|  | 							identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", "") | ||||||
|  | 					}; | ||||||
|  | 					ContentValues values = new ContentValues(); | ||||||
|  | 					values.put(SQLiteAxolotlStore.TRUSTED, 2); | ||||||
|  | 					db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, | ||||||
|  | 							SQLiteAxolotlStore.ACCOUNT + " = ? AND " | ||||||
|  | 									+ SQLiteAxolotlStore.FINGERPRINT + " = ? ", | ||||||
|  | 							selectionArgs); | ||||||
| 				} else { | 				} else { | ||||||
| 					Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not load own identity key pair"); | 					Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not load own identity key pair"); | ||||||
| 				} | 				} | ||||||
| @ -346,6 +357,33 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		if (oldVersion < 30 && newVersion >= 30) { | 		if (oldVersion < 30 && newVersion >= 30) { | ||||||
| 			db.execSQL(CREATE_START_TIMES_TABLE); | 			db.execSQL(CREATE_START_TIMES_TABLE); | ||||||
| 		} | 		} | ||||||
|  | 		if (oldVersion < 31 && newVersion >= 31) { | ||||||
|  | 			db.execSQL("ALTER TABLE "+ SQLiteAxolotlStore.IDENTITIES_TABLENAME + " ADD COLUMN "+SQLiteAxolotlStore.TRUST + " TEXT"); | ||||||
|  | 			db.execSQL("ALTER TABLE "+ SQLiteAxolotlStore.IDENTITIES_TABLENAME + " ADD COLUMN "+SQLiteAxolotlStore.ACTIVE + " NUMBER"); | ||||||
|  | 			HashMap<Integer,ContentValues> migration = new HashMap<>(); | ||||||
|  | 			migration.put(0,createFingerprintStatusContentValues(FingerprintStatus.Trust.UNDECIDED,true)); | ||||||
|  | 			migration.put(1,createFingerprintStatusContentValues(FingerprintStatus.Trust.TRUSTED, true)); | ||||||
|  | 			migration.put(2,createFingerprintStatusContentValues(FingerprintStatus.Trust.UNTRUSTED, true)); | ||||||
|  | 			migration.put(3,createFingerprintStatusContentValues(FingerprintStatus.Trust.COMPROMISED, false)); | ||||||
|  | 			migration.put(4,createFingerprintStatusContentValues(FingerprintStatus.Trust.TRUSTED, false)); | ||||||
|  | 			migration.put(5,createFingerprintStatusContentValues(FingerprintStatus.Trust.UNDECIDED, false)); | ||||||
|  | 			migration.put(6,createFingerprintStatusContentValues(FingerprintStatus.Trust.UNTRUSTED, false)); | ||||||
|  | 			migration.put(7,createFingerprintStatusContentValues(FingerprintStatus.Trust.VERIFIED_X509, true)); | ||||||
|  | 			migration.put(8,createFingerprintStatusContentValues(FingerprintStatus.Trust.VERIFIED_X509, false)); | ||||||
|  | 			for(Map.Entry<Integer,ContentValues> entry : migration.entrySet()) { | ||||||
|  | 				String whereClause = SQLiteAxolotlStore.TRUSTED+"=?"; | ||||||
|  | 				String[] where = {String.valueOf(entry.getKey())}; | ||||||
|  | 				db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME,entry.getValue(),whereClause,where); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private static ContentValues createFingerprintStatusContentValues(FingerprintStatus.Trust trust, boolean active) { | ||||||
|  | 		ContentValues values = new ContentValues(); | ||||||
|  | 		values.put(SQLiteAxolotlStore.TRUST,trust.toString()); | ||||||
|  | 		values.put(SQLiteAxolotlStore.ACTIVE,active ? 1 : 0); | ||||||
|  | 		return values; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void canonicalizeJids(SQLiteDatabase db) { | 	private void canonicalizeJids(SQLiteDatabase db) { | ||||||
| @ -1006,7 +1044,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, Boolean own, String fingerprint) { | 	private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, Boolean own, String fingerprint) { | ||||||
| 		String[] columns = {SQLiteAxolotlStore.TRUSTED, | 		String[] columns = {SQLiteAxolotlStore.TRUST, | ||||||
|  | 				SQLiteAxolotlStore.ACTIVE, | ||||||
| 				SQLiteAxolotlStore.KEY}; | 				SQLiteAxolotlStore.KEY}; | ||||||
| 		ArrayList<String> selectionArgs = new ArrayList<>(4); | 		ArrayList<String> selectionArgs = new ArrayList<>(4); | ||||||
| 		selectionArgs.add(account.getUuid()); | 		selectionArgs.add(account.getUuid()); | ||||||
| @ -1058,14 +1097,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		return loadIdentityKeys(account, name, null); | 		return loadIdentityKeys(account, name, null); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public Set<IdentityKey> loadIdentityKeys(Account account, String name, XmppAxolotlSession.Trust trust) { | 	public Set<IdentityKey> loadIdentityKeys(Account account, String name, FingerprintStatus status) { | ||||||
| 		Set<IdentityKey> identityKeys = new HashSet<>(); | 		Set<IdentityKey> identityKeys = new HashSet<>(); | ||||||
| 		Cursor cursor = getIdentityKeyCursor(account, name, false); | 		Cursor cursor = getIdentityKeyCursor(account, name, false); | ||||||
| 
 | 
 | ||||||
| 		while (cursor.moveToNext()) { | 		while (cursor.moveToNext()) { | ||||||
| 			if (trust != null && | 			if (status != null && !FingerprintStatus.fromCursor(cursor).equals(status)) { | ||||||
| 					cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED)) |  | ||||||
| 							!= trust.getCode()) { |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			try { | 			try { | ||||||
| @ -1084,22 +1121,24 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		String[] args = { | 		String[] args = { | ||||||
| 				account.getUuid(), | 				account.getUuid(), | ||||||
| 				name, | 				name, | ||||||
| 				String.valueOf(XmppAxolotlSession.Trust.TRUSTED.getCode()), | 				FingerprintStatus.Trust.TRUSTED.toString(), | ||||||
| 				String.valueOf(XmppAxolotlSession.Trust.TRUSTED_X509.getCode()) | 				FingerprintStatus.Trust.VERIFIED.toString(), | ||||||
|  | 				FingerprintStatus.Trust.VERIFIED_X509.toString() | ||||||
| 		}; | 		}; | ||||||
| 		return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME, | 		return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME, | ||||||
| 				SQLiteAxolotlStore.ACCOUNT + " = ?" | 				SQLiteAxolotlStore.ACCOUNT + " = ?" | ||||||
| 						+ " AND " + SQLiteAxolotlStore.NAME + " = ?" | 						+ " AND " + SQLiteAxolotlStore.NAME + " = ?" | ||||||
| 						+ " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR " + SQLiteAxolotlStore.TRUSTED + " = ?)", | 						+ " AND (" + SQLiteAxolotlStore.TRUST + " = ? OR " + SQLiteAxolotlStore.TRUST + " = ? OR " +SQLiteAxolotlStore.TRUST +" = ?)" | ||||||
|  | 						+ " AND " +SQLiteAxolotlStore.ACTIVE + " > 0", | ||||||
| 				args | 				args | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { | 	private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { | ||||||
| 		storeIdentityKey(account, name, own, fingerprint, base64Serialized, XmppAxolotlSession.Trust.UNDECIDED); | 		storeIdentityKey(account, name, own, fingerprint, base64Serialized, FingerprintStatus.createActiveUndecided()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, XmppAxolotlSession.Trust trusted) { | 	private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, FingerprintStatus status) { | ||||||
| 		SQLiteDatabase db = this.getWritableDatabase(); | 		SQLiteDatabase db = this.getWritableDatabase(); | ||||||
| 		ContentValues values = new ContentValues(); | 		ContentValues values = new ContentValues(); | ||||||
| 		values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); | 		values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); | ||||||
| @ -1107,35 +1146,34 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		values.put(SQLiteAxolotlStore.OWN, own ? 1 : 0); | 		values.put(SQLiteAxolotlStore.OWN, own ? 1 : 0); | ||||||
| 		values.put(SQLiteAxolotlStore.FINGERPRINT, fingerprint); | 		values.put(SQLiteAxolotlStore.FINGERPRINT, fingerprint); | ||||||
| 		values.put(SQLiteAxolotlStore.KEY, base64Serialized); | 		values.put(SQLiteAxolotlStore.KEY, base64Serialized); | ||||||
| 		values.put(SQLiteAxolotlStore.TRUSTED, trusted.getCode()); | 		values.putAll(status.toContentValues()); | ||||||
| 		db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); | 		db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public XmppAxolotlSession.Trust isIdentityKeyTrusted(Account account, String fingerprint) { | 	public FingerprintStatus getFingerprintStatus(Account account, String fingerprint) { | ||||||
| 		Cursor cursor = getIdentityKeyCursor(account, fingerprint); | 		Cursor cursor = getIdentityKeyCursor(account, fingerprint); | ||||||
| 		XmppAxolotlSession.Trust trust = null; | 		final FingerprintStatus status; | ||||||
| 		if (cursor.getCount() > 0) { | 		if (cursor.getCount() > 0) { | ||||||
| 			cursor.moveToFirst(); | 			cursor.moveToFirst(); | ||||||
| 			int trustValue = cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED)); | 			status = FingerprintStatus.fromCursor(cursor); | ||||||
| 			trust = XmppAxolotlSession.Trust.fromCode(trustValue); | 		} else { | ||||||
|  | 			status = null; | ||||||
| 		} | 		} | ||||||
| 		cursor.close(); | 		cursor.close(); | ||||||
| 		return trust; | 		return status; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public boolean setIdentityKeyTrust(Account account, String fingerprint, XmppAxolotlSession.Trust trust) { | 	public boolean setIdentityKeyTrust(Account account, String fingerprint, FingerprintStatus fingerprintStatus) { | ||||||
| 		SQLiteDatabase db = this.getWritableDatabase(); | 		SQLiteDatabase db = this.getWritableDatabase(); | ||||||
| 		return setIdentityKeyTrust(db, account, fingerprint, trust); | 		return setIdentityKeyTrust(db, account, fingerprint, fingerprintStatus); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private boolean setIdentityKeyTrust(SQLiteDatabase db, Account account, String fingerprint, XmppAxolotlSession.Trust trust) { | 	private boolean setIdentityKeyTrust(SQLiteDatabase db, Account account, String fingerprint, FingerprintStatus status) { | ||||||
| 		String[] selectionArgs = { | 		String[] selectionArgs = { | ||||||
| 				account.getUuid(), | 				account.getUuid(), | ||||||
| 				fingerprint | 				fingerprint | ||||||
| 		}; | 		}; | ||||||
| 		ContentValues values = new ContentValues(); | 		int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, status.toContentValues(), | ||||||
| 		values.put(SQLiteAxolotlStore.TRUSTED, trust.getCode()); |  | ||||||
| 		int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, |  | ||||||
| 				SQLiteAxolotlStore.ACCOUNT + " = ? AND " | 				SQLiteAxolotlStore.ACCOUNT + " = ? AND " | ||||||
| 						+ SQLiteAxolotlStore.FINGERPRINT + " = ? ", | 						+ SQLiteAxolotlStore.FINGERPRINT + " = ? ", | ||||||
| 				selectionArgs); | 				selectionArgs); | ||||||
| @ -1194,7 +1232,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void storeOwnIdentityKeyPair(Account account, IdentityKeyPair identityKeyPair) { | 	public void storeOwnIdentityKeyPair(Account account, IdentityKeyPair identityKeyPair) { | ||||||
| 		storeIdentityKey(account, account.getJid().toBareJid().toPreppedString(), true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), XmppAxolotlSession.Trust.TRUSTED); | 		storeIdentityKey(account, account.getJid().toBareJid().toPreppedString(), true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), FingerprintStatus.createActiveVerified(false)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,6 +39,7 @@ import eu.siacs.conversations.Config; | |||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
| import eu.siacs.conversations.crypto.PgpEngine; | import eu.siacs.conversations.crypto.PgpEngine; | ||||||
| import eu.siacs.conversations.crypto.axolotl.AxolotlService; | import eu.siacs.conversations.crypto.axolotl.AxolotlService; | ||||||
|  | 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.entities.Contact; | import eu.siacs.conversations.entities.Contact; | ||||||
| @ -509,8 +510,8 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void onOmemoKeyClicked(Account account, String fingerprint) { | 	private void onOmemoKeyClicked(Account account, String fingerprint) { | ||||||
| 		final XmppAxolotlSession.Trust trust = account.getAxolotlService().getFingerprintTrust(fingerprint); | 		FingerprintStatus status = account.getAxolotlService().getFingerprintTrust(fingerprint); | ||||||
| 		if (Config.X509_VERIFICATION && trust != null && trust == XmppAxolotlSession.Trust.TRUSTED_X509) { | 		if (Config.X509_VERIFICATION && status != null && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509) { | ||||||
| 			X509Certificate x509Certificate = account.getAxolotlService().getFingerprintCertificate(fingerprint); | 			X509Certificate x509Certificate = account.getAxolotlService().getFingerprintCertificate(fingerprint); | ||||||
| 			if (x509Certificate != null) { | 			if (x509Certificate != null) { | ||||||
| 				showCertificateInformationDialog(CryptoHelper.extractCertificateInformation(x509Certificate)); | 				showCertificateInformationDialog(CryptoHelper.extractCertificateInformation(x509Certificate)); | ||||||
|  | |||||||
| @ -49,6 +49,7 @@ import de.timroes.android.listview.EnhancedListView; | |||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
| import eu.siacs.conversations.crypto.axolotl.AxolotlService; | import eu.siacs.conversations.crypto.axolotl.AxolotlService; | ||||||
|  | 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.entities.Blockable; | import eu.siacs.conversations.entities.Blockable; | ||||||
| @ -1677,8 +1678,8 @@ public class ConversationActivity extends XmppActivity | |||||||
| 		AxolotlService axolotlService = mSelectedConversation.getAccount().getAxolotlService(); | 		AxolotlService axolotlService = mSelectedConversation.getAccount().getAxolotlService(); | ||||||
| 		final List<Jid> targets = axolotlService.getCryptoTargets(mSelectedConversation); | 		final List<Jid> targets = axolotlService.getCryptoTargets(mSelectedConversation); | ||||||
| 		boolean hasUnaccepted = !mSelectedConversation.getAcceptedCryptoTargets().containsAll(targets); | 		boolean hasUnaccepted = !mSelectedConversation.getAcceptedCryptoTargets().containsAll(targets); | ||||||
| 		boolean hasUndecidedOwn = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED).isEmpty(); | 		boolean hasUndecidedOwn = !axolotlService.getKeysWithTrust(FingerprintStatus.createActiveUndecided()).isEmpty(); | ||||||
| 		boolean hasUndecidedContacts = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED, targets).isEmpty(); | 		boolean hasUndecidedContacts = !axolotlService.getKeysWithTrust(FingerprintStatus.createActiveUndecided(), targets).isEmpty(); | ||||||
| 		boolean hasPendingKeys = !axolotlService.findDevicesWithoutSession(mSelectedConversation).isEmpty(); | 		boolean hasPendingKeys = !axolotlService.findDevicesWithoutSession(mSelectedConversation).isEmpty(); | ||||||
| 		boolean hasNoTrustedKeys = axolotlService.anyTargetHasNoTrustedKeys(targets); | 		boolean hasNoTrustedKeys = axolotlService.anyTargetHasNoTrustedKeys(targets); | ||||||
| 		if(hasUndecidedOwn || hasUndecidedContacts || hasPendingKeys || hasNoTrustedKeys || hasUnaccepted) { | 		if(hasUndecidedOwn || hasUndecidedContacts || hasPendingKeys || hasNoTrustedKeys || hasUnaccepted) { | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ import java.util.Set; | |||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
| import eu.siacs.conversations.crypto.axolotl.AxolotlService; | import eu.siacs.conversations.crypto.axolotl.AxolotlService; | ||||||
|  | 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.entities.Conversation; | import eu.siacs.conversations.entities.Conversation; | ||||||
| @ -108,7 +109,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate | |||||||
| 		for(final String fingerprint : ownKeysToTrust.keySet()) { | 		for(final String fingerprint : ownKeysToTrust.keySet()) { | ||||||
| 			hasOwnKeys = true; | 			hasOwnKeys = true; | ||||||
| 			addFingerprintRowWithListeners(ownKeys, mAccount, fingerprint, false, | 			addFingerprintRowWithListeners(ownKeys, mAccount, fingerprint, false, | ||||||
| 					XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint)), false, | 					FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint)), false, | ||||||
| 					new CompoundButton.OnCheckedChangeListener() { | 					new CompoundButton.OnCheckedChangeListener() { | ||||||
| 						@Override | 						@Override | ||||||
| 						public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | 						public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | ||||||
| @ -133,7 +134,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate | |||||||
| 				final Map<String, Boolean> fingerprints = entry.getValue(); | 				final Map<String, Boolean> fingerprints = entry.getValue(); | ||||||
| 				for (final String fingerprint : fingerprints.keySet()) { | 				for (final String fingerprint : fingerprints.keySet()) { | ||||||
| 					addFingerprintRowWithListeners(keysContainer, mAccount, fingerprint, false, | 					addFingerprintRowWithListeners(keysContainer, mAccount, fingerprint, false, | ||||||
| 							XmppAxolotlSession.Trust.fromBoolean(fingerprints.get(fingerprint)), false, | 							FingerprintStatus.createActive(fingerprints.get(fingerprint)), false, | ||||||
| 							new CompoundButton.OnCheckedChangeListener() { | 							new CompoundButton.OnCheckedChangeListener() { | ||||||
| 								@Override | 								@Override | ||||||
| 								public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | 								public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | ||||||
| @ -184,7 +185,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate | |||||||
| 		List<Jid> acceptedTargets = mConversation == null ? new ArrayList<Jid>() : mConversation.getAcceptedCryptoTargets(); | 		List<Jid> acceptedTargets = mConversation == null ? new ArrayList<Jid>() : mConversation.getAcceptedCryptoTargets(); | ||||||
| 		ownKeysToTrust.clear(); | 		ownKeysToTrust.clear(); | ||||||
| 		AxolotlService service = this.mAccount.getAxolotlService(); | 		AxolotlService service = this.mAccount.getAxolotlService(); | ||||||
| 		Set<IdentityKey> ownKeysSet = service.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED); | 		Set<IdentityKey> ownKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided()); | ||||||
| 		for(final IdentityKey identityKey : ownKeysSet) { | 		for(final IdentityKey identityKey : ownKeysSet) { | ||||||
| 			if(!ownKeysToTrust.containsKey(identityKey)) { | 			if(!ownKeysToTrust.containsKey(identityKey)) { | ||||||
| 				ownKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); | 				ownKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false); | ||||||
| @ -193,9 +194,9 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate | |||||||
| 		synchronized (this.foreignKeysToTrust) { | 		synchronized (this.foreignKeysToTrust) { | ||||||
| 			foreignKeysToTrust.clear(); | 			foreignKeysToTrust.clear(); | ||||||
| 			for (Jid jid : contactJids) { | 			for (Jid jid : contactJids) { | ||||||
| 				Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED, jid); | 				Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided(), jid); | ||||||
| 				if (hasNoOtherTrustedKeys(jid) && ownKeysSet.size() == 0) { | 				if (hasNoOtherTrustedKeys(jid) && ownKeysSet.size() == 0) { | ||||||
| 					foreignKeysSet.addAll(service.getKeysWithTrust(XmppAxolotlSession.Trust.UNTRUSTED, jid)); | 					foreignKeysSet.addAll(service.getKeysWithTrust(FingerprintStatus.createActive(false), jid)); | ||||||
| 				} | 				} | ||||||
| 				Map<String, Boolean> foreignFingerprints = new HashMap<>(); | 				Map<String, Boolean> foreignFingerprints = new HashMap<>(); | ||||||
| 				for (final IdentityKey identityKey : foreignKeysSet) { | 				for (final IdentityKey identityKey : foreignKeysSet) { | ||||||
| @ -280,7 +281,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate | |||||||
| 		for(final String fingerprint :ownKeysToTrust.keySet()) { | 		for(final String fingerprint :ownKeysToTrust.keySet()) { | ||||||
| 			mAccount.getAxolotlService().setFingerprintTrust( | 			mAccount.getAxolotlService().setFingerprintTrust( | ||||||
| 					fingerprint, | 					fingerprint, | ||||||
| 					XmppAxolotlSession.Trust.fromBoolean(ownKeysToTrust.get(fingerprint))); | 					FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint))); | ||||||
| 		} | 		} | ||||||
| 		List<Jid> acceptedTargets = mConversation == null ? new ArrayList<Jid>() : mConversation.getAcceptedCryptoTargets(); | 		List<Jid> acceptedTargets = mConversation == null ? new ArrayList<Jid>() : mConversation.getAcceptedCryptoTargets(); | ||||||
| 		synchronized (this.foreignKeysToTrust) { | 		synchronized (this.foreignKeysToTrust) { | ||||||
| @ -293,7 +294,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate | |||||||
| 				for (final String fingerprint : value.keySet()) { | 				for (final String fingerprint : value.keySet()) { | ||||||
| 					mAccount.getAxolotlService().setFingerprintTrust( | 					mAccount.getAxolotlService().setFingerprintTrust( | ||||||
| 							fingerprint, | 							fingerprint, | ||||||
| 							XmppAxolotlSession.Trust.fromBoolean(value.get(fingerprint))); | 							FingerprintStatus.createActive(value.get(fingerprint))); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -78,6 +78,7 @@ import java.util.concurrent.atomic.AtomicInteger; | |||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
|  | 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.entities.Contact; | import eu.siacs.conversations.entities.Contact; | ||||||
| @ -780,25 +781,21 @@ public abstract class XmppActivity extends Activity { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	protected boolean addFingerprintRow(LinearLayout keys, final Account account, final String fingerprint, boolean highlight, View.OnClickListener onKeyClickedListener) { | 	protected boolean addFingerprintRow(LinearLayout keys, final Account account, final String fingerprint, boolean highlight, View.OnClickListener onKeyClickedListener) { | ||||||
| 		final XmppAxolotlSession.Trust trust = account.getAxolotlService() | 		final FingerprintStatus status = account.getAxolotlService().getFingerprintTrust(fingerprint); | ||||||
| 				.getFingerprintTrust(fingerprint); | 		if (status == null) { | ||||||
| 		if (trust == null) { |  | ||||||
| 			return false; | 			return false; | ||||||
| 		} | 		} | ||||||
| 		return addFingerprintRowWithListeners(keys, account, fingerprint, highlight, trust, true, | 		return addFingerprintRowWithListeners(keys, account, fingerprint, highlight, status, true, | ||||||
| 				new CompoundButton.OnCheckedChangeListener() { | 				new CompoundButton.OnCheckedChangeListener() { | ||||||
| 					@Override | 					@Override | ||||||
| 					public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | 					public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | ||||||
| 						account.getAxolotlService().setFingerprintTrust(fingerprint, | 						account.getAxolotlService().setFingerprintTrust(fingerprint,FingerprintStatus.createActive(isChecked)); | ||||||
| 								(isChecked) ? XmppAxolotlSession.Trust.TRUSTED : |  | ||||||
| 										XmppAxolotlSession.Trust.UNTRUSTED); |  | ||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				new View.OnClickListener() { | 				new View.OnClickListener() { | ||||||
| 					@Override | 					@Override | ||||||
| 					public void onClick(View v) { | 					public void onClick(View v) { | ||||||
| 						account.getAxolotlService().setFingerprintTrust(fingerprint, | 						account.getAxolotlService().setFingerprintTrust(fingerprint,FingerprintStatus.createActive(true)); | ||||||
| 								XmppAxolotlSession.Trust.UNTRUSTED); |  | ||||||
| 						v.setEnabled(true); | 						v.setEnabled(true); | ||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| @ -810,13 +807,13 @@ public abstract class XmppActivity extends Activity { | |||||||
| 	protected boolean addFingerprintRowWithListeners(LinearLayout keys, final Account account, | 	protected boolean addFingerprintRowWithListeners(LinearLayout keys, final Account account, | ||||||
| 	                                                 final String fingerprint, | 	                                                 final String fingerprint, | ||||||
| 	                                                 boolean highlight, | 	                                                 boolean highlight, | ||||||
| 	                                                 XmppAxolotlSession.Trust trust, | 	                                                 FingerprintStatus status, | ||||||
| 	                                                 boolean showTag, | 	                                                 boolean showTag, | ||||||
| 	                                                 CompoundButton.OnCheckedChangeListener | 	                                                 CompoundButton.OnCheckedChangeListener | ||||||
| 			                                                 onCheckedChangeListener, | 			                                                 onCheckedChangeListener, | ||||||
| 	                                                 View.OnClickListener onClickListener, | 	                                                 View.OnClickListener onClickListener, | ||||||
| 													 View.OnClickListener onKeyClickedListener) { | 													 View.OnClickListener onKeyClickedListener) { | ||||||
| 		if (trust == XmppAxolotlSession.Trust.COMPROMISED) { | 		if (status.isCompromised()) { | ||||||
| 			return false; | 			return false; | ||||||
| 		} | 		} | ||||||
| 		View view = getLayoutInflater().inflate(R.layout.contact_key, keys, false); | 		View view = getLayoutInflater().inflate(R.layout.contact_key, keys, false); | ||||||
| @ -826,8 +823,6 @@ public abstract class XmppActivity extends Activity { | |||||||
| 		keyType.setOnClickListener(onKeyClickedListener); | 		keyType.setOnClickListener(onKeyClickedListener); | ||||||
| 		Switch trustToggle = (Switch) view.findViewById(R.id.tgl_trust); | 		Switch trustToggle = (Switch) view.findViewById(R.id.tgl_trust); | ||||||
| 		trustToggle.setVisibility(View.VISIBLE); | 		trustToggle.setVisibility(View.VISIBLE); | ||||||
| 		trustToggle.setOnCheckedChangeListener(onCheckedChangeListener); |  | ||||||
| 		trustToggle.setOnClickListener(onClickListener); |  | ||||||
| 		final View.OnLongClickListener purge = new View.OnLongClickListener() { | 		final View.OnLongClickListener purge = new View.OnLongClickListener() { | ||||||
| 			@Override | 			@Override | ||||||
| 			public boolean onLongClick(View v) { | 			public boolean onLongClick(View v) { | ||||||
| @ -835,50 +830,46 @@ public abstract class XmppActivity extends Activity { | |||||||
| 				return true; | 				return true; | ||||||
| 			} | 			} | ||||||
| 		}; | 		}; | ||||||
| 		boolean active = true; |  | ||||||
| 		view.setOnLongClickListener(purge); | 		view.setOnLongClickListener(purge); | ||||||
| 		key.setOnLongClickListener(purge); | 		key.setOnLongClickListener(purge); | ||||||
| 		keyType.setOnLongClickListener(purge); | 		keyType.setOnLongClickListener(purge); | ||||||
| 		boolean x509 = Config.X509_VERIFICATION | 		boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509; | ||||||
| 				&& (trust == XmppAxolotlSession.Trust.TRUSTED_X509 || trust == XmppAxolotlSession.Trust.INACTIVE_TRUSTED_X509); | 		final View.OnClickListener toast; | ||||||
| 		switch (trust) { | 		if (status.isActive()) { | ||||||
| 			case UNTRUSTED: |  | ||||||
| 			case TRUSTED: |  | ||||||
| 			case TRUSTED_X509: |  | ||||||
| 				trustToggle.setChecked(trust.trusted(), false); |  | ||||||
| 				trustToggle.setEnabled(!Config.X509_VERIFICATION || trust != XmppAxolotlSession.Trust.TRUSTED_X509); |  | ||||||
| 				if (Config.X509_VERIFICATION && trust == XmppAxolotlSession.Trust.TRUSTED_X509) { |  | ||||||
| 					trustToggle.setOnClickListener(null); |  | ||||||
| 				} |  | ||||||
| 			key.setTextColor(getPrimaryTextColor()); | 			key.setTextColor(getPrimaryTextColor()); | ||||||
| 			keyType.setTextColor(getSecondaryTextColor()); | 			keyType.setTextColor(getSecondaryTextColor()); | ||||||
| 				break; | 			trustToggle.setOnCheckedChangeListener(onCheckedChangeListener); | ||||||
| 			case UNDECIDED: | 			if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED) { | ||||||
| 				trustToggle.setChecked(false, false); | 				trustToggle.setOnClickListener(onClickListener); | ||||||
| 				trustToggle.setEnabled(false); | 				trustToggle.setEnabled(false); | ||||||
| 				key.setTextColor(getPrimaryTextColor()); | 			} else { | ||||||
| 				keyType.setTextColor(getSecondaryTextColor()); |  | ||||||
| 				break; |  | ||||||
| 			case INACTIVE_UNTRUSTED: |  | ||||||
| 			case INACTIVE_UNDECIDED: |  | ||||||
| 				trustToggle.setOnClickListener(null); | 				trustToggle.setOnClickListener(null); | ||||||
| 				trustToggle.setChecked(false, false); | 				trustToggle.setChecked(status.isTrusted(), false); | ||||||
| 				trustToggle.setEnabled(false); | 				trustToggle.setEnabled(true); | ||||||
| 				key.setTextColor(getTertiaryTextColor()); |  | ||||||
| 				keyType.setTextColor(getTertiaryTextColor()); |  | ||||||
| 				active = false; |  | ||||||
| 				break; |  | ||||||
| 			case INACTIVE_TRUSTED: |  | ||||||
| 			case INACTIVE_TRUSTED_X509: |  | ||||||
| 				trustToggle.setOnClickListener(null); |  | ||||||
| 				trustToggle.setChecked(true, false); |  | ||||||
| 				trustToggle.setEnabled(false); |  | ||||||
| 				key.setTextColor(getTertiaryTextColor()); |  | ||||||
| 				keyType.setTextColor(getTertiaryTextColor()); |  | ||||||
| 				active = false; |  | ||||||
| 				break; |  | ||||||
| 			} | 			} | ||||||
| 
 | 			toast = new View.OnClickListener() { | ||||||
|  | 				@Override | ||||||
|  | 				public void onClick(View v) { | ||||||
|  | 					hideToast(); | ||||||
|  | 				} | ||||||
|  | 			}; | ||||||
|  | 		} else { | ||||||
|  | 			key.setTextColor(getTertiaryTextColor()); | ||||||
|  | 			keyType.setTextColor(getTertiaryTextColor()); | ||||||
|  | 			trustToggle.setOnClickListener(null); | ||||||
|  | 			trustToggle.setEnabled(false); | ||||||
|  | 			trustToggle.setChecked(status.isTrusted(), false); | ||||||
|  | 			toast = new View.OnClickListener() { | ||||||
|  | 				@Override | ||||||
|  | 				public void onClick(View v) { | ||||||
|  | 					replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); | ||||||
|  | 				} | ||||||
|  | 			}; | ||||||
|  | 			trustToggle.setOnClickListener(toast); | ||||||
|  | 		} | ||||||
|  | 		view.setOnClickListener(toast); | ||||||
|  | 		key.setOnClickListener(toast); | ||||||
|  | 		keyType.setOnClickListener(toast); | ||||||
| 		if (showTag) { | 		if (showTag) { | ||||||
| 			keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); | 			keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); | ||||||
| 		} else { | 		} else { | ||||||
| @ -893,27 +884,6 @@ public abstract class XmppActivity extends Activity { | |||||||
| 
 | 
 | ||||||
| 		key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); | 		key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); | ||||||
| 
 | 
 | ||||||
| 		final View.OnClickListener toast; |  | ||||||
| 		if (!active) { |  | ||||||
| 			toast = new View.OnClickListener() { |  | ||||||
| 				@Override |  | ||||||
| 				public void onClick(View v) { |  | ||||||
| 					replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); |  | ||||||
| 				} |  | ||||||
| 			}; |  | ||||||
| 			trustToggle.setOnClickListener(toast); |  | ||||||
| 		} else { |  | ||||||
| 			toast = new View.OnClickListener() { |  | ||||||
| 				@Override |  | ||||||
| 				public void onClick(View v) { |  | ||||||
| 					hideToast(); |  | ||||||
| 				} |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 		view.setOnClickListener(toast); |  | ||||||
| 		key.setOnClickListener(toast); |  | ||||||
| 		keyType.setOnClickListener(toast); |  | ||||||
| 
 |  | ||||||
| 		keys.addView(view); | 		keys.addView(view); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -44,6 +44,7 @@ import java.util.regex.Pattern; | |||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
|  | 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.entities.Conversation; | import eu.siacs.conversations.entities.Conversation; | ||||||
| @ -203,11 +204,11 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie | |||||||
| 			viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_lock_white_18dp : R.drawable.ic_lock_black_18dp); | 			viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_lock_white_18dp : R.drawable.ic_lock_black_18dp); | ||||||
| 			viewHolder.indicator.setVisibility(View.VISIBLE); | 			viewHolder.indicator.setVisibility(View.VISIBLE); | ||||||
| 			if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { | 			if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { | ||||||
| 				XmppAxolotlSession.Trust trust = message.getConversation() | 				FingerprintStatus status = message.getConversation() | ||||||
| 						.getAccount().getAxolotlService().getFingerprintTrust( | 						.getAccount().getAxolotlService().getFingerprintTrust( | ||||||
| 								message.getFingerprint()); | 								message.getFingerprint()); | ||||||
| 
 | 
 | ||||||
| 				if(trust == null || (!trust.trusted() && !trust.trustedInactive())) { | 				if(status == null || (!status.isTrustedAndActive())) { | ||||||
| 					viewHolder.indicator.setColorFilter(activity.getWarningTextColor()); | 					viewHolder.indicator.setColorFilter(activity.getWarningTextColor()); | ||||||
| 					viewHolder.indicator.setAlpha(1.0f); | 					viewHolder.indicator.setAlpha(1.0f); | ||||||
| 				} else { | 				} else { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch