From eb413f30b17c995b5e98c4e90e1fbf5b4cae1edd Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Wed, 16 Aug 2017 16:42:11 +0200 Subject: [PATCH] Refactor JET in order to match spec --- .../jivesoftware/smackx/jet/JetManager.java | 38 +++++++++---------- ...Method.java => JingleEnvelopeManager.java} | 12 ++++-- .../smackx/jet/component/JetSecurity.java | 28 +++++++------- .../jet/element/JetSecurityElement.java | 22 +++++------ .../jet/provider/JetSecurityProvider.java | 8 ++-- .../smackx/jet/JetElementTest.java | 12 +++--- .../jingle/component/JingleContent.java | 2 +- .../smackx/jet/JetIntegrationTest.java | 6 +-- .../smackx/omemo/OmemoManager.java | 20 ++++++---- 9 files changed, 78 insertions(+), 70 deletions(-) rename smack-experimental/src/main/java/org/jivesoftware/smackx/jet/{JingleEncryptionMethod.java => JingleEnvelopeManager.java} (74%) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetManager.java index 759acc79f..a1ad1586e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetManager.java @@ -50,8 +50,8 @@ public final class JetManager extends Manager implements JingleDescriptionManage private static final Logger LOGGER = Logger.getLogger(JetManager.class.getName()); private static final WeakHashMap INSTANCES = new WeakHashMap<>(); - private static final HashMap encryptionMethods = new HashMap<>(); - private static final HashMap> encryptionMethodProviders = new HashMap<>(); + private static final HashMap envelopeManagers = new HashMap<>(); + private static final HashMap> envelopeProviders = new HashMap<>(); private final JingleManager jingleManager; @@ -78,17 +78,17 @@ public final class JetManager extends Manager implements JingleDescriptionManage return manager; } - public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEncryptionMethod method) throws Exception { - return sendEncryptedFile(file, null, recipient, method); + public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEnvelopeManager envelopeManager) throws Exception { + return sendEncryptedFile(file, null, recipient, envelopeManager); } - public OutgoingFileOfferController sendEncryptedFile(File file, String filename, FullJid recipient, JingleEncryptionMethod method) throws Exception { + public OutgoingFileOfferController sendEncryptedFile(File file, String filename, FullJid recipient, JingleEnvelopeManager envelopeManager) throws Exception { if (file == null || !file.exists()) { throw new IllegalArgumentException("File MUST NOT be null and MUST exist."); } ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection()); - if (!disco.supportsFeature(recipient, getNamespace()) || !disco.supportsFeature(recipient, method.getNamespace())) { + if (!disco.supportsFeature(recipient, getNamespace()) || !disco.supportsFeature(recipient, envelopeManager.getJingleEnvelopeNamespace())) { throw new SmackException.FeatureNotSupportedException(getNamespace(), recipient); } @@ -106,35 +106,35 @@ public final class JetManager extends Manager implements JingleDescriptionManage JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient); content.setTransport(transportManager.createTransportForInitiator(content)); - JetSecurity security = new JetSecurity(method, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE); + JetSecurity security = new JetSecurity(envelopeManager, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE); content.setSecurity(security); session.sendInitiate(connection()); return offer; } - public void registerEncryptionMethod(JingleEncryptionMethod method) { - encryptionMethods.put(method.getNamespace(), method); + public void registerEnvelopeManager(JingleEnvelopeManager method) { + envelopeManagers.put(method.getJingleEnvelopeNamespace(), method); } - public void unregisterEncryptionMethod(String namespace) { - encryptionMethods.remove(namespace); + public void unregisterEnvelopeManager(String namespace) { + envelopeManagers.remove(namespace); } - public JingleEncryptionMethod getEncryptionMethod(String namespace) { - return encryptionMethods.get(namespace); + public JingleEnvelopeManager getEnvelopeManager(String namespace) { + return envelopeManagers.get(namespace); } - public static void registerEncryptionMethodProvider(String namespace, ExtensionElementProvider provider) { - encryptionMethodProviders.put(namespace, provider); + public static void registerEnvelopeProvider(String namespace, ExtensionElementProvider provider) { + envelopeProviders.put(namespace, provider); } - public static void removeEncryptionMethodProvider(String namespace) { - encryptionMethodProviders.remove(namespace); + public static void unregisterEnvelopeProvider(String namespace) { + envelopeProviders.remove(namespace); } - public static ExtensionElementProvider getEncryptionMethodProvider(String namespace) { - return encryptionMethodProviders.get(namespace); + public static ExtensionElementProvider getEnvelopeProvider(String namespace) { + return envelopeProviders.get(namespace); } @Override diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEncryptionMethod.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java similarity index 74% rename from smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEncryptionMethod.java rename to smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java index 262b2b456..88464f47d 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEncryptionMethod.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java @@ -28,11 +28,15 @@ import org.jxmpp.jid.FullJid; /** * Classes that implement this interface can be used to encrypt Jingle File Transfers. */ -public interface JingleEncryptionMethod { +public interface JingleEnvelopeManager { - ExtensionElement encryptJingleTransfer(FullJid recipient, byte[] keyData) throws JingleEncryptionException, InterruptedException, NoSuchAlgorithmException, SmackException.NotConnectedException, SmackException.NoResponseException; + ExtensionElement encryptJingleTransfer(FullJid recipient, byte[] keyData) + throws JingleEncryptionException, InterruptedException, NoSuchAlgorithmException, + SmackException.NotConnectedException, SmackException.NoResponseException; - byte[] decryptJingleTransfer(FullJid sender, ExtensionElement encryptionElement) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException; + byte[] decryptJingleTransfer(FullJid sender, ExtensionElement envelope) + throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, + SmackException.NotConnectedException, SmackException.NoResponseException; class JingleEncryptionException extends Exception { private static final long serialVersionUID = 1L; @@ -44,5 +48,5 @@ public interface JingleEncryptionMethod { XMPPConnection getConnection(); - String getNamespace(); + String getJingleEnvelopeNamespace(); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurity.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurity.java index 0397dbaeb..6d2609618 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurity.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurity.java @@ -31,7 +31,7 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.ciphers.AesGcmNoPadding; import org.jivesoftware.smackx.jet.JetManager; -import org.jivesoftware.smackx.jet.JingleEncryptionMethod; +import org.jivesoftware.smackx.jet.JingleEnvelopeManager; import org.jivesoftware.smackx.jet.element.JetSecurityElement; import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback; import org.jivesoftware.smackx.jingle.component.JingleSecurity; @@ -49,7 +49,7 @@ public class JetSecurity extends JingleSecurity { public static final String NAMESPACE_V0 = "urn:xmpp:jingle:jet:0"; public static final String NAMESPACE = NAMESPACE_V0; - private final String methodNamespace; + private final String envelopeNamespace; private AesGcmNoPadding aesKey; private final ExtensionElement child; @@ -59,26 +59,26 @@ public class JetSecurity extends JingleSecurity { public JetSecurity(JetSecurityElement element) { super(); this.child = element.getChild(); - this.methodNamespace = element.getMethodNamespace(); + this.envelopeNamespace = element.getEnvelopeNamespace(); this.contentName = element.getContentName(); this.cipherName = element.getCipherName(); } - public JetSecurity(JingleEncryptionMethod method, FullJid recipient, String contentName, String cipherName) + public JetSecurity(JingleEnvelopeManager envelopeManager, FullJid recipient, String contentName, String cipherName) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, InterruptedException, - JingleEncryptionMethod.JingleEncryptionException, SmackException.NotConnectedException, + JingleEnvelopeManager.JingleEncryptionException, SmackException.NotConnectedException, SmackException.NoResponseException { - this.methodNamespace = method.getNamespace(); + this.envelopeNamespace = envelopeManager.getJingleEnvelopeNamespace(); this.aesKey = AesGcmNoPadding.createEncryptionKey(cipherName); - this.child = method.encryptJingleTransfer(recipient, aesKey.getKeyAndIv()); + this.child = envelopeManager.encryptJingleTransfer(recipient, aesKey.getKeyAndIv()); this.contentName = contentName; this.cipherName = cipherName; } - private void decryptEncryptionKey(JingleEncryptionMethod method, FullJid sender) - throws InterruptedException, JingleEncryptionMethod.JingleEncryptionException, XMPPException.XMPPErrorException, + private void decryptEncryptionKey(JingleEnvelopeManager method, FullJid sender) + throws InterruptedException, JingleEnvelopeManager.JingleEncryptionException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException { byte[] keyAndIv = method.decryptJingleTransfer(sender, child); @@ -125,18 +125,18 @@ public class JetSecurity extends JingleSecurity { return; } - JingleEncryptionMethod method = JetManager.getInstanceFor(connection).getEncryptionMethod(getMethodNamespace()); + JingleEnvelopeManager method = JetManager.getInstanceFor(connection).getEnvelopeManager(getEnvelopeNamespace()); if (method == null) { - throw new AssertionError("No JingleEncryptionMethodManager found for " + getMethodNamespace()); + throw new AssertionError("No JingleEncryptionMethodManager found for " + getEnvelopeNamespace()); } try { decryptEncryptionKey(method, sender); - } catch (InterruptedException | NoSuchPaddingException | InvalidKeyException | NoSuchProviderException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | JingleEncryptionMethod.JingleEncryptionException e) { + } catch (InterruptedException | NoSuchPaddingException | InvalidKeyException | NoSuchProviderException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | JingleEnvelopeManager.JingleEncryptionException e) { LOGGER.log(Level.SEVERE, "Could not decrypt security key: " + e, e); } } - public String getMethodNamespace() { - return methodNamespace; + public String getEnvelopeNamespace() { + return envelopeNamespace; } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/JetSecurityElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/JetSecurityElement.java index 98df7589c..c976a99f2 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/JetSecurityElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/JetSecurityElement.java @@ -32,16 +32,16 @@ import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement; * */ public class JetSecurityElement extends JingleContentSecurityElement { - public static final String ATTR_NAME = "name"; - public static final String ATTR_TYPE = "type"; - public static final String ATTR_CIPHER = "cipher"; + public static final String ATTR_CONTENT_NAME = "name"; + public static final String ATTR_ENVELOPE_TYPE = "type"; + public static final String ATTR_CIPHER_TYPE = "cipher"; private final ExtensionElement child; - private final String name; + private final String contentName; private final String cipherName; - public JetSecurityElement(String name, String cipherName, ExtensionElement child) { - this.name = name; + public JetSecurityElement(String contentName, String cipherName, ExtensionElement child) { + this.contentName = contentName; this.child = child; this.cipherName = cipherName; } @@ -49,9 +49,9 @@ public class JetSecurityElement extends JingleContentSecurityElement { @Override public CharSequence toXML() { XmlStringBuilder xml = new XmlStringBuilder(this); - xml.attribute(ATTR_NAME, name) - .attribute(ATTR_CIPHER, cipherName) - .attribute(ATTR_TYPE, child.getNamespace()); + xml.attribute(ATTR_CONTENT_NAME, contentName) + .attribute(ATTR_CIPHER_TYPE, cipherName) + .attribute(ATTR_ENVELOPE_TYPE, child.getNamespace()); xml.rightAngleBracket(); xml.element(child); xml.closeElement(this); @@ -63,7 +63,7 @@ public class JetSecurityElement extends JingleContentSecurityElement { return JetSecurity.NAMESPACE; } - public String getMethodNamespace() { + public String getEnvelopeNamespace() { return child.getNamespace(); } @@ -72,7 +72,7 @@ public class JetSecurityElement extends JingleContentSecurityElement { } public String getContentName() { - return name; + return contentName; } public String getCipherName() { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/provider/JetSecurityProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/provider/JetSecurityProvider.java index cd6fa5ece..e997f5019 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/provider/JetSecurityProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/provider/JetSecurityProvider.java @@ -37,16 +37,16 @@ public class JetSecurityProvider extends JingleContentSecurityProvider encryptionElementProvider = - JetManager.getEncryptionMethodProvider(type); + JetManager.getEnvelopeProvider(type); if (encryptionElementProvider != null) { child = encryptionElementProvider.parse(parser); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/jet/JetElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/jet/JetElementTest.java index 1fd7e31c4..537808804 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/jet/JetElementTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/jet/JetElementTest.java @@ -38,13 +38,13 @@ import org.xml.sax.SAXException; public class JetElementTest extends SmackTestSuite { @Test - public void jetTest() throws InterruptedException, JingleEncryptionMethod.JingleEncryptionException, NoSuchAlgorithmException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException, SAXException { + public void jetTest() throws InterruptedException, JingleEnvelopeManager.JingleEncryptionException, NoSuchAlgorithmException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException, SAXException { ExtensionElement child = new SecurityStub().encryptJingleTransfer(null, null); JetSecurityElement element = new JetSecurityElement("content1", Aes128GcmNoPadding.NAMESPACE, child); JetSecurity security = new JetSecurity(element); - assertEquals(SecurityStub.NAMESPACE, security.getMethodNamespace()); + assertEquals(SecurityStub.NAMESPACE, security.getEnvelopeNamespace()); assertEquals(Aes128GcmNoPadding.NAMESPACE, element.getCipherName()); - assertEquals(SecurityStub.NAMESPACE, element.getMethodNamespace()); + assertEquals(SecurityStub.NAMESPACE, element.getEnvelopeNamespace()); assertEquals("content1", element.getContentName()); String xml = "> INSTANCES = new WeakHashMap<>(); @@ -760,11 +760,15 @@ public final class OmemoManager extends Manager implements JingleEncryptionMetho return connection(); } - @Override - public String getNamespace() { + public static String getNamespace() { return OMEMO_NAMESPACE_V_AXOLOTL; } + @Override + public String getJingleEnvelopeNamespace() { + return getNamespace(); + } + /** * Return the OMEMO service object. * @@ -870,13 +874,13 @@ public final class OmemoManager extends Manager implements JingleEncryptionMetho } @Override - public byte[] decryptJingleTransfer(FullJid sender, ExtensionElement encryptionElement) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { - if (!encryptionElement.getNamespace().equals(OMEMO_NAMESPACE_V_AXOLOTL) - || !encryptionElement.getElementName().equals(OmemoElement.ENCRYPTED)) { + public byte[] decryptJingleTransfer(FullJid sender, ExtensionElement envelope) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { + if (!envelope.getNamespace().equals(OMEMO_NAMESPACE_V_AXOLOTL) + || !envelope.getElementName().equals(OmemoElement.ENCRYPTED)) { throw new IllegalArgumentException("Passed ExtensionElement MUST be an OmemoElement!"); } - OmemoElement omemoElement = (OmemoElement) encryptionElement; + OmemoElement omemoElement = (OmemoElement) envelope; Message pseudoMessage = new Message(); pseudoMessage.setFrom(sender.asBareJid()); pseudoMessage.addExtension(omemoElement);