From 77619b55e47aafbe6b5a530b33ce8b6a77a615dd Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 25 Jun 2015 16:58:24 +0200 Subject: Added PEP and message protocol layers Can now fetch/retrieve from PEP, as well as encode/decode messages --- .../conversations/generator/AbstractGenerator.java | 4 +- .../siacs/conversations/generator/IqGenerator.java | 70 ++++++++++++++++++++++ .../conversations/generator/MessageGenerator.java | 21 +++++++ 3 files changed, 94 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 79626511..69bb1803 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Locale; import java.util.TimeZone; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.PhoneHelper; @@ -28,7 +29,8 @@ public abstract class AbstractGenerator { "urn:xmpp:avatar:metadata+notify", "urn:xmpp:ping", "jabber:iq:version", - "http://jabber.org/protocol/chatstates"}; + "http://jabber.org/protocol/chatstates", + AxolotlService.PEP_DEVICE_LIST+"+notify"}; private final String[] MESSAGE_CONFIRMATION_FEATURES = { "urn:xmpp:chat-markers:0", "urn:xmpp:receipts" diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 47915e3f..6daadc2a 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -1,9 +1,17 @@ package eu.siacs.conversations.generator; +import android.util.Base64; + +import org.whispersystems.libaxolotl.IdentityKey; +import org.whispersystems.libaxolotl.ecc.ECPublicKey; +import org.whispersystems.libaxolotl.state.PreKeyRecord; +import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; + import java.util.ArrayList; import java.util.List; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; @@ -115,6 +123,68 @@ public class IqGenerator extends AbstractGenerator { return packet; } + public IqPacket retrieveDeviceIds(final Jid to) { + final IqPacket packet = retrieve(AxolotlService.PEP_DEVICE_LIST, null); + if(to != null) { + packet.setTo(to); + } + return packet; + } + + public IqPacket retrieveBundleForDevice(final Jid to, final int deviceid) { + final IqPacket packet = retrieve(AxolotlService.PEP_BUNDLE+":"+deviceid, null); + if(to != null) { + packet.setTo(to); + } + return packet; + } + + public IqPacket retrievePreKeysForDevice(final Jid to, final int deviceId) { + final IqPacket packet = retrieve(AxolotlService.PEP_PREKEYS+":"+deviceId, null); + if(to != null) { + packet.setTo(to); + } + return packet; + } + + public IqPacket publishDeviceIds(final List ids) { + final Element item = new Element("item"); + final Element list = item.addChild("list", AxolotlService.PEP_PREFIX); + for(Integer id:ids) { + final Element device = new Element("device"); + device.setAttribute("id", id); + list.addChild(device); + } + return publish(AxolotlService.PEP_DEVICE_LIST, item); + } + + public IqPacket publishBundle(final SignedPreKeyRecord signedPreKeyRecord, IdentityKey identityKey, final int deviceId) { + final Element item = new Element("item"); + final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX); + final Element signedPreKeyPublic = bundle.addChild("signedPreKeyPublic"); + signedPreKeyPublic.setAttribute("signedPreKeyId", signedPreKeyRecord.getId()); + ECPublicKey publicKey = signedPreKeyRecord.getKeyPair().getPublicKey(); + signedPreKeyPublic.setContent(Base64.encodeToString(publicKey.serialize(),Base64.DEFAULT)); + final Element signedPreKeySignature = bundle.addChild("signedPreKeySignature"); + signedPreKeySignature.setContent(Base64.encodeToString(signedPreKeyRecord.getSignature(),Base64.DEFAULT)); + final Element identityKeyElement = bundle.addChild("identityKey"); + identityKeyElement.setContent(Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); + + return publish(AxolotlService.PEP_BUNDLE+":"+deviceId, item); + } + + public IqPacket publishPreKeys(final List prekeyList, final int deviceId) { + final Element item = new Element("item"); + final Element prekeys = item.addChild("prekeys", AxolotlService.PEP_PREFIX); + for(PreKeyRecord preKeyRecord:prekeyList) { + final Element prekey = prekeys.addChild("preKeyPublic"); + prekey.setAttribute("preKeyId", preKeyRecord.getId()); + prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT)); + } + + return publish(AxolotlService.PEP_PREKEYS+":"+deviceId, item); + } + public IqPacket queryMessageArchiveManagement(final MessageArchiveService.Query mam) { final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); final Element query = packet.query("urn:xmpp:mam:0"); diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index bc1148d9..e6032e0c 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.generator; +import android.util.Log; + import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -7,6 +9,11 @@ import java.util.TimeZone; import net.java.otr4j.OtrException; import net.java.otr4j.session.Session; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; +import eu.siacs.conversations.crypto.axolotl.NoSessionsCreatedException; +import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -59,6 +66,20 @@ public class MessageGenerator extends AbstractGenerator { delay.setAttribute("stamp", mDateFormat.format(date)); } + public MessagePacket generateAxolotlChat(Message message) throws NoSessionsCreatedException{ + return generateAxolotlChat(message, false); + } + + public MessagePacket generateAxolotlChat(Message message, boolean addDelay) throws NoSessionsCreatedException{ + MessagePacket packet = preparePacket(message, addDelay); + AxolotlService service = message.getConversation().getAccount().getAxolotlService(); + Log.d(Config.LOGTAG, "Submitting message to axolotl service for send processing..."); + XmppAxolotlMessage axolotlMessage = service.processSending(message.getContact(), + message.getBody()); + packet.setAxolotlMessage(axolotlMessage.toXml()); + return packet; + } + public MessagePacket generateOtrChat(Message message) { return generateOtrChat(message, false); } -- cgit v1.2.3 From 299bbdf27f0144e6eed99e70a3b2e46f9a3aa301 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 26 Jun 2015 15:41:02 +0200 Subject: Reformat code to use tabs This really sucks to do it like this. Sorry. :( --- .../siacs/conversations/generator/IqGenerator.java | 36 +++++++++++----------- .../conversations/generator/MessageGenerator.java | 22 ++++++------- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 6daadc2a..5b3bde6a 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -147,16 +147,16 @@ public class IqGenerator extends AbstractGenerator { return packet; } - public IqPacket publishDeviceIds(final List ids) { - final Element item = new Element("item"); - final Element list = item.addChild("list", AxolotlService.PEP_PREFIX); - for(Integer id:ids) { - final Element device = new Element("device"); - device.setAttribute("id", id); - list.addChild(device); - } - return publish(AxolotlService.PEP_DEVICE_LIST, item); - } + public IqPacket publishDeviceIds(final List ids) { + final Element item = new Element("item"); + final Element list = item.addChild("list", AxolotlService.PEP_PREFIX); + for(Integer id:ids) { + final Element device = new Element("device"); + device.setAttribute("id", id); + list.addChild(device); + } + return publish(AxolotlService.PEP_DEVICE_LIST, item); + } public IqPacket publishBundle(final SignedPreKeyRecord signedPreKeyRecord, IdentityKey identityKey, final int deviceId) { final Element item = new Element("item"); @@ -173,17 +173,17 @@ public class IqGenerator extends AbstractGenerator { return publish(AxolotlService.PEP_BUNDLE+":"+deviceId, item); } - public IqPacket publishPreKeys(final List prekeyList, final int deviceId) { - final Element item = new Element("item"); - final Element prekeys = item.addChild("prekeys", AxolotlService.PEP_PREFIX); - for(PreKeyRecord preKeyRecord:prekeyList) { - final Element prekey = prekeys.addChild("preKeyPublic"); + public IqPacket publishPreKeys(final List prekeyList, final int deviceId) { + final Element item = new Element("item"); + final Element prekeys = item.addChild("prekeys", AxolotlService.PEP_PREFIX); + for(PreKeyRecord preKeyRecord:prekeyList) { + final Element prekey = prekeys.addChild("preKeyPublic"); prekey.setAttribute("preKeyId", preKeyRecord.getId()); - prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT)); - } + prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT)); + } return publish(AxolotlService.PEP_PREKEYS+":"+deviceId, item); - } + } public IqPacket queryMessageArchiveManagement(final MessageArchiveService.Query mam) { final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index e6032e0c..0b6a7c61 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -66,19 +66,19 @@ public class MessageGenerator extends AbstractGenerator { delay.setAttribute("stamp", mDateFormat.format(date)); } - public MessagePacket generateAxolotlChat(Message message) throws NoSessionsCreatedException{ - return generateAxolotlChat(message, false); - } + public MessagePacket generateAxolotlChat(Message message) throws NoSessionsCreatedException{ + return generateAxolotlChat(message, false); + } public MessagePacket generateAxolotlChat(Message message, boolean addDelay) throws NoSessionsCreatedException{ - MessagePacket packet = preparePacket(message, addDelay); - AxolotlService service = message.getConversation().getAccount().getAxolotlService(); - Log.d(Config.LOGTAG, "Submitting message to axolotl service for send processing..."); - XmppAxolotlMessage axolotlMessage = service.processSending(message.getContact(), - message.getBody()); - packet.setAxolotlMessage(axolotlMessage.toXml()); - return packet; - } + MessagePacket packet = preparePacket(message, addDelay); + AxolotlService service = message.getConversation().getAccount().getAxolotlService(); + Log.d(Config.LOGTAG, "Submitting message to axolotl service for send processing..."); + XmppAxolotlMessage axolotlMessage = service.processSending(message.getContact(), + message.getBody()); + packet.setAxolotlMessage(axolotlMessage.toXml()); + return packet; + } public MessagePacket generateOtrChat(Message message) { return generateOtrChat(message, false); -- cgit v1.2.3 From c1d23b2395bfc9570aed07ba3413f988f08d84f5 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 29 Jun 2015 14:18:11 +0200 Subject: Migrate to new PEP layout Merge prekeys into bundle node --- .../siacs/conversations/generator/IqGenerator.java | 29 +++++++--------------- 1 file changed, 9 insertions(+), 20 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 5b3bde6a..0bef8853 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -10,6 +10,7 @@ import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import java.util.ArrayList; import java.util.List; +import java.util.Set; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; @@ -131,23 +132,15 @@ public class IqGenerator extends AbstractGenerator { return packet; } - public IqPacket retrieveBundleForDevice(final Jid to, final int deviceid) { - final IqPacket packet = retrieve(AxolotlService.PEP_BUNDLE+":"+deviceid, null); + public IqPacket retrieveBundlesForDevice(final Jid to, final int deviceid) { + final IqPacket packet = retrieve(AxolotlService.PEP_BUNDLES+":"+deviceid, null); if(to != null) { packet.setTo(to); } return packet; } - public IqPacket retrievePreKeysForDevice(final Jid to, final int deviceId) { - final IqPacket packet = retrieve(AxolotlService.PEP_PREKEYS+":"+deviceId, null); - if(to != null) { - packet.setTo(to); - } - return packet; - } - - public IqPacket publishDeviceIds(final List ids) { + public IqPacket publishDeviceIds(final Set ids) { final Element item = new Element("item"); final Element list = item.addChild("list", AxolotlService.PEP_PREFIX); for(Integer id:ids) { @@ -158,7 +151,8 @@ public class IqGenerator extends AbstractGenerator { return publish(AxolotlService.PEP_DEVICE_LIST, item); } - public IqPacket publishBundle(final SignedPreKeyRecord signedPreKeyRecord, IdentityKey identityKey, final int deviceId) { + public IqPacket publishBundles(final SignedPreKeyRecord signedPreKeyRecord, final IdentityKey identityKey, + final List preKeyRecords, final int deviceId) { final Element item = new Element("item"); final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX); final Element signedPreKeyPublic = bundle.addChild("signedPreKeyPublic"); @@ -170,19 +164,14 @@ public class IqGenerator extends AbstractGenerator { final Element identityKeyElement = bundle.addChild("identityKey"); identityKeyElement.setContent(Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); - return publish(AxolotlService.PEP_BUNDLE+":"+deviceId, item); - } - - public IqPacket publishPreKeys(final List prekeyList, final int deviceId) { - final Element item = new Element("item"); - final Element prekeys = item.addChild("prekeys", AxolotlService.PEP_PREFIX); - for(PreKeyRecord preKeyRecord:prekeyList) { + final Element prekeys = bundle.addChild("prekeys", AxolotlService.PEP_PREFIX); + for(PreKeyRecord preKeyRecord:preKeyRecords) { final Element prekey = prekeys.addChild("preKeyPublic"); prekey.setAttribute("preKeyId", preKeyRecord.getId()); prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT)); } - return publish(AxolotlService.PEP_PREKEYS+":"+deviceId, item); + return publish(AxolotlService.PEP_BUNDLES+":"+deviceId, item); } public IqPacket queryMessageArchiveManagement(final MessageArchiveService.Query mam) { -- cgit v1.2.3 From 3815d4efa378846c8aef840ad659268a0bef1536 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 29 Jun 2015 14:22:26 +0200 Subject: Fetch bundles on-demand, encrypt in background Bundles are now fetched on demand when a session needs to be established. This should lessen the chance of changes to the bundles occuring before they're used, as well as lessen the load of fetching bundles. Also, the message encryption is now done in a background thread, as this can be somewhat costly if many sessions are present. This is probably not going to be an issue in real use, but it's good practice anyway. --- .../eu/siacs/conversations/generator/MessageGenerator.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 0b6a7c61..b0727690 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -66,16 +66,18 @@ public class MessageGenerator extends AbstractGenerator { delay.setAttribute("stamp", mDateFormat.format(date)); } - public MessagePacket generateAxolotlChat(Message message) throws NoSessionsCreatedException{ + public MessagePacket generateAxolotlChat(Message message) { return generateAxolotlChat(message, false); } - public MessagePacket generateAxolotlChat(Message message, boolean addDelay) throws NoSessionsCreatedException{ + public MessagePacket generateAxolotlChat(Message message, boolean addDelay) { MessagePacket packet = preparePacket(message, addDelay); AxolotlService service = message.getConversation().getAccount().getAxolotlService(); Log.d(Config.LOGTAG, "Submitting message to axolotl service for send processing..."); - XmppAxolotlMessage axolotlMessage = service.processSending(message.getContact(), - message.getBody()); + XmppAxolotlMessage axolotlMessage = service.encrypt(message); + if (axolotlMessage == null) { + return null; + } packet.setAxolotlMessage(axolotlMessage.toXml()); return packet; } -- cgit v1.2.3 From 18c1e15d002f415c4449afe06e6dc80aef5aeade Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 3 Jul 2015 13:20:27 +0200 Subject: Rework PEP content verification Now checks which part(s) are out of sync w/ local storage, and updates only those, rather than assuming the entire node corrupt and overwriting it all (especially relevant for preKey list) --- src/main/java/eu/siacs/conversations/generator/IqGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 0bef8853..19c1d4f7 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -152,7 +152,7 @@ public class IqGenerator extends AbstractGenerator { } public IqPacket publishBundles(final SignedPreKeyRecord signedPreKeyRecord, final IdentityKey identityKey, - final List preKeyRecords, final int deviceId) { + final Set preKeyRecords, final int deviceId) { final Element item = new Element("item"); final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX); final Element signedPreKeyPublic = bundle.addChild("signedPreKeyPublic"); -- cgit v1.2.3 From 3458f5bb9182ca99dd800e4cde21168323260da4 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 8 Jul 2015 17:44:24 +0200 Subject: Clean up logging Add a fixed prefix to axolotl-related log messages, set log levels sensibly. --- src/main/java/eu/siacs/conversations/generator/MessageGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index b0727690..1dd21541 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -73,7 +73,7 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket generateAxolotlChat(Message message, boolean addDelay) { MessagePacket packet = preparePacket(message, addDelay); AxolotlService service = message.getConversation().getAccount().getAxolotlService(); - Log.d(Config.LOGTAG, "Submitting message to axolotl service for send processing..."); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(message.getConversation().getAccount())+"Submitting message to axolotl service for send processing..."); XmppAxolotlMessage axolotlMessage = service.encrypt(message); if (axolotlMessage == null) { return null; -- cgit v1.2.3 From 012f036840ade8f46462eafcc96d1f223f8ba845 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 14:26:29 +0200 Subject: Optimize imports --- src/main/java/eu/siacs/conversations/generator/IqGenerator.java | 1 - .../java/eu/siacs/conversations/generator/MessageGenerator.java | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/generator') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 19c1d4f7..88ff8f46 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -18,7 +18,6 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.PhoneHelper; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.forms.Data; diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 1dd21541..06ec0284 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -2,17 +2,16 @@ package eu.siacs.conversations.generator; import android.util.Log; +import net.java.otr4j.OtrException; +import net.java.otr4j.session.Session; + import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; -import net.java.otr4j.OtrException; -import net.java.otr4j.session.Session; - import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.AxolotlService; -import eu.siacs.conversations.crypto.axolotl.NoSessionsCreatedException; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; -- cgit v1.2.3