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 --- .../eu/siacs/conversations/parser/IqParser.java | 158 ++++++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 6039d395..00f96885 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -1,9 +1,19 @@ package eu.siacs.conversations.parser; +import android.util.Base64; import android.util.Log; +import org.whispersystems.libaxolotl.IdentityKey; +import org.whispersystems.libaxolotl.InvalidKeyException; +import org.whispersystems.libaxolotl.ecc.Curve; +import org.whispersystems.libaxolotl.ecc.ECPublicKey; +import org.whispersystems.libaxolotl.state.PreKeyBundle; + import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; @@ -60,7 +70,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public String avatarData(final IqPacket packet) { final Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); + "http://jabber.org/protocol/pubsub"); if (pubsub == null) { return null; } @@ -71,6 +81,152 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return super.avatarData(items); } + public Element getItem(final IqPacket packet) { + final Element pubsub = packet.findChild("pubsub", + "http://jabber.org/protocol/pubsub"); + if (pubsub == null) { + return null; + } + final Element items = pubsub.findChild("items"); + if (items == null) { + return null; + } + return items.findChild("item"); + } + + public List deviceIds(final Element item) { + List deviceIds = new ArrayList<>(); + if (item == null) { + return null; + } + final Element list = item.findChild("list"); + if(list == null) { + return null; + } + for(Element device : list.getChildren()) { + if(!device.getName().equals("device")) { + continue; + } + try { + Integer id = Integer.valueOf(device.getAttribute("id")); + deviceIds.add(id); + } catch (NumberFormatException e) { + Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() + + ", skipping..."); + continue; + } + } + return deviceIds; + } + + public Integer signedPreKeyId(final Element bundle) { + final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic"); + if(signedPreKeyPublic == null) { + return null; + } + return Integer.valueOf(signedPreKeyPublic.getAttribute("signedPreKeyId")); + } + + public ECPublicKey signedPreKeyPublic(final Element bundle) { + ECPublicKey publicKey = null; + final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic"); + if(signedPreKeyPublic == null) { + return null; + } + try { + publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); + } catch (InvalidKeyException e) { + Log.e(Config.LOGTAG, "Invalid signedPreKeyPublic in PEP: " + e.getMessage()); + } + return publicKey; + } + + public byte[] signedPreKeySignature(final Element bundle) { + final Element signedPreKeySignature = bundle.findChild("signedPreKeySignature"); + if(signedPreKeySignature == null) { + return null; + } + return Base64.decode(signedPreKeySignature.getContent(),Base64.DEFAULT); + } + + public IdentityKey identityKey(final Element bundle) { + IdentityKey identityKey = null; + final Element identityKeyElement = bundle.findChild("identityKey"); + if(identityKeyElement == null) { + return null; + } + try { + identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); + } catch (InvalidKeyException e) { + Log.e(Config.LOGTAG,"Invalid identityKey in PEP: "+e.getMessage()); + } + return identityKey; + } + + public Map preKeyPublics(final IqPacket packet) { + Map preKeyRecords = new HashMap<>(); + Element prekeysItem = getItem(packet); + if (prekeysItem == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } + final Element prekeysElement = prekeysItem.findChild("prekeys"); + if(prekeysElement == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } + for(Element preKeyPublicElement : prekeysElement.getChildren()) { + if(!preKeyPublicElement.getName().equals("preKeyPublic")){ + Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); + continue; + } + Integer preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); + try { + ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); + preKeyRecords.put(preKeyId, preKeyPublic); + } catch (InvalidKeyException e) { + Log.e(Config.LOGTAG, "Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); + continue; + } + } + return preKeyRecords; + } + + public PreKeyBundle bundle(final IqPacket bundle) { + Element bundleItem = getItem(bundle); + if(bundleItem == null) { + return null; + } + final Element bundleElement = bundleItem.findChild("bundle"); + if(bundleElement == null) { + return null; + } + ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement); + Integer signedPreKeyId = signedPreKeyId(bundleElement); + byte[] signedPreKeySignature = signedPreKeySignature(bundleElement); + IdentityKey identityKey = identityKey(bundleElement); + if(signedPreKeyPublic == null || identityKey == null) { + return null; + } + + return new PreKeyBundle(0, 0, 0, null, + signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); + } + + public List preKeys(final IqPacket preKeys) { + List bundles = new ArrayList<>(); + Map preKeyPublics = preKeyPublics(preKeys); + if ( preKeyPublics != null) { + for (Integer preKeyId : preKeyPublics.keySet()) { + ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId); + bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic, + 0, null, null, null)); + } + } + + return bundles; + } + @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { -- 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. :( --- .../eu/siacs/conversations/parser/IqParser.java | 76 +++++++++++----------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 00f96885..df143a41 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -70,7 +70,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public String avatarData(final IqPacket packet) { final Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); + "http://jabber.org/protocol/pubsub"); if (pubsub == null) { return null; } @@ -165,19 +165,19 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public Map preKeyPublics(final IqPacket packet) { Map preKeyRecords = new HashMap<>(); - Element prekeysItem = getItem(packet); - if (prekeysItem == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); - return null; - } - final Element prekeysElement = prekeysItem.findChild("prekeys"); - if(prekeysElement == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); - return null; - } + Element prekeysItem = getItem(packet); + if (prekeysItem == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } + final Element prekeysElement = prekeysItem.findChild("prekeys"); + if(prekeysElement == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } for(Element preKeyPublicElement : prekeysElement.getChildren()) { if(!preKeyPublicElement.getName().equals("preKeyPublic")){ - Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); + Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); continue; } Integer preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); @@ -192,37 +192,37 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return preKeyRecords; } - public PreKeyBundle bundle(final IqPacket bundle) { - Element bundleItem = getItem(bundle); - if(bundleItem == null) { - return null; - } - final Element bundleElement = bundleItem.findChild("bundle"); - if(bundleElement == null) { - return null; - } - ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement); - Integer signedPreKeyId = signedPreKeyId(bundleElement); - byte[] signedPreKeySignature = signedPreKeySignature(bundleElement); - IdentityKey identityKey = identityKey(bundleElement); - if(signedPreKeyPublic == null || identityKey == null) { - return null; - } + public PreKeyBundle bundle(final IqPacket bundle) { + Element bundleItem = getItem(bundle); + if(bundleItem == null) { + return null; + } + final Element bundleElement = bundleItem.findChild("bundle"); + if(bundleElement == null) { + return null; + } + ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement); + Integer signedPreKeyId = signedPreKeyId(bundleElement); + byte[] signedPreKeySignature = signedPreKeySignature(bundleElement); + IdentityKey identityKey = identityKey(bundleElement); + if(signedPreKeyPublic == null || identityKey == null) { + return null; + } - return new PreKeyBundle(0, 0, 0, null, - signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); - } + return new PreKeyBundle(0, 0, 0, null, + signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); + } public List preKeys(final IqPacket preKeys) { List bundles = new ArrayList<>(); Map preKeyPublics = preKeyPublics(preKeys); - if ( preKeyPublics != null) { - for (Integer preKeyId : preKeyPublics.keySet()) { - ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId); - bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic, - 0, null, null, null)); - } - } + if ( preKeyPublics != null) { + for (Integer preKeyId : preKeyPublics.keySet()) { + ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId); + bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic, + 0, null, null, null)); + } + } return bundles; } -- 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 --- .../java/eu/siacs/conversations/parser/IqParser.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index df143a41..93551787 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -12,8 +12,10 @@ import org.whispersystems.libaxolotl.state.PreKeyBundle; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; @@ -94,8 +96,8 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return items.findChild("item"); } - public List deviceIds(final Element item) { - List deviceIds = new ArrayList<>(); + public Set deviceIds(final Element item) { + Set deviceIds = new HashSet<>(); if (item == null) { return null; } @@ -165,14 +167,18 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public Map preKeyPublics(final IqPacket packet) { Map preKeyRecords = new HashMap<>(); - Element prekeysItem = getItem(packet); - if (prekeysItem == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + Element item = getItem(packet); + if (item == null) { + Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); + return null; + } + final Element bundleElement = item.findChild("bundle"); + if(bundleElement == null) { return null; } - final Element prekeysElement = prekeysItem.findChild("prekeys"); + final Element prekeysElement = bundleElement.findChild("prekeys"); if(prekeysElement == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); return null; } for(Element preKeyPublicElement : prekeysElement.getChildren()) { -- cgit v1.2.3 From 6867b5c3abeeb5116a2542c56a706b733fd9cbf0 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sun, 5 Jul 2015 22:53:34 +0200 Subject: Return empty set on invalid PEP devicelist --- .../eu/siacs/conversations/parser/IqParser.java | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 93551787..c147978e 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.parser; +import android.support.annotation.NonNull; import android.util.Base64; import android.util.Log; @@ -96,26 +97,25 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return items.findChild("item"); } + @NonNull public Set deviceIds(final Element item) { Set deviceIds = new HashSet<>(); - if (item == null) { - return null; - } - final Element list = item.findChild("list"); - if(list == null) { - return null; - } - for(Element device : list.getChildren()) { - if(!device.getName().equals("device")) { - continue; - } - try { - Integer id = Integer.valueOf(device.getAttribute("id")); - deviceIds.add(id); - } catch (NumberFormatException e) { - Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() - + ", skipping..."); - continue; + if (item != null) { + final Element list = item.findChild("list"); + if (list != null) { + for (Element device : list.getChildren()) { + if (!device.getName().equals("device")) { + continue; + } + try { + Integer id = Integer.valueOf(device.getAttribute("id")); + deviceIds.add(id); + } catch (NumberFormatException e) { + Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() + + ", skipping..."); + continue; + } + } } } return deviceIds; -- 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/parser/IqParser.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index c147978e..e74cb65c 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Set; import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; @@ -111,7 +112,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Integer id = Integer.valueOf(device.getAttribute("id")); deviceIds.add(id); } catch (NumberFormatException e) { - Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered nvalid node in PEP:" + device.toString() + ", skipping..."); continue; } @@ -138,7 +139,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); } catch (InvalidKeyException e) { - Log.e(Config.LOGTAG, "Invalid signedPreKeyPublic in PEP: " + e.getMessage()); + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid signedPreKeyPublic in PEP: " + e.getMessage()); } return publicKey; } @@ -160,7 +161,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); } catch (InvalidKeyException e) { - Log.e(Config.LOGTAG,"Invalid identityKey in PEP: "+e.getMessage()); + Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : "+"Invalid identityKey in PEP: "+e.getMessage()); } return identityKey; } @@ -169,7 +170,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Map preKeyRecords = new HashMap<>(); Element item = getItem(packet); if (item == null) { - Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Couldn't find in bundle IQ packet: " + packet); return null; } final Element bundleElement = item.findChild("bundle"); @@ -178,12 +179,12 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } final Element prekeysElement = bundleElement.findChild("prekeys"); if(prekeysElement == null) { - Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Couldn't find in bundle IQ packet: " + packet); return null; } for(Element preKeyPublicElement : prekeysElement.getChildren()) { if(!preKeyPublicElement.getName().equals("preKeyPublic")){ - Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered unexpected tag in prekeys list: " + preKeyPublicElement); continue; } Integer preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); @@ -191,7 +192,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); preKeyRecords.put(preKeyId, preKeyPublic); } catch (InvalidKeyException e) { - Log.e(Config.LOGTAG, "Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); continue; } } -- cgit v1.2.3 From 496f531e2ef2cad5ff4dfb01ef0afe87c8b6b5c3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 23 Aug 2015 08:01:47 +0200 Subject: modified clearIqCallbacks into 2-step process --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index e74cb65c..4488eed8 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -236,7 +236,9 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { + if (packet.getType() == IqPacket.TYPE.ERROR) { + return; + } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { final Element query = packet.findChild("query"); // If this is in response to a query for the whole roster: if (packet.getType() == IqPacket.TYPE.RESULT) { @@ -306,15 +308,13 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT); mXmppConnectionService.sendIqPacket(account, response, null); } else { - if ((packet.getType() == IqPacket.TYPE.GET) - || (packet.getType() == IqPacket.TYPE.SET)) { + if (packet.getType() == IqPacket.TYPE.GET || packet.getType() == IqPacket.TYPE.SET) { final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR); final Element error = response.addChild("error"); error.setAttribute("type", "cancel"); - error.addChild("feature-not-implemented", - "urn:ietf:params:xml:ns:xmpp-stanzas"); + error.addChild("feature-not-implemented","urn:ietf:params:xml:ns:xmpp-stanzas"); account.getXmppConnection().sendIqPacket(response, null); - } + } } } -- cgit v1.2.3 From 0dfb9bd1a06436ffb6dd7a5cfbdefa11d3ae130e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 23 Aug 2015 17:53:23 +0200 Subject: introduce special iq type for internal timeouts. always use != result to check for error in callbacks --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 4488eed8..cef5b03d 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -236,7 +236,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.ERROR) { + if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) { return; } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { final Element query = packet.findChild("query"); -- cgit v1.2.3 From d0b8bd0f8a0cb10c93d45d6900ff1fdb62db80b7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 24 Aug 2015 18:18:01 +0200 Subject: catch invalid base64 in axolotl key parsing --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index cef5b03d..44e4bc08 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -138,7 +138,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); - } catch (InvalidKeyException e) { + } catch (InvalidKeyException | IllegalArgumentException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid signedPreKeyPublic in PEP: " + e.getMessage()); } return publicKey; -- cgit v1.2.3 From 8f4b7686c94c52563c29f100cd25599ac08a7bb2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 30 Aug 2015 11:11:54 +0200 Subject: catch invalid base64 on omemo key decoding --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 44e4bc08..f6446cfd 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -149,7 +149,12 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { if(signedPreKeySignature == null) { return null; } - return Base64.decode(signedPreKeySignature.getContent(),Base64.DEFAULT); + try { + return Base64.decode(signedPreKeySignature.getContent(), Base64.DEFAULT); + } catch (IllegalArgumentException e) { + Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : Invalid base64 in signedPreKeySignature"); + return null; + } } public IdentityKey identityKey(final Element bundle) { @@ -160,7 +165,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); - } catch (InvalidKeyException e) { + } catch (InvalidKeyException | IllegalArgumentException e) { Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : "+"Invalid identityKey in PEP: "+e.getMessage()); } return identityKey; @@ -191,7 +196,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); preKeyRecords.put(preKeyId, preKeyPublic); - } catch (InvalidKeyException e) { + } catch (InvalidKeyException | IllegalArgumentException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); continue; } -- cgit v1.2.3 From cfeb67d71da01bc95ed713d6591fa6e79fc08dd6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Oct 2015 23:48:42 +0200 Subject: introduced code to verify omemo device keys with x509 certificates. cleaned up TrustKeysActivity to automatically close if there is nothing to do --- .../eu/siacs/conversations/parser/IqParser.java | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index f6446cfd..e26a493f 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.parser; import android.support.annotation.NonNull; import android.util.Base64; import android.util.Log; +import android.util.Pair; import org.whispersystems.libaxolotl.IdentityKey; import org.whispersystems.libaxolotl.InvalidKeyException; @@ -10,6 +11,10 @@ import org.whispersystems.libaxolotl.ecc.Curve; import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.state.PreKeyBundle; +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -204,6 +209,30 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return preKeyRecords; } + public Pair verification(final IqPacket packet) { + Element item = getItem(packet); + Element verification = item != null ? item.findChild("verification",AxolotlService.PEP_PREFIX) : null; + Element chain = verification != null ? verification.findChild("chain") : null; + Element signature = verification != null ? verification.findChild("signature") : null; + if (chain != null && signature != null) { + List certElements = chain.getChildren(); + X509Certificate[] certificates = new X509Certificate[certElements.size()]; + try { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + int i = 0; + for(Element cert : certElements) { + certificates[i] = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.getContent(),Base64.DEFAULT))); + ++i; + } + return new Pair<>(certificates,Base64.decode(signature.getContent(),Base64.DEFAULT)); + } catch (CertificateException e) { + return null; + } + } else { + return null; + } + } + public PreKeyBundle bundle(final IqPacket bundle) { Element bundleItem = getItem(bundle); if(bundleItem == null) { -- cgit v1.2.3 From 88523bbb5073867be3faeed27d4b7def1263205b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 12 Dec 2015 15:58:22 +0100 Subject: more detailed logging --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index e26a493f..1761e0df 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -117,8 +117,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Integer id = Integer.valueOf(device.getAttribute("id")); deviceIds.add(id); } catch (NumberFormatException e) { - Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered nvalid node in PEP:" + device.toString() - + ", skipping..."); + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered invalid node in PEP ("+e.getMessage()+"):" + device.toString()+ ", skipping..."); continue; } } -- cgit v1.2.3