private async Task buildSessionForDevicesAsync(Dictionary <uint, SessionCipher> sessions, IList <SignalProtocolAddress> devices) { if (devices.Count <= 0) { return; } SignalProtocolAddress device = devices[0]; devices.RemoveAt(0); // Check if there exists already a session for this device: if (OMEMO_HELPER.OMEMO_STORE.ContainsSession(device)) { // If yes, the load it: SessionCipher cipher = OMEMO_HELPER.loadCipher(device); sessions.Add(device.getDeviceId(), cipher); Logger.Info("[OmemoSessionBuildHelper] Session for " + device.ToString() + " loaded from cache."); } else { // Else try to build a new one by requesting the devices bundle information: OmemoBundleInformationResultMessage bundleMsg = await requestBundleInformationAsync(device); if (!(bundleMsg is null)) { SignalProtocolAddress address = OMEMO_HELPER.newSession(CHAT_JID, bundleMsg); SessionCipher cipher = OMEMO_HELPER.loadCipher(address); sessions.Add(device.getDeviceId(), cipher); Logger.Info("[OmemoSessionBuildHelper] Session with " + device.ToString() + " established."); }
private bool onRequestBundleInformationMessage(IQMessage msg) { if (STATE != OmemoSessionBuildHelperState.REQUESTING_BUNDLE_INFORMATION) { return(true); } if (msg is OmemoBundleInformationResultMessage bundleMsg) { Logger.Info("[OmemoSessionBuildHelper] Session with " + curAddress.getName() + ':' + curAddress.getDeviceId() + " established."); SignalProtocolAddress address = OMEMO_HELPER.newSession(CHAT_JID, bundleMsg); SessionCipher cipher = OMEMO_HELPER.loadCipher(address); SESSION.DEVICE_SESSIONS.Add(curAddress.getDeviceId(), cipher); createSessionForNextDevice(); return(true); } else if (msg is IQErrorMessage errMsg) { if (errMsg.ERROR_OBJ.ERROR_NAME == ErrorName.ITEM_NOT_FOUND) { Logger.Error("[OmemoSessionBuildHelper] Failed to establish session - " + curAddress.getName() + ':' + curAddress.getDeviceId() + " doesn't support OMEMO: " + errMsg.ERROR_OBJ.ToString()); setState(OmemoSessionBuildHelperState.ERROR); ON_SESSION_RESULT(this, new OmemoSessionBuildResult(OmemoSessionBuildError.TARGET_DOES_NOT_SUPPORT_OMEMO)); } else { Logger.Error("[OmemoSessionBuildHelper] Failed to establish session - request bundle info failed(" + curAddress.getName() + ':' + curAddress.getDeviceId() + "): " + errMsg.ERROR_OBJ.ToString()); setState(OmemoSessionBuildHelperState.ERROR); ON_SESSION_RESULT(this, new OmemoSessionBuildResult(OmemoSessionBuildError.REQUEST_BUNDLE_INFORMATION_IQ_ERROR)); } return(true); } return(false); }
private async Task buildSessionForDevicesAsync(Dictionary <uint, SessionCipher> sessions, IList <SignalProtocolAddress> devices) { if (devices.Count <= 0) { return; } SignalProtocolAddress device = devices[0]; devices.RemoveAt(0); // Validate the device fingerprint: OmemoFingerprint fingerprint = OMEMO_HELPER.OMEMO_STORE.LoadFingerprint(device); if (!(fingerprint is null) && !OMEMO_HELPER.OMEMO_STORE.IsFingerprintTrusted(fingerprint)) { Logger.Warn("[OmemoSessionBuildHelper] Not building a session with " + device.ToString() + " - key not trusted."); await buildSessionForDevicesAsync(sessions, devices); return; } // Check if there exists already a session for this device: if (OMEMO_HELPER.OMEMO_STORE.ContainsSession(device)) { // If yes, the load it: SessionCipher cipher = OMEMO_HELPER.loadCipher(device); sessions.Add(device.getDeviceId(), cipher); Logger.Info("[OmemoSessionBuildHelper] Session for " + device.ToString() + " loaded from cache."); } else { // Else try to build a new one by requesting the devices bundle information: OmemoBundleInformationResultMessage bundleMsg = await requestBundleInformationAsync(device); if (!(bundleMsg is null)) { OMEMO_HELPER.newSession(device.getName(), bundleMsg); // Validate fingerprints: if (fingerprint is null) { fingerprint = new OmemoFingerprint(bundleMsg.BUNDLE_INFO.PUBLIC_IDENTITY_KEY, device); OMEMO_HELPER.OMEMO_STORE.StoreFingerprint(fingerprint); } else { OmemoFingerprint receivedFingerprint = new OmemoFingerprint(bundleMsg.BUNDLE_INFO.PUBLIC_IDENTITY_KEY, device); // Make sure the fingerprint did not change or somebody is doing an attack: if (!fingerprint.checkIdentityKey(receivedFingerprint.IDENTITY_PUB_KEY)) { Logger.Warn("[OmemoSessionBuildHelper] Unable to establish session with " + device.ToString() + " - other fingerprint received than stored locally."); await buildSessionForDevicesAsync(sessions, devices); return; } } // Check if the fingerprint is trusted: if (OMEMO_HELPER.OMEMO_STORE.IsFingerprintTrusted(fingerprint)) { SessionCipher cipher = OMEMO_HELPER.loadCipher(device); sessions.Add(device.getDeviceId(), cipher); Logger.Info("[OmemoSessionBuildHelper] Session with " + device.ToString() + " established."); } else { Logger.Warn("[OmemoSessionBuildHelper] Unable to establish session with " + device.ToString() + " - key not trusted."); } }