public MessageMessage toXmppMessage(string fromFullJid, ChatTable chat) { MessageMessage msg; switch (type) { case MessageMessage.TYPE_GROUPCHAT: msg = new MessageMessage(fromFullJid, chat.chatJabberId, message, type, fromUser, true); break; default: if (isEncrypted) { msg = new OmemoMessageMessage(fromFullJid, chat.chatJabberId, message, type, true); } else { msg = new MessageMessage(fromFullJid, chat.chatJabberId, message, type, true); } break; } msg.addDelay(date); msg.chatMessageId = id; return(msg); }
public async Task sendOmemoMessageAsync(OmemoMessageMessage msg, string chatJid, string accountJid) { // Check if already trying to build a new session: if (MESSAGE_CACHE.ContainsKey(chatJid)) { MESSAGE_CACHE[chatJid].Item1.Add(msg); } else { // If not start a new session build helper: OmemoSessionBuildHelper sessionHelper = new OmemoSessionBuildHelper(chatJid, accountJid, CONNECTION.account.getFullJid(), CONNECTION, this); MESSAGE_CACHE[chatJid] = new Tuple <List <OmemoMessageMessage>, OmemoSessionBuildHelper>(new List <OmemoMessageMessage>(), sessionHelper); MESSAGE_CACHE[chatJid].Item1.Add(msg); Tuple <OmemoDeviceListSubscriptionState, DateTime> subscription = OMEMO_STORE.LoadDeviceListSubscription(chatJid); OmemoSessionBuildResult result = await sessionHelper.buildSessionAsync(subscription.Item1); if (result.SUCCESS) { OMEMO_SESSIONS[result.SESSION.CHAT_JID] = result.SESSION; await sendAllOutstandingMessagesAsync(result.SESSION); } else { OmemoSessionBuildErrorEventArgs args = new OmemoSessionBuildErrorEventArgs(chatJid, result.ERROR, MESSAGE_CACHE[chatJid]?.Item1 ?? new List <OmemoMessageMessage>()); MESSAGE_CACHE.Remove(chatJid); CONNECTION.OnOmemoSessionBuildError(args); Logger.Error("Failed to build OMEMO session for: " + chatJid + " with: " + result.ERROR); } } }
private async Task SendChatMessageAsync(ChatDataTemplate chat, string message) { MessageMessage toSendMsg; string from = chat.Client.getXMPPAccount().getFullJid(); string to = chat.Chat.chatJabberId; string chatType = chat.Chat.chatType == ChatType.CHAT ? MessageMessage.TYPE_CHAT : MessageMessage.TYPE_GROUPCHAT; bool reciptRequested = true; if (chat.Chat.omemoEnabled) { if (chat.Chat.chatType == ChatType.CHAT) { toSendMsg = new OmemoMessageMessage(from, to, message, chatType, reciptRequested); } else { // ToDo: Add MUC OMEMO support throw new NotImplementedException("Sending encrypted messages for MUC is not supported right now!"); } } else { toSendMsg = chat.Chat.chatType == ChatType.CHAT ? new MessageMessage(from, to, message, chatType, reciptRequested) : new MessageMessage(from, to, message, chatType, chat.MucInfo.nickname, reciptRequested); } // Create a copy for the DB: ChatMessageTable toSendMsgDB = new ChatMessageTable(toSendMsg, chat.Chat) { state = toSendMsg is OmemoMessageMessage ? MessageState.TO_ENCRYPT : MessageState.SENDING }; // Set the chat message id for later identification: toSendMsg.chatMessageId = toSendMsgDB.id; // Update chat last active: chat.Chat.lastActive = DateTime.Now; // Update DB: await Task.Run(() => { ChatDBManager.INSTANCE.setChatMessage(toSendMsgDB, true, false); ChatDBManager.INSTANCE.setChat(chat.Chat, false, true); }); // Send the message: if (toSendMsg is OmemoMessageMessage toSendOmemoMsg) { await chat.Client.sendOmemoMessageAsync(toSendOmemoMsg, chat.Chat.chatJabberId, chat.Client.getXMPPAccount().getBareJid()); } else { await chat.Client.SendAsync(toSendMsg); } }
public void sendOmemoMessage(OmemoMessageMessage msg, string chatJid, string accountJid) { // Check if already trying to build a new session: if (MESSAGE_CACHE.ContainsKey(chatJid)) { MESSAGE_CACHE[chatJid].Item1.Add(msg); } else { // If not start a new session build helper: OmemoDeviceListSubscriptionTable subscriptionTable = OmemoDeviceDBManager.INSTANCE.getDeviceListSubscription(chatJid, accountJid); OmemoSessionBuildHelper sessionHelper = new OmemoSessionBuildHelper(chatJid, accountJid, CONNECTION.account.getIdDomainAndResource(), onSessionBuilderResult, CONNECTION, this); MESSAGE_CACHE[chatJid] = new Tuple <List <OmemoMessageMessage>, OmemoSessionBuildHelper>(new List <OmemoMessageMessage>(), sessionHelper); MESSAGE_CACHE[chatJid].Item1.Add(msg); sessionHelper.start(subscriptionTable.state); } }
public async Task sendOmemoMessageAsync(OmemoMessageMessage msg, string chatJid, string accountJid) { if (connection.omemoHelper is null) { OmemoSessionBuildError?.Invoke(this, new OmemoSessionBuildErrorEventArgs(chatJid, Network.XML.Messages.XEP_0384.Signal.Session.OmemoSessionBuildError.KEY_ERROR, new List <OmemoMessageMessage> { msg })); Logger.Error("Failed to send OMEMO message - OmemoHelper is null"); } else if (!connection.account.checkOmemoKeys()) { OmemoSessionBuildError?.Invoke(this, new OmemoSessionBuildErrorEventArgs(chatJid, Network.XML.Messages.XEP_0384.Signal.Session.OmemoSessionBuildError.KEY_ERROR, new List <OmemoMessageMessage> { msg })); Logger.Error("Failed to send OMEMO message - keys are corrupted"); } else { await connection.omemoHelper.sendOmemoMessageAsync(msg, chatJid, accountJid); } }
private async Task SendChatMessageAsync(ChatTable chat, string message) { AccountTable account = AccountDBManager.INSTANCE.getAccount(chat.userAccountId); if (account is null) { Logger.Warn("Unable to send message - no such account: " + chat.userAccountId); return; } string fromBareJid = account.userId + '@' + account.domain; string fromFullJid = fromBareJid + '/' + account.resource; string to = chat.chatJabberId; string chatType = chat.chatType == ChatType.CHAT ? MessageMessage.TYPE_CHAT : MessageMessage.TYPE_GROUPCHAT; bool reciptRequested = true; MessageMessage toSendMsg; if (chat.omemoEnabled) { if (chat.chatType == ChatType.CHAT) { toSendMsg = new OmemoMessageMessage(fromFullJid, to, message, chatType, reciptRequested); } else { // ToDo: Add MUC OMEMO support throw new NotImplementedException("Sending encrypted messages for MUC is not supported right now!"); } } else if (chat.chatType == ChatType.CHAT) { toSendMsg = new MessageMessage(fromFullJid, to, message, chatType, reciptRequested); } else { MUCChatInfoTable mucInfo = MUCDBManager.INSTANCE.getMUCInfo(chat.id); toSendMsg = new MessageMessage(fromFullJid, to, message, chatType, mucInfo.nickname, reciptRequested); } // Create a copy for the DB: ChatMessageTable toSendMsgDB = new ChatMessageTable(toSendMsg, chat) { state = toSendMsg is OmemoMessageMessage ? MessageState.TO_ENCRYPT : MessageState.SENDING }; // Set the chat message id for later identification: toSendMsg.chatMessageId = toSendMsgDB.id; // Update chat last active: chat.lastActive = DateTime.Now; // Update DB: ChatDBManager.INSTANCE.setChatMessage(toSendMsgDB, true, false); ChatDBManager.INSTANCE.setChat(chat, false, true); Logger.Info("Added to send message in background"); if (isRunning) { XMPPClient client = ConnectionHandler.INSTANCE.getClient(fromBareJid); if (client is null) { Logger.Error("Unable to send message in background - no such client: " + fromBareJid); } // Send the message: else if (toSendMsg is OmemoMessageMessage toSendOmemoMsg) { await client.sendOmemoMessageAsync(toSendOmemoMsg, chat.chatJabberId, client.getXMPPAccount().getBareJid()); } else { await client.SendAsync(toSendMsg); } } else { ToastHelper.showWillBeSendLaterToast(chat); } }
private void sendMessage() { if (!string.IsNullOrWhiteSpace(message_tbx.Text)) { if (IsDummy) { addDummyMessage(message_tbx.Text, Chat.userAccountId, MessageState.SEND); sendDummyMessages++; switch (sendDummyMessages) { case 1: accImg_aiwp.Presence = Presence.Online; break; case 3: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_3_img"), true, 3000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_3"), false, 4000); accImg_aiwp.Presence = Presence.Chat; break; case 4: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_4"), false, 3000); accImg_aiwp.Presence = Presence.Online; break; case 7: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_7"), false, 3000); break; case 11: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_11"), false, 3000); break; case 15: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_15"), false, 3000); accImg_aiwp.Presence = Presence.Xa; break; case 20: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_20"), false, 3000); break; case 30: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_30"), false, 3000); break; case 50: sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_1"), false, 3000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_2"), false, 4000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_3"), false, 5000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_4"), false, 6000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_5"), false, 7000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_6"), false, 8000); sendBotMessage(Localisation.getLocalizedString("chat_details_dummy_answer_50_7"), true, 9000); Task.Run(async() => { await Task.Delay(9000); await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { storeChatState(ChatState.GONE); accImg_aiwp.Presence = Presence.Unavailable; }); }); break; } } else { MessageMessage sendMessage; string messageText = message_tbx.Text; // Remove all tailing whitespaces, tabs and newlines: messageText = messageText.TrimEnd(TRIM_CHARS).TrimStart(TRIM_CHARS); // For MUC messages also pass the nickname: bool toEncrypt = false; if (Chat.chatType == ChatType.MUC && MUCInfo != null) { sendMessage = new MessageMessage(Client.getXMPPAccount().getIdAndDomain(), Chat.chatJabberId, messageText, getChatType(), MUCInfo.nickname, false); } else { if (Chat.omemoEnabled) { sendMessage = new OmemoMessageMessage(Client.getXMPPAccount().getIdAndDomain(), Chat.chatJabberId, messageText, getChatType(), true); toEncrypt = true; } else { sendMessage = new MessageMessage(Client.getXMPPAccount().getIdAndDomain(), Chat.chatJabberId, messageText, getChatType(), true); } } ChatMessageTable sendMessageTable = new ChatMessageTable(sendMessage, Chat) { state = toEncrypt ? MessageState.TO_ENCRYPT : MessageState.SENDING }; // Set chatMessageId: sendMessage.chatMessageId = sendMessageTable.id; // Add message to DB and update chat last active: Chat.lastActive = DateTime.Now; ChatTable chatCpy = Chat; Task.Run(() => { ChatDBManager.INSTANCE.setChatMessage(sendMessageTable, true, false); ChatDBManager.INSTANCE.setChat(chatCpy, false, true); }); if (sendMessage is OmemoMessageMessage omemoMsg) { Client.sendOmemoMessage(omemoMsg, Chat.chatJabberId, Client.getXMPPAccount().getIdAndDomain()); } else { Task t = Client.sendMessageAsync(sendMessage); } } message_tbx.Text = ""; } }
public async void Test_Omemo_Enc_Dec_2() { // Generate Alices keys: IdentityKeyPair aliceIdentKey = CryptoUtils.generateOmemoIdentityKeyPair(); IList <PreKeyRecord> alicePreKeys = CryptoUtils.generateOmemoPreKeys(); SignedPreKeyRecord aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey); // Create Alices stores: InMemoryIdentityKeyStore aliceIdentStore = new InMemoryIdentityKeyStore(aliceIdentKey, ALICE_ADDRESS.getDeviceId()); InMemoryPreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); foreach (PreKeyRecord key in alicePreKeys) { alicePreKeyStore.StorePreKey(key.getId(), key); } InMemorySignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore(); aliceSignedPreKeyStore.StoreSignedPreKey(aliceSignedPreKey.getId(), aliceSignedPreKey); InMemorySessionStore aliceSessionStore = new InMemorySessionStore(); // Generate Bobs keys: IdentityKeyPair bobIdentKey = CryptoUtils.generateOmemoIdentityKeyPair(); IList <PreKeyRecord> bobPreKeys = CryptoUtils.generateOmemoPreKeys(); SignedPreKeyRecord bobSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(bobIdentKey); // Create Bobs stores: InMemoryIdentityKeyStore bobIdentStore = new InMemoryIdentityKeyStore(bobIdentKey, BOB_ADDRESS.getDeviceId()); InMemoryPreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); foreach (PreKeyRecord key in bobPreKeys) { bobPreKeyStore.StorePreKey(key.getId(), key); } InMemorySignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore(); bobSignedPreKeyStore.StoreSignedPreKey(bobSignedPreKey.getId(), bobSignedPreKey); InMemorySessionStore bobSessionStore = new InMemorySessionStore(); //-----------------OMEOMO Session Building:----------------- MessageParser2 parser = new MessageParser2(); string deviceListMsg = getDeviceListMsg(); List <AbstractMessage> messages = parser.parseMessages(ref deviceListMsg); Assert.IsTrue(messages.Count == 1); Assert.IsTrue(messages[0] is OmemoDeviceListResultMessage); OmemoDeviceListResultMessage devList = messages[0] as OmemoDeviceListResultMessage; uint selectedBobDeviceId = devList.DEVICES.getRandomDeviceId(); Assert.IsTrue(selectedBobDeviceId == BOB_ADDRESS.getDeviceId()); // Alice builds a session to Bob: string bundleInfoMsg = getBundleInfoMsg(bobIdentKey, bobSignedPreKey, bobPreKeys); messages = parser.parseMessages(ref bundleInfoMsg); Assert.IsTrue(messages.Count == 1); Assert.IsTrue(messages[0] is OmemoBundleInformationResultMessage); OmemoBundleInformationResultMessage bundleInfo = messages[0] as OmemoBundleInformationResultMessage; Assert.IsTrue(bundleInfo.DEVICE_ID == BOB_ADDRESS.getDeviceId()); SessionBuilder sessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS); PreKeyBundle bobPreKey = bundleInfo.BUNDLE_INFO.getRandomPreKey(bundleInfo.DEVICE_ID); sessionBuilder.process(bobPreKey); // Check if session exists: Assert.IsTrue(aliceSessionStore.ContainsSession(BOB_ADDRESS)); Assert.IsTrue(aliceSessionStore.LoadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); // Alice sends a message: string aliceOrigMsg = "$(rm -rvf .)"; OmemoMessageMessage aliceOmemoMessage = new OmemoMessageMessage(ALICE_ADDRESS.getName() + "/SOME_RESOURCE", BOB_ADDRESS.getName(), aliceOrigMsg, MessageMessage.TYPE_CHAT, true); Assert.IsFalse(aliceOmemoMessage.ENCRYPTED); OmemoSession omemoSession = new OmemoSession(BOB_ADDRESS.getName()); SessionCipher aliceSessionCipher = new SessionCipher(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS); omemoSession.DEVICE_SESSIONS_REMOTE.Add(BOB_ADDRESS.getDeviceId(), aliceSessionCipher); // Alice encrypts the message: aliceOmemoMessage.encrypt(omemoSession, ALICE_ADDRESS.getDeviceId()); Assert.IsTrue(aliceOmemoMessage.ENCRYPTED); string aliceOmemoMsgText = aliceOmemoMessage.toXmlString(); // Bob receives the message from Alice: messages = parser.parseMessages(ref aliceOmemoMsgText); Assert.IsTrue(messages.Count == 1); Assert.IsTrue(messages[0] is OmemoMessageMessage); OmemoMessageMessage bobOmemoMessage = messages[0] as OmemoMessageMessage; Assert.IsTrue(bobOmemoMessage.ENCRYPTED); Assert.AreEqual(bobOmemoMessage.SOURCE_DEVICE_ID, aliceOmemoMessage.SOURCE_DEVICE_ID); Assert.AreEqual(bobOmemoMessage.BASE_64_IV, aliceOmemoMessage.BASE_64_IV); Assert.AreEqual(bobOmemoMessage.BASE_64_PAYLOAD, aliceOmemoMessage.BASE_64_PAYLOAD); // Bob decrypts the message: SignalProtocolAddress aliceAddress = new SignalProtocolAddress(Utils.getBareJidFromFullJid(bobOmemoMessage.getFrom()), bobOmemoMessage.SOURCE_DEVICE_ID); SessionCipher bobSessionCipher = new SessionCipher(bobSessionStore, bobPreKeyStore, bobSignedPreKeyStore, bobIdentStore, aliceAddress); await bobOmemoMessage.decryptAsync(bobSessionCipher, aliceAddress, BOB_ADDRESS.getDeviceId(), null); Assert.IsFalse(bobOmemoMessage.ENCRYPTED); Assert.AreEqual(aliceOrigMsg, bobOmemoMessage.MESSAGE); }
public void TestOmemoMessageMessage_1() { OmemoMessageMessage msg = new OmemoMessageMessage("from", "to", "TestMessage", "chat", true); }
public void sendOmemoMessage(OmemoMessageMessage msg, string chatJid, string accountJid) { connection.OMEMO_HELPER.sendOmemoMessage(msg, chatJid, accountJid); }