diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes128GcmNoPadding.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes128GcmNoPadding.java index ff1168cff..e52453bfe 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes128GcmNoPadding.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes128GcmNoPadding.java @@ -32,8 +32,8 @@ public class Aes128GcmNoPadding extends AesGcmNoPadding { public Aes128GcmNoPadding(byte[] keyAndIv, int MODE) throws NoSuchProviderException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException { - super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, keyAndIv.length / 2), //Key - AesGcmNoPadding.copyOfRange(keyAndIv, keyAndIv.length / 2, keyAndIv.length), MODE); //IV + super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, 16), // 16 byte key + AesGcmNoPadding.copyOfRange(keyAndIv, 16, keyAndIv.length), MODE); // rest (12 byte) IV } @Override diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes256GcmNoPadding.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes256GcmNoPadding.java index e65677b10..e7a323264 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes256GcmNoPadding.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/Aes256GcmNoPadding.java @@ -32,8 +32,8 @@ public class Aes256GcmNoPadding extends AesGcmNoPadding { public Aes256GcmNoPadding(byte[] keyAndIv, int MODE) throws NoSuchProviderException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException { - super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, keyAndIv.length / 2), //Key - AesGcmNoPadding.copyOfRange(keyAndIv, keyAndIv.length / 2, keyAndIv.length), MODE); //IV + super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, 32), // 32 byte key + AesGcmNoPadding.copyOfRange(keyAndIv, 32, keyAndIv.length), MODE); // rest (12 byte) IV } @Override diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/AesGcmNoPadding.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/AesGcmNoPadding.java index 5f4daa02b..a49b37396 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/AesGcmNoPadding.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/ciphers/AesGcmNoPadding.java @@ -47,12 +47,12 @@ public abstract class AesGcmNoPadding { key = keyGenerator.generateKey().getEncoded(); SecureRandom secureRandom = new SecureRandom(); - iv = new byte[bytes]; + iv = new byte[12]; secureRandom.nextBytes(iv); - keyAndIv = new byte[2 * bytes]; + keyAndIv = new byte[bytes + 12]; System.arraycopy(key, 0, keyAndIv, 0, bytes); - System.arraycopy(iv, 0, keyAndIv, bytes, bytes); + System.arraycopy(iv, 0, keyAndIv, bytes, 12); cipher = Cipher.getInstance(cipherMode, "BC"); SecretKey keySpec = new SecretKeySpec(key, keyType); @@ -86,6 +86,7 @@ public abstract class AesGcmNoPadding { */ public AesGcmNoPadding(byte[] key, byte[] iv, int MODE) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException { + assert iv.length == 12; this.length = key.length * 8; this.key = key; this.iv = iv; diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/ciphers/AesGcmNoPaddingTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/ciphers/AesGcmNoPaddingTest.java index 980229959..0366ed5d3 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/ciphers/AesGcmNoPaddingTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/ciphers/AesGcmNoPaddingTest.java @@ -42,8 +42,8 @@ public class AesGcmNoPaddingTest extends SmackTestSuite { AesGcmNoPadding aes128 = AesGcmNoPadding.createEncryptionKey(Aes128GcmNoPadding.NAMESPACE); assertNotNull(aes128); assertEquals(16, aes128.getKey().length); - assertEquals(16, aes128.getIv().length); - assertEquals(32, aes128.getKeyAndIv().length); + assertEquals(12, aes128.getIv().length); + assertEquals(28, aes128.getKeyAndIv().length); assertNotNull(aes128.getCipher()); assertEquals(128, aes128.getLength()); } @@ -53,8 +53,8 @@ public class AesGcmNoPaddingTest extends SmackTestSuite { AesGcmNoPadding aes256 = AesGcmNoPadding.createEncryptionKey(Aes256GcmNoPadding.NAMESPACE); assertNotNull(aes256); assertEquals(32, aes256.getKey().length); - assertEquals(32, aes256.getIv().length); - assertEquals(64, aes256.getKeyAndIv().length); + assertEquals(12, aes256.getIv().length); + assertEquals(44, aes256.getKeyAndIv().length); assertNotNull(aes256.getCipher()); assertEquals(256, aes256.getLength()); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentSecurityElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentSecurityElement.java index 8e7befaae..08bfbe30f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentSecurityElement.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentSecurityElement.java @@ -33,6 +33,14 @@ public abstract class JingleContentSecurityElement implements ExtensionElement { public static final String ELEMENT = "security"; private JingleContentSecurityInfoElement securityInfo; + public JingleContentSecurityElement() { + + } + + public JingleContentSecurityElement(JingleContentSecurityInfoElement info) { + this.securityInfo = info; + } + @Override public String getElementName() { return ELEMENT; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/UnknownJingleContentSecurityElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/UnknownJingleContentSecurityElement.java new file mode 100644 index 000000000..892c33b26 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/UnknownJingleContentSecurityElement.java @@ -0,0 +1,54 @@ +/** + * + * Copyright 2017 Paul Schaub. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.jingle.element; + +import org.jivesoftware.smack.packet.StandardExtensionElement; +import org.jivesoftware.smack.util.XmlStringBuilder; + +public final class UnknownJingleContentSecurityElement extends JingleContentSecurityElement { + + private final StandardExtensionElement standardExtensionElement; + + public UnknownJingleContentSecurityElement(StandardExtensionElement standardExtensionElement) { + super(); + this.standardExtensionElement = standardExtensionElement; + } + + @Override + public String getElementName() { + return standardExtensionElement.getElementName(); + } + + @Override + public String getNamespace() { + return standardExtensionElement.getNamespace(); + } + + @Override + public XmlStringBuilder toXML() { + return standardExtensionElement.toXML(); + } + + @Override + public JingleContentSecurityInfoElement getSecurityInfo() { + throw new UnsupportedOperationException(); + } + + public StandardExtensionElement getStandardExtensionElement() { + return standardExtensionElement; + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java index a8bb4ab61..f7f735562 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java @@ -26,10 +26,12 @@ import org.jivesoftware.smackx.jingle.JingleManager; import org.jivesoftware.smackx.jingle.element.JingleAction; import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement; import org.jivesoftware.smackx.jingle.element.JingleContentElement; +import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement; import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement; import org.jivesoftware.smackx.jingle.element.JingleElement; import org.jivesoftware.smackx.jingle.element.JingleReasonElement; import org.jivesoftware.smackx.jingle.element.UnknownJingleContentDescriptionElement; +import org.jivesoftware.smackx.jingle.element.UnknownJingleContentSecurityElement; import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransportElement; import org.jxmpp.jid.FullJid; @@ -120,45 +122,57 @@ public class JingleProvider extends IQProvider { outerloop: while (true) { int eventType = parser.next(); switch (eventType) { - case XmlPullParser.START_TAG: - String tagName = parser.getName(); - String namespace = parser.getNamespace(); - switch (tagName) { - case JingleContentDescriptionElement.ELEMENT: { - JingleContentDescriptionElement description; - JingleContentDescriptionProvider provider = JingleManager.getJingleDescriptionProvider(namespace); - if (provider == null) { - StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); - description = new UnknownJingleContentDescriptionElement(standardExtensionElement); + case XmlPullParser.START_TAG: + String tagName = parser.getName(); + String namespace = parser.getNamespace(); + switch (tagName) { + case JingleContentDescriptionElement.ELEMENT: { + JingleContentDescriptionElement description; + JingleContentDescriptionProvider provider = JingleManager.getJingleDescriptionProvider(namespace); + if (provider == null) { + StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); + description = new UnknownJingleContentDescriptionElement(standardExtensionElement); + } + else { + description = provider.parse(parser); + } + builder.setDescription(description); + break; + } + case JingleContentTransportElement.ELEMENT: { + JingleContentTransportElement transport; + JingleContentTransportProvider provider = JingleManager.getJingleTransportProvider(namespace); + if (provider == null) { + StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); + transport = new UnknownJingleContentTransportElement(standardExtensionElement); + } + else { + transport = provider.parse(parser); + } + builder.setTransport(transport); + break; + } + case JingleContentSecurityElement.ELEMENT: { + JingleContentSecurityElement security; + JingleContentSecurityProvider provider = JingleManager.getJingleSecurityProvider(namespace); + if (provider == null) { + StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); + security = new UnknownJingleContentSecurityElement(standardExtensionElement); + } else { + security = provider.parse(parser); + } + builder.setSecurity(security); + break; + } + default: + LOGGER.severe("Unknown Jingle content element: " + tagName); + break; } - else { - description = provider.parse(parser); - } - builder.setDescription(description); break; - } - case JingleContentTransportElement.ELEMENT: { - JingleContentTransportElement transport; - JingleContentTransportProvider provider = JingleManager.getJingleTransportProvider(namespace); - if (provider == null) { - StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); - transport = new UnknownJingleContentTransportElement(standardExtensionElement); + case XmlPullParser.END_TAG: + if (parser.getDepth() == initialDepth) { + break outerloop; } - else { - transport = provider.parse(parser); - } - builder.setTransport(transport); - break; - } - default: - LOGGER.severe("Unknown Jingle content element: " + tagName); - break; - } - break; - case XmlPullParser.END_TAG: - if (parser.getDepth() == initialDepth) { - break outerloop; - } } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transport/jingle_s5b/JingleS5BTransport.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transport/jingle_s5b/JingleS5BTransport.java index 62870805d..c8cdb3328 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transport/jingle_s5b/JingleS5BTransport.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transport/jingle_s5b/JingleS5BTransport.java @@ -469,6 +469,7 @@ public class JingleS5BTransport extends JingleTransport localStreamHosts = null; private List availableStreamHosts = null; - public static boolean useLocalCandidates = false; + public static boolean useLocalCandidates = true; public static boolean useExternalCandidates = true; static { diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index eba8d0f55..d697a2579 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -68,6 +68,7 @@ import org.jivesoftware.smackx.omemo.internal.OmemoDevice; import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation; import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener; import org.jivesoftware.smackx.omemo.listener.OmemoMucMessageListener; +import org.jivesoftware.smackx.omemo.util.OmemoConstants; import org.jivesoftware.smackx.pep.PEPListener; import org.jivesoftware.smackx.pep.PEPManager; import org.jivesoftware.smackx.pubsub.EventElement; @@ -115,6 +116,7 @@ public final class OmemoManager extends Manager implements JingleEncryptionMetho setConnectionListener(); this.deviceId = deviceId; service = OmemoService.getInstance(); + ServiceDiscoveryManager.getInstanceFor(connection).addFeature(OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL); } /**