diff options
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/crypto')
4 files changed, 145 insertions, 1 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlMessageParser.java b/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlMessageParser.java new file mode 100644 index 00000000..d77db0d4 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlMessageParser.java @@ -0,0 +1,37 @@ +package de.thedevstack.conversationsplus.crypto.axolotl; + +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.Config; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; + +/** + */ +public class AxolotlMessageParser { + public static Message parseAxolotlChat(Element axolotlMessage, Jid counterpart, Jid from, Conversation conversation) { + Jid origin; + if (conversation.getMode() == Conversation.MODE_MULTI) { + origin = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart()); + if (origin == null) { + Logging.d(Config.LOGTAG,"axolotl message in non anonymous conference received"); + return null; + } + } else { + origin = from; + } + + Message finishedMessage = null; + AxolotlService service = conversation.getAccount().getAxolotlService(); + XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlMessage, from.toBareJid()); + XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceivingPayloadMessage(xmppAxolotlMessage); + if(plaintextMessage != null) { + finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL); + finishedMessage.setFingerprint(plaintextMessage.getFingerprint()); + Logging.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(finishedMessage.getConversation().getAccount())+" Received Message with session fingerprint: "+plaintextMessage.getFingerprint()); + } + + return finishedMessage; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java b/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java index 9cf540a3..3569a7a5 100644 --- a/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java +++ b/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java @@ -39,6 +39,7 @@ import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Contact; import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.parser.IqParser; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.utils.CryptoHelper; @@ -944,7 +945,7 @@ public class AxolotlServiceImpl implements OnAdvancedStreamFeaturesLoaded, Axolo public void run() { XmppAxolotlMessage axolotlMessage = encrypt(message); if (axolotlMessage == null) { - MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED); + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.FAILED); //mXmppConnectionService.updateConversationUi(); } else { Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Generated message, caching: " + message.getUuid()); diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/otr/OtrMessageParser.java b/src/main/java/de/thedevstack/conversationsplus/crypto/otr/OtrMessageParser.java new file mode 100644 index 00000000..8791bff3 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/crypto/otr/OtrMessageParser.java @@ -0,0 +1,67 @@ +package de.thedevstack.conversationsplus.crypto.otr; + +import net.java.otr4j.session.Session; +import net.java.otr4j.session.SessionStatus; + +import de.thedevstack.conversationsplus.crypto.OtrService; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.utils.CryptoHelper; +import de.thedevstack.conversationsplus.utils.UiUpdateHelper; +import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; + +/** + */ +public class OtrMessageParser { + public static Message parseOtrChat(String body, Jid from, String id, Conversation conversation) { + String presence; + if (from.isBareJid()) { + presence = ""; + } else { + presence = from.getResourcepart(); + } + if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) { + conversation.endOtrIfNeeded(); + } + if (!conversation.hasValidOtrSession()) { + conversation.startOtrSession(presence,false); + } else { + String foreignPresence = conversation.getOtrSession().getSessionID().getUserID(); + if (!foreignPresence.equals(presence)) { + conversation.endOtrIfNeeded(); + conversation.startOtrSession(presence, false); + } + } + try { + conversation.setLastReceivedOtrMessageId(id); + Session otrSession = conversation.getOtrSession(); + body = otrSession.transformReceiving(body); + SessionStatus status = otrSession.getSessionStatus(); + if (body == null && status == SessionStatus.ENCRYPTED) { + XmppConnectionServiceAccessor.xmppConnectionService.onOtrSessionEstablished(conversation); + return null; + } else if (body == null && status == SessionStatus.FINISHED) { + conversation.resetOtrSession(); + UiUpdateHelper.updateConversationUi(); + return null; + } else if (body == null || (body.isEmpty())) { + return null; + } + if (body.startsWith(CryptoHelper.FILETRANSFER)) { + String key = body.substring(CryptoHelper.FILETRANSFER.length()); + conversation.setSymmetricKey(CryptoHelper.hexToBytes(key)); + return null; + } + final OtrService otrService = conversation.getAccount().getOtrService(); + Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR); + finishedMessage.setFingerprint(otrService.getFingerprint(otrSession.getRemotePublicKey())); + conversation.setLastReceivedOtrMessageId(null); + + return finishedMessage; + } catch (Exception e) { + conversation.resetOtrSession(); + return null; + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/otr/OtrUtil.java b/src/main/java/de/thedevstack/conversationsplus/crypto/otr/OtrUtil.java new file mode 100644 index 00000000..97075455 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/crypto/otr/OtrUtil.java @@ -0,0 +1,39 @@ +package de.thedevstack.conversationsplus.crypto.otr; + +import net.java.otr4j.session.SessionID; +import net.java.otr4j.session.SessionImpl; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.xmpp.Forwarded; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; +import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; + +/** + */ +public class OtrUtil { + public static boolean isOtrSessionActive(Conversation conversation) { + return null != conversation && null != conversation.getOtrSession(); + } + + public static boolean isCounterpartOfActiveOtrSession(Conversation conversation, Jid counterpart) { + SessionImpl otrSession = (null != conversation) ? conversation.getOtrSession() : null; + SessionID sessionID = (null != otrSession) ? otrSession.getSessionID() : null; + String userID = (null != sessionID) ? sessionID.getUserID() : null; + + return null != userID && null != counterpart && userID.equals(counterpart.getResourcepart()); + } + + public static boolean isValidOtrMessagePacket(MessagePacket messagePacket, Account account) { + Jid to = messagePacket.getTo(); + boolean isProperlyAddressed = (to != null) && (!to.isBareJid() || account.countPresences() <= 1); + boolean isNotTypeGroupChat = messagePacket.getType() != MessagePacket.TYPE_GROUPCHAT; + boolean isNotForwarded = !messagePacket.hasChildRecursive(Forwarded.FORWARDED); + + return isProperlyAddressed && isNotTypeGroupChat && isNotForwarded; + } + + public static boolean isOtrBody(String body) { + return body != null && body.startsWith("?OTR"); + } +} |