parse omemo fingerprints from uris
This commit is contained in:
		
							parent
							
								
									3f3b360eee
								
							
						
					
					
						commit
						7e2e42cb11
					
				| @ -98,6 +98,10 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public void preVerifyFingerprint(Contact contact, String fingerprint) { | ||||||
|  | 		axolotlStore.preVerifyFingerprint(contact.getAccount(), contact.getJid().toBareJid().toPreppedString(), fingerprint); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private static class AxolotlAddressMap<T> { | 	private static class AxolotlAddressMap<T> { | ||||||
| 		protected Map<String, Map<Integer, T>> map; | 		protected Map<String, Map<Integer, T>> map; | ||||||
| 		protected final Object MAP_LOCK = new Object(); | 		protected final Object MAP_LOCK = new Object(); | ||||||
| @ -200,7 +204,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		public void put(AxolotlAddress address, XmppAxolotlSession value) { | 		public void put(AxolotlAddress address, XmppAxolotlSession value) { | ||||||
| 			super.put(address, value); | 			super.put(address, value); | ||||||
| 			value.setNotFresh(); | 			value.setNotFresh(); | ||||||
| 			xmppConnectionService.syncRosterToDisk(account); | 			xmppConnectionService.syncRosterToDisk(account); //TODO why? | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public void put(XmppAxolotlSession session) { | 		public void put(XmppAxolotlSession session) { | ||||||
| @ -417,7 +421,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void purgeKey(final String fingerprint) { | 	public void purgeKey(final String fingerprint) { | ||||||
| 		axolotlStore.setFingerprintTrust(fingerprint.replaceAll("\\s", ""), FingerprintStatus.createCompromised()); | 		axolotlStore.setFingerprintStatus(fingerprint.replaceAll("\\s", ""), FingerprintStatus.createCompromised()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void publishOwnDeviceIdIfNeeded() { | 	public void publishOwnDeviceIdIfNeeded() { | ||||||
| @ -690,7 +694,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setFingerprintTrust(String fingerprint, FingerprintStatus status) { | 	public void setFingerprintTrust(String fingerprint, FingerprintStatus status) { | ||||||
| 		axolotlStore.setFingerprintTrust(fingerprint, status); | 		axolotlStore.setFingerprintStatus(fingerprint, status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void verifySessionWithPEP(final XmppAxolotlSession session) { | 	private void verifySessionWithPEP(final XmppAxolotlSession session) { | ||||||
| @ -749,14 +753,15 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 
 | 
 | ||||||
| 	private void finishBuildingSessionsFromPEP(final AxolotlAddress address) { | 	private void finishBuildingSessionsFromPEP(final AxolotlAddress address) { | ||||||
| 		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), 0); | 		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), 0); | ||||||
| 		if (!fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING) | 		Map<Integer, FetchStatus> own = fetchStatusMap.getAll(ownAddress); | ||||||
| 				&& !fetchStatusMap.getAll(address).containsValue(FetchStatus.PENDING)) { | 		Map<Integer, FetchStatus> remote = fetchStatusMap.getAll(address); | ||||||
|  | 		if (!own.containsValue(FetchStatus.PENDING) && !remote.containsValue(FetchStatus.PENDING)) { | ||||||
| 			FetchStatus report = null; | 			FetchStatus report = null; | ||||||
| 			if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.SUCCESS_VERIFIED) | 			if (own.containsValue(FetchStatus.SUCCESS) || remote.containsValue(FetchStatus.SUCCESS)) { | ||||||
| 					| fetchStatusMap.getAll(address).containsValue(FetchStatus.SUCCESS_VERIFIED)) { | 				report = FetchStatus.SUCCESS; | ||||||
|  | 			} else if (own.containsValue(FetchStatus.SUCCESS_VERIFIED) || remote.containsValue(FetchStatus.SUCCESS_VERIFIED)) { | ||||||
| 				report = FetchStatus.SUCCESS_VERIFIED; | 				report = FetchStatus.SUCCESS_VERIFIED; | ||||||
| 			} else if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.ERROR) | 			} else if (own.containsValue(FetchStatus.ERROR) || remote.containsValue(FetchStatus.ERROR)) { | ||||||
| 					|| fetchStatusMap.getAll(address).containsValue(FetchStatus.ERROR)) { |  | ||||||
| 				report = FetchStatus.ERROR; | 				report = FetchStatus.ERROR; | ||||||
| 			} | 			} | ||||||
| 			mXmppConnectionService.keyStatusUpdated(report); | 			mXmppConnectionService.keyStatusUpdated(report); | ||||||
| @ -812,7 +817,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 							if (Config.X509_VERIFICATION) { | 							if (Config.X509_VERIFICATION) { | ||||||
| 								verifySessionWithPEP(session); | 								verifySessionWithPEP(session); | ||||||
| 							} else { | 							} else { | ||||||
| 								fetchStatusMap.put(address, FetchStatus.SUCCESS); | 								FingerprintStatus status = getFingerprintTrust(bundle.getIdentityKey().getFingerprint().replaceAll("\\s","")); | ||||||
|  | 								boolean verified = status != null && status.isVerified(); | ||||||
|  | 								fetchStatusMap.put(address, verified ? FetchStatus.SUCCESS_VERIFIED : FetchStatus.SUCCESS); | ||||||
| 								finishBuildingSessionsFromPEP(address); | 								finishBuildingSessionsFromPEP(address); | ||||||
| 							} | 							} | ||||||
| 						} catch (UntrustedIdentityException | InvalidKeyException e) { | 						} catch (UntrustedIdentityException | InvalidKeyException e) { | ||||||
|  | |||||||
| @ -114,6 +114,20 @@ public class FingerprintStatus { | |||||||
|         return status; |         return status; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public FingerprintStatus toVerified() { | ||||||
|  |         FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.active = active; | ||||||
|  |         status.trust = Trust.VERIFIED; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FingerprintStatus createInactiveVerified() { | ||||||
|  |         final FingerprintStatus status = new FingerprintStatus(); | ||||||
|  |         status.trust = Trust.VERIFIED; | ||||||
|  |         status.active = false; | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public enum Trust { |     public enum Trust { | ||||||
|         COMPROMISED, |         COMPROMISED, | ||||||
|         UNDECIDED, |         UNDECIDED, | ||||||
|  | |||||||
| @ -187,7 +187,15 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 	@Override | 	@Override | ||||||
| 	public void saveIdentity(String name, IdentityKey identityKey) { | 	public void saveIdentity(String name, IdentityKey identityKey) { | ||||||
| 		if (!mXmppConnectionService.databaseBackend.loadIdentityKeys(account, name).contains(identityKey)) { | 		if (!mXmppConnectionService.databaseBackend.loadIdentityKeys(account, name).contains(identityKey)) { | ||||||
| 			mXmppConnectionService.databaseBackend.storeIdentityKey(account, name, identityKey); | 			String fingerprint = identityKey.getFingerprint().replaceAll("\\s", ""); | ||||||
|  | 			FingerprintStatus status = getFingerprintStatus(fingerprint); | ||||||
|  | 			if (status == null) { | ||||||
|  | 				status = FingerprintStatus.createActiveUndecided(); //default for new keys | ||||||
|  | 			} else { | ||||||
|  | 				status = status.toActive(); | ||||||
|  | 			} | ||||||
|  | 			mXmppConnectionService.databaseBackend.storeIdentityKey(account, name, identityKey, status); | ||||||
|  | 			trustCache.remove(fingerprint); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -214,7 +222,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 		return (fingerprint == null)? null : trustCache.get(fingerprint); | 		return (fingerprint == null)? null : trustCache.get(fingerprint); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setFingerprintTrust(String fingerprint, FingerprintStatus status) { | 	public void setFingerprintStatus(String fingerprint, FingerprintStatus status) { | ||||||
| 		mXmppConnectionService.databaseBackend.setIdentityKeyTrust(account, fingerprint, status); | 		mXmppConnectionService.databaseBackend.setIdentityKeyTrust(account, fingerprint, status); | ||||||
| 		trustCache.remove(fingerprint); | 		trustCache.remove(fingerprint); | ||||||
| 	} | 	} | ||||||
| @ -430,4 +438,8 @@ public class SQLiteAxolotlStore implements AxolotlStore { | |||||||
| 	public void removeSignedPreKey(int signedPreKeyId) { | 	public void removeSignedPreKey(int signedPreKeyId) { | ||||||
| 		mXmppConnectionService.databaseBackend.deleteSignedPreKey(account, signedPreKeyId); | 		mXmppConnectionService.databaseBackend.deleteSignedPreKey(account, signedPreKeyId); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	public void preVerifyFingerprint(Account account, String name, String fingerprint) { | ||||||
|  | 		mXmppConnectionService.databaseBackend.storePreVerification(account,name,fingerprint,FingerprintStatus.createInactiveVerified()); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -73,7 +73,7 @@ public class XmppAxolotlSession { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	protected void setTrust(FingerprintStatus status) { | 	protected void setTrust(FingerprintStatus status) { | ||||||
| 		sqLiteAxolotlStore.setFingerprintTrust(getFingerprint(), status); | 		sqLiteAxolotlStore.setFingerprintStatus(getFingerprint(), status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	protected FingerprintStatus getTrust() { | 	protected FingerprintStatus getTrust() { | ||||||
|  | |||||||
| @ -1106,7 +1106,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			try { | 			try { | ||||||
| 				identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT), 0)); | 				String key = cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)); | ||||||
|  | 				if (key != null) { | ||||||
|  | 					identityKeys.add(new IdentityKey(Base64.decode(key, Base64.DEFAULT), 0)); | ||||||
|  | 				} else { | ||||||
|  | 					Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Missing key (possibly preverified) in database for account" + account.getJid().toBareJid() + ", address: " + name); | ||||||
|  | 				} | ||||||
| 			} catch (InvalidKeyException e) { | 			} catch (InvalidKeyException e) { | ||||||
| 				Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); | 				Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); | ||||||
| 			} | 			} | ||||||
| @ -1134,10 +1139,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { |  | ||||||
| 		storeIdentityKey(account, name, own, fingerprint, base64Serialized, FingerprintStatus.createActiveUndecided()); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, FingerprintStatus status) { | 	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(); | ||||||
| @ -1147,6 +1148,22 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		values.put(SQLiteAxolotlStore.FINGERPRINT, fingerprint); | 		values.put(SQLiteAxolotlStore.FINGERPRINT, fingerprint); | ||||||
| 		values.put(SQLiteAxolotlStore.KEY, base64Serialized); | 		values.put(SQLiteAxolotlStore.KEY, base64Serialized); | ||||||
| 		values.putAll(status.toContentValues()); | 		values.putAll(status.toContentValues()); | ||||||
|  | 		String where = SQLiteAxolotlStore.ACCOUNT+"=? AND "+SQLiteAxolotlStore.NAME+"=? AND "+SQLiteAxolotlStore.FINGERPRINT+" =?"; | ||||||
|  | 		String[] whereArgs = {account.getUuid(),name,fingerprint}; | ||||||
|  | 		int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME,values,where,whereArgs); | ||||||
|  | 		if (rows == 0) { | ||||||
|  | 			db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void storePreVerification(Account account, String name, String fingerprint, FingerprintStatus status) { | ||||||
|  | 		SQLiteDatabase db = this.getWritableDatabase(); | ||||||
|  | 		ContentValues values = new ContentValues(); | ||||||
|  | 		values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); | ||||||
|  | 		values.put(SQLiteAxolotlStore.NAME, name); | ||||||
|  | 		values.put(SQLiteAxolotlStore.OWN, 0); | ||||||
|  | 		values.put(SQLiteAxolotlStore.FINGERPRINT, fingerprint); | ||||||
|  | 		values.putAll(status.toContentValues()); | ||||||
| 		db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); | 		db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -1227,8 +1244,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void storeIdentityKey(Account account, String name, IdentityKey identityKey) { | 	public void storeIdentityKey(Account account, String name, IdentityKey identityKey, FingerprintStatus status) { | ||||||
| 		storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); | 		storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT), status); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void storeOwnIdentityKeyPair(Account account, IdentityKeyPair identityKeyPair) { | 	public void storeOwnIdentityKeyPair(Account account, IdentityKeyPair identityKeyPair) { | ||||||
|  | |||||||
| @ -65,6 +65,7 @@ import eu.siacs.conversations.R; | |||||||
| import eu.siacs.conversations.crypto.PgpDecryptionService; | import eu.siacs.conversations.crypto.PgpDecryptionService; | ||||||
| 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.XmppAxolotlMessage; | import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage; | ||||||
| import eu.siacs.conversations.entities.Account; | import eu.siacs.conversations.entities.Account; | ||||||
| import eu.siacs.conversations.entities.Blockable; | import eu.siacs.conversations.entities.Blockable; | ||||||
| @ -102,6 +103,7 @@ import eu.siacs.conversations.utils.PhoneHelper; | |||||||
| import eu.siacs.conversations.utils.ReplacingSerialSingleThreadExecutor; | import eu.siacs.conversations.utils.ReplacingSerialSingleThreadExecutor; | ||||||
| import eu.siacs.conversations.utils.SerialSingleThreadExecutor; | import eu.siacs.conversations.utils.SerialSingleThreadExecutor; | ||||||
| import eu.siacs.conversations.utils.Xmlns; | import eu.siacs.conversations.utils.Xmlns; | ||||||
|  | import eu.siacs.conversations.utils.XmppUri; | ||||||
| import eu.siacs.conversations.xml.Element; | import eu.siacs.conversations.xml.Element; | ||||||
| import eu.siacs.conversations.xmpp.OnBindListener; | import eu.siacs.conversations.xmpp.OnBindListener; | ||||||
| import eu.siacs.conversations.xmpp.OnContactStatusChanged; | import eu.siacs.conversations.xmpp.OnContactStatusChanged; | ||||||
| @ -3608,6 +3610,29 @@ public class XmppConnectionService extends Service { | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public void verifyFingerprints(Contact contact, List<XmppUri.Fingerprint> fingerprints) { | ||||||
|  | 		boolean needsRosterWrite = false; | ||||||
|  | 		final AxolotlService axolotlService = contact.getAccount().getAxolotlService(); | ||||||
|  | 		for(XmppUri.Fingerprint fp : fingerprints) { | ||||||
|  | 			if (fp.type == XmppUri.FingerprintType.OTR) { | ||||||
|  | 				needsRosterWrite |= contact.addOtrFingerprint(fp.fingerprint); | ||||||
|  | 			} else if (fp.type == XmppUri.FingerprintType.OMEMO) { | ||||||
|  | 				String fingerprint = "05"+fp.fingerprint.replaceAll("\\s",""); | ||||||
|  | 				FingerprintStatus fingerprintStatus = axolotlService.getFingerprintTrust(fingerprint); | ||||||
|  | 				if (fingerprintStatus != null) { | ||||||
|  | 					if (!fingerprintStatus.isVerified()) { | ||||||
|  | 						axolotlService.setFingerprintTrust(fingerprint,fingerprintStatus.toVerified()); | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					axolotlService.preVerifyFingerprint(contact,fingerprint); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if (needsRosterWrite) { | ||||||
|  | 			syncRosterToDisk(contact.getAccount()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public interface OnMamPreferencesFetched { | 	public interface OnMamPreferencesFetched { | ||||||
| 		void onPreferencesFetched(Element prefs); | 		void onPreferencesFetched(Element prefs); | ||||||
| 		void onPreferencesFetchFailed(); | 		void onPreferencesFetchFailed(); | ||||||
|  | |||||||
| @ -397,11 +397,11 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @SuppressLint("InflateParams") |     @SuppressLint("InflateParams") | ||||||
|     protected void showCreateContactDialog(final String prefilledJid, final String fingerprint) { |     protected void showCreateContactDialog(final String prefilledJid, final Invite invite) { | ||||||
|         EnterJidDialog dialog = new EnterJidDialog( |         EnterJidDialog dialog = new EnterJidDialog( | ||||||
|                 this, mKnownHosts, mActivatedAccounts, |                 this, mKnownHosts, mActivatedAccounts, | ||||||
|                 getString(R.string.create_contact), getString(R.string.create), |                 getString(R.string.create_contact), getString(R.string.create), | ||||||
|                 prefilledJid, null, fingerprint == null |                 prefilledJid, null, !invite.hasFingerprints() | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         dialog.setOnEnterJidDialogPositiveListener(new EnterJidDialog.OnEnterJidDialogPositiveListener() { |         dialog.setOnEnterJidDialogPositiveListener(new EnterJidDialog.OnEnterJidDialogPositiveListener() { | ||||||
| @ -420,7 +420,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU | |||||||
|                 if (contact.showInRoster()) { |                 if (contact.showInRoster()) { | ||||||
|                     throw new EnterJidDialog.JidError(getString(R.string.contact_already_exists)); |                     throw new EnterJidDialog.JidError(getString(R.string.contact_already_exists)); | ||||||
|                 } else { |                 } else { | ||||||
|                     contact.addOtrFingerprint(fingerprint); |                     //contact.addOtrFingerprint(fingerprint); | ||||||
|                     xmppConnectionService.createContact(contact); |                     xmppConnectionService.createContact(contact); | ||||||
|                     switchToConversation(contact); |                     switchToConversation(contact); | ||||||
|                     return true; |                     return true; | ||||||
| @ -842,6 +842,10 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private boolean handleJid(Invite invite) { |     private boolean handleJid(Invite invite) { | ||||||
|  |         Log.d(Config.LOGTAG,"handling invite for "+invite.getJid()); | ||||||
|  |         for(XmppUri.Fingerprint fp : invite.getFingerprints()) { | ||||||
|  |             Log.d(Config.LOGTAG,fp.toString()); | ||||||
|  |         } | ||||||
|         List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid()); |         List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid()); | ||||||
|         if (invite.isMuc()) { |         if (invite.isMuc()) { | ||||||
|             Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid()); |             Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid()); | ||||||
| @ -853,16 +857,19 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU | |||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } else if (contacts.size() == 0) { |         } else if (contacts.size() == 0) { | ||||||
|             showCreateContactDialog(invite.getJid().toString(), invite.getFingerprint()); |             showCreateContactDialog(invite.getJid().toString(), invite); | ||||||
|             return false; |             return false; | ||||||
|         } else if (contacts.size() == 1) { |         } else if (contacts.size() == 1) { | ||||||
|             Contact contact = contacts.get(0); |             Contact contact = contacts.get(0); | ||||||
|             if (invite.getFingerprint() != null) { |             if (invite.hasFingerprints()) { | ||||||
|  |                 xmppConnectionService.verifyFingerprints(contact,invite.getFingerprints()); | ||||||
|  |             } | ||||||
|  |             /*if (invite.getFingerprint() != null) { | ||||||
|                 if (contact.addOtrFingerprint(invite.getFingerprint())) { |                 if (contact.addOtrFingerprint(invite.getFingerprint())) { | ||||||
|                     Log.d(Config.LOGTAG, "added new fingerprint"); |                     Log.d(Config.LOGTAG, "added new fingerprint"); | ||||||
|                     xmppConnectionService.syncRosterToDisk(contact.getAccount()); |                     xmppConnectionService.syncRosterToDisk(contact.getAccount()); | ||||||
|                 } |                 } | ||||||
|             } |             }*/ | ||||||
|             switchToConversation(contact); |             switchToConversation(contact); | ||||||
|             return true; |             return true; | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ import java.util.List; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| 
 | 
 | ||||||
|  | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.OmemoActivity; | import eu.siacs.conversations.OmemoActivity; | ||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
| import eu.siacs.conversations.crypto.axolotl.AxolotlService; | import eu.siacs.conversations.crypto.axolotl.AxolotlService; | ||||||
| @ -245,7 +246,9 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat | |||||||
| 							Toast.makeText(TrustKeysActivity.this,R.string.error_fetching_omemo_key,Toast.LENGTH_SHORT).show(); | 							Toast.makeText(TrustKeysActivity.this,R.string.error_fetching_omemo_key,Toast.LENGTH_SHORT).show(); | ||||||
| 							break; | 							break; | ||||||
| 						case SUCCESS_VERIFIED: | 						case SUCCESS_VERIFIED: | ||||||
| 							Toast.makeText(TrustKeysActivity.this,R.string.verified_omemo_key_with_certificate,Toast.LENGTH_LONG).show(); | 							Toast.makeText(TrustKeysActivity.this, | ||||||
|  | 									Config.X509_VERIFICATION ? R.string.verified_omemo_key_with_certificate : R.string.all_omemo_keys_have_been_verified, | ||||||
|  | 									Toast.LENGTH_LONG).show(); | ||||||
| 							break; | 							break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | |||||||
| @ -173,11 +173,10 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer | |||||||
| 
 | 
 | ||||||
| 	protected boolean verifyWithUri(XmppUri uri) { | 	protected boolean verifyWithUri(XmppUri uri) { | ||||||
| 		Contact contact = mConversation.getContact(); | 		Contact contact = mConversation.getContact(); | ||||||
| 		if (this.mConversation.getContact().getJid().equals(uri.getJid()) && uri.getFingerprint() != null) { | 		if (this.mConversation.getContact().getJid().equals(uri.getJid()) && uri.hasFingerprints()) { | ||||||
| 			contact.addOtrFingerprint(uri.getFingerprint()); | 			xmppConnectionService.verifyFingerprints(contact,uri.getFingerprints()); | ||||||
| 			Toast.makeText(this,R.string.verified,Toast.LENGTH_SHORT).show(); | 			Toast.makeText(this,R.string.verified,Toast.LENGTH_SHORT).show(); | ||||||
| 			updateView(); | 			updateView(); | ||||||
| 			xmppConnectionService.syncRosterToDisk(contact.getAccount()); |  | ||||||
| 			return true; | 			return true; | ||||||
| 		} else { | 		} else { | ||||||
| 			Toast.makeText(this,R.string.could_not_verify_fingerprint,Toast.LENGTH_SHORT).show(); | 			Toast.makeText(this,R.string.could_not_verify_fingerprint,Toast.LENGTH_SHORT).show(); | ||||||
|  | |||||||
| @ -4,7 +4,9 @@ import android.net.Uri; | |||||||
| 
 | 
 | ||||||
| import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||||
| import java.net.URLDecoder; | import java.net.URLDecoder; | ||||||
|  | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Locale; | ||||||
| 
 | 
 | ||||||
| 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; | ||||||
| @ -13,7 +15,9 @@ public class XmppUri { | |||||||
| 
 | 
 | ||||||
| 	protected String jid; | 	protected String jid; | ||||||
| 	protected boolean muc; | 	protected boolean muc; | ||||||
| 	protected String fingerprint; | 	protected List<Fingerprint> fingerprints = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 	private static final String OMEMO_URI_PARAM = "omemo-sid-"; | ||||||
| 
 | 
 | ||||||
| 	public XmppUri(String uri) { | 	public XmppUri(String uri) { | ||||||
| 		try { | 		try { | ||||||
| @ -56,7 +60,7 @@ public class XmppUri { | |||||||
| 			} else { | 			} else { | ||||||
| 				jid = uri.getSchemeSpecificPart().split("\\?")[0]; | 				jid = uri.getSchemeSpecificPart().split("\\?")[0]; | ||||||
| 			} | 			} | ||||||
| 			fingerprint = parseFingerprint(uri.getQuery()); | 			this.fingerprints = parseFingerprints(uri.getQuery()); | ||||||
| 		} else if ("imto".equalsIgnoreCase(scheme)) { | 		} else if ("imto".equalsIgnoreCase(scheme)) { | ||||||
| 			// sample: imto://xmpp/foo@bar.com | 			// sample: imto://xmpp/foo@bar.com | ||||||
| 			try { | 			try { | ||||||
| @ -73,18 +77,28 @@ public class XmppUri { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	protected  String parseFingerprint(String query) { | 	protected List<Fingerprint> parseFingerprints(String query) { | ||||||
| 		if (query == null) { | 		List<Fingerprint> fingerprints = new ArrayList<>(); | ||||||
| 			return null; | 		String[] pairs = query == null ? new String[0] : query.split(";"); | ||||||
| 		} else { | 		for(String pair : pairs) { | ||||||
| 			final String NEEDLE = "otr-fingerprint="; | 			String[] parts = pair.split("=",2); | ||||||
| 			int index = query.indexOf(NEEDLE); | 			if (parts.length == 2) { | ||||||
| 			if (index >= 0 && query.length() >= (NEEDLE.length() + index + 40)) { | 				String key = parts[0].toLowerCase(Locale.US); | ||||||
| 				return query.substring(index + NEEDLE.length(), index + NEEDLE.length() + 40); | 				String value = parts[1]; | ||||||
| 			} else { | 				if ("otr-fingerprint".equals(key)) { | ||||||
| 				return null; | 					fingerprints.add(new Fingerprint(FingerprintType.OTR,value)); | ||||||
|  | 				} | ||||||
|  | 				if (key.startsWith(OMEMO_URI_PARAM)) { | ||||||
|  | 					try { | ||||||
|  | 						int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length())); | ||||||
|  | 						fingerprints.add(new Fingerprint(FingerprintType.OMEMO,value,id)); | ||||||
|  | 					} catch (Exception e) { | ||||||
|  | 						//ignoring invalid device id | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		return fingerprints; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public Jid getJid() { | 	public Jid getJid() { | ||||||
| @ -95,7 +109,36 @@ public class XmppUri { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public String getFingerprint() { | 	public List<Fingerprint> getFingerprints() { | ||||||
| 		return this.fingerprint; | 		return this.fingerprints; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public boolean hasFingerprints() { | ||||||
|  | 		return fingerprints.size() > 0; | ||||||
|  | 	} | ||||||
|  | 	public enum FingerprintType { | ||||||
|  | 		OMEMO, | ||||||
|  | 		OTR | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public static class Fingerprint { | ||||||
|  | 		public final FingerprintType type; | ||||||
|  | 		public final String fingerprint; | ||||||
|  | 		public final int deviceId; | ||||||
|  | 
 | ||||||
|  | 		public Fingerprint(FingerprintType type, String fingerprint) { | ||||||
|  | 			this(type, fingerprint, 0); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public Fingerprint(FingerprintType type, String fingerprint, int deviceId) { | ||||||
|  | 			this.type = type; | ||||||
|  | 			this.fingerprint = fingerprint; | ||||||
|  | 			this.deviceId = deviceId; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Override | ||||||
|  | 		public String toString() { | ||||||
|  | 			return type.toString()+": "+fingerprint+(deviceId != 0 ? " "+String.valueOf(deviceId) : ""); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -702,4 +702,5 @@ | |||||||
| 	<string name="error_unable_to_create_temporary_file">Unable to create temporary file</string> | 	<string name="error_unable_to_create_temporary_file">Unable to create temporary file</string> | ||||||
| 	<string name="this_device_has_been_verified">This device has been verified</string> | 	<string name="this_device_has_been_verified">This device has been verified</string> | ||||||
| 	<string name="copy_fingerprint">Copy fingerprint</string> | 	<string name="copy_fingerprint">Copy fingerprint</string> | ||||||
|  | 	<string name="all_omemo_keys_have_been_verified">All OMEMO keys have been verified</string> | ||||||
| </resources> | </resources> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch