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 e84834fa2..13fb7dc1d 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 @@ -17,6 +17,9 @@ package org.jivesoftware.smackx.jet; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -53,6 +56,7 @@ import org.jxmpp.jid.FullJid; /** * Manager for Jingle Encrypted Transfers (XEP-XXXX). + * @see Proto-XEP */ public final class JetManager extends Manager implements JingleDescriptionManager { @@ -76,6 +80,11 @@ public final class JetManager extends Manager implements JingleDescriptionManage jingleManager.addJingleDescriptionManager(this); } + /** + * Return an instance of the JetManager for the given connection. + * @param connection connection. + * @return instance. + */ public static JetManager getInstanceFor(XMPPConnection connection) { JetManager manager = INSTANCES.get(connection); @@ -87,35 +96,60 @@ public final class JetManager extends Manager implements JingleDescriptionManage return manager; } - public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEnvelopeManager envelopeManager) throws Exception { + /** + * Send a file to recipient, JET encrypted using the method described by envelopeManager. + * @param file file + * @param recipient recipient + * @param envelopeManager {@link JingleEnvelopeManager} (eg. OmemoManager). + * @return controller for the outgoing file transfer. + */ + public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEnvelopeManager envelopeManager) + throws IOException, NoSuchAlgorithmException, SmackException.FeatureNotSupportedException, + InvalidKeyException, InterruptedException, XMPPException.XMPPErrorException, NoSuchPaddingException, + JingleEnvelopeManager.JingleEncryptionException, SmackException.NotConnectedException, + SmackException.NoResponseException, NoSuchProviderException, InvalidAlgorithmParameterException { return sendEncryptedFile(file, JingleFile.fromFile(file, null, null, null), recipient, envelopeManager); } - public OutgoingFileOfferController sendEncryptedFile(File file, JingleFile metadata, FullJid recipient, JingleEnvelopeManager envelopeManager) throws Exception { + /** + * Send a file to recipient, JET encrypted using the method described by envelopeManager. + * @param file file containing data. + * @param metadata custom metadata about the file (like alternative filename...) + * @param recipient recipient + * @param envelopeManager {@link JingleEnvelopeManager} (eg. OmemoManager). + * @return controller for the outgoing file transfer. + */ + public OutgoingFileOfferController sendEncryptedFile(File file, JingleFile metadata, FullJid recipient, JingleEnvelopeManager envelopeManager) + throws FileNotFoundException, SmackException.FeatureNotSupportedException, NoSuchAlgorithmException, + InvalidKeyException, InterruptedException, XMPPException.XMPPErrorException, NoSuchPaddingException, + JingleEnvelopeManager.JingleEncryptionException, SmackException.NotConnectedException, + SmackException.NoResponseException, NoSuchProviderException, InvalidAlgorithmParameterException { if (file == null || !file.exists()) { throw new IllegalArgumentException("File MUST NOT be null and MUST exist."); } - throwIfRecipientLacksSupport(recipient); - - JingleSession session = jingleManager.createSession(Role.initiator, recipient); - - JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator); - session.addContent(content); - - JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file, metadata); - content.setDescription(offer); - - JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient); - content.setTransport(transportManager.createTransportForInitiator(content)); - - JetSecurity security = new JetSecurity(envelopeManager, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE); - content.setSecurity(security); - session.sendInitiate(connection()); - - return offer; + return sendEncryptedStream(new FileInputStream(file), metadata, recipient, envelopeManager); } + /** + * Send the content of an InputStream to recipient, JET encrypted via the method described by envelopeManager. + * @param inputStream InputStream with data. + * @param metadata metadata about the inputstream (filename etc). + * @param recipient recipient + * @param envelopeManager {@link JingleEnvelopeManager} (eg. OmemoManager). + * @return controller for the outgoing file transfer. + * @throws XMPPException.XMPPErrorException + * @throws SmackException.FeatureNotSupportedException Recipient does not support JET or needed Jingle features. + * @throws SmackException.NotConnectedException + * @throws InterruptedException + * @throws SmackException.NoResponseException + * @throws NoSuchPaddingException + * @throws InvalidKeyException + * @throws NoSuchAlgorithmException + * @throws JingleEnvelopeManager.JingleEncryptionException JET encryption failed. + * @throws NoSuchProviderException + * @throws InvalidAlgorithmParameterException + */ public OutgoingFileOfferController sendEncryptedStream(InputStream inputStream, JingleFile metadata, FullJid recipient, JingleEnvelopeManager envelopeManager) throws XMPPException.XMPPErrorException, SmackException.FeatureNotSupportedException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, @@ -140,26 +174,53 @@ public final class JetManager extends Manager implements JingleDescriptionManage return offer; } + /** + * Register an {@link JingleEnvelopeManager} + * @param method manager. + */ public void registerEnvelopeManager(JingleEnvelopeManager method) { envelopeManagers.put(method.getJingleEnvelopeNamespace(), method); } + /** + * Unregister an {@link JingleEnvelopeManager} + * @param namespace namespace of the manager. + */ public void unregisterEnvelopeManager(String namespace) { envelopeManagers.remove(namespace); } + /** + * Return an {@link JingleEnvelopeManager} for the given namespace. + * @param namespace namespace. + * @return manager or null. + */ public JingleEnvelopeManager getEnvelopeManager(String namespace) { return envelopeManagers.get(namespace); } + /** + * Register an {@link ExtensionElementProvider} for an envelope element. + * @param namespace namespace. + * @param provider provider. + */ public static void registerEnvelopeProvider(String namespace, ExtensionElementProvider provider) { envelopeProviders.put(namespace, provider); } + /** + * Unregister an {@link ExtensionElementProvider} for an envelope element. + * @param namespace namespace. + */ public static void unregisterEnvelopeProvider(String namespace) { envelopeProviders.remove(namespace); } + /** + * Return an {@link ExtensionElementProvider} for an envelope element with the given namespace. + * @param namespace namespace. + * @return provider. + */ public static ExtensionElementProvider getEnvelopeProvider(String namespace) { return envelopeProviders.get(namespace); } @@ -179,6 +240,15 @@ public final class JetManager extends Manager implements JingleDescriptionManage JingleFileTransferManager.getInstanceFor(connection()).notifyContentAdd(session, content); } + /** + * Throw a {@link org.jivesoftware.smack.SmackException.FeatureNotSupportedException} when recipient doesn't support JET. + * @param recipient recipient. + * @throws XMPPException.XMPPErrorException + * @throws SmackException.NotConnectedException + * @throws InterruptedException + * @throws SmackException.NoResponseException + * @throws SmackException.FeatureNotSupportedException + */ private void throwIfRecipientLacksSupport(FullJid recipient) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.FeatureNotSupportedException { if (!ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(recipient, getNamespace())) { throw new SmackException.FeatureNotSupportedException(getNamespace(), recipient); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetSecurityAdapter.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetSecurityAdapter.java index 32e9831da..2ee32af28 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetSecurityAdapter.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JetSecurityAdapter.java @@ -21,6 +21,9 @@ import org.jivesoftware.smackx.jet.element.JetSecurityElement; import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter; import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement; +/** + * Adapter to parse JetSecurityElements into JetSecurity components. + */ public class JetSecurityAdapter implements JingleSecurityAdapter { @Override diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java index 88464f47d..1b068aacc 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/JingleEnvelopeManager.java @@ -26,18 +26,44 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jxmpp.jid.FullJid; /** - * Classes that implement this interface can be used to encrypt Jingle File Transfers. + * Interface that provides methods that need to be implemented by potential JingleEnvelopeManagers. + * An JingleEnvelopeManager can be used to secure a JET encrypted Transport. */ public interface JingleEnvelopeManager { + /** + * Encrypt a serialized encryption key (Transport Secret) and return the resulting {@link ExtensionElement} (Envelope). + * @param recipient recipient of the transfer. + * @param keyData Serialized key. This is referred to in the XEP as Transport Secret. + * @return encrypted Transport Secret as Envelope element. + * @throws JingleEncryptionException JET encryption fails. + * @throws InterruptedException + * @throws NoSuchAlgorithmException + * @throws SmackException.NotConnectedException + * @throws SmackException.NoResponseException + */ ExtensionElement encryptJingleTransfer(FullJid recipient, byte[] keyData) throws JingleEncryptionException, InterruptedException, NoSuchAlgorithmException, SmackException.NotConnectedException, SmackException.NoResponseException; + /** + * Decrypt a serialized encryption key (Transport Secret) from an {@link ExtensionElement} (Envelope). + * @param sender sender of the Envelope. + * @param envelope encrypted key as Envelope element. + * @return decrypted Transport Secret. + * @throws JingleEncryptionException JET encryption fails. + * @throws InterruptedException + * @throws XMPPException.XMPPErrorException + * @throws SmackException.NotConnectedException + * @throws SmackException.NoResponseException + */ byte[] decryptJingleTransfer(FullJid sender, ExtensionElement envelope) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException; + /** + * Exception that wraps possible exceptions that might occur during encryption/decryption. + */ class JingleEncryptionException extends Exception { private static final long serialVersionUID = 1L; @@ -46,7 +72,15 @@ public interface JingleEnvelopeManager { } } + /** + * Return the connection of the manager. + * @return connection. + */ XMPPConnection getConnection(); + /** + * Return the namespace of the Envelope method. + * @return namespace. + */ 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 6d2609618..d861de2b2 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 @@ -41,7 +41,8 @@ import org.jivesoftware.smackx.jingle.element.JingleElement; import org.jxmpp.jid.FullJid; /** - * Created by vanitas on 22.07.17. + * JetSecurity security component for Jingle Encrypted Transports. + * @see Proto-XEP */ public class JetSecurity extends JingleSecurity { private static final Logger LOGGER = Logger.getLogger(JetSecurity.class.getName()); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurityBytestreamSession.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurityBytestreamSession.java index 6426e4c93..d4983b7dc 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurityBytestreamSession.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/JetSecurityBytestreamSession.java @@ -26,6 +26,10 @@ import javax.crypto.CipherOutputStream; import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.jingle.component.JingleSecurityBytestreamSession; +/** + * Wrapper that wraps a the {@link InputStream} and {@link OutputStream} of a {@link BytestreamSession} into a + * {@link CipherInputStream} and {@link CipherOutputStream}. + */ public class JetSecurityBytestreamSession extends JingleSecurityBytestreamSession { private final Cipher cipher; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/package-info.java index e3468c8c9..b8d6b9a39 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/component/package-info.java @@ -16,7 +16,8 @@ */ /** - * Smack's API for XEP-XXXX: Jingle Encrypted Transfers. + * Smack's API for XEP-XXXX: Jingle Encrypted Transports + * @see Proto-XEP * Internal classes. */ package org.jivesoftware.smackx.jet.component; 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 c976a99f2..d95d0c3aa 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 @@ -22,7 +22,7 @@ import org.jivesoftware.smackx.jet.component.JetSecurity; import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement; /** - * Implementation of the Jingle security element as specified in XEP-XXXX (Jingle Encrypted Transfers). + * Implementation of the Jingle security element as specified in XEP-XXXX (Jingle Encrypted Transports). * * * @@ -30,6 +30,7 @@ import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement; * <- You are here. * * + * @see Proto-XEP */ public class JetSecurityElement extends JingleContentSecurityElement { public static final String ATTR_CONTENT_NAME = "name"; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/package-info.java index 442412fc7..eb6661bca 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/element/package-info.java @@ -16,7 +16,8 @@ */ /** - * Smack's API for XEP-XXXX: Jingle Encrypted Transfers. + * Smack's API for XEP-XXXX: Jingle Encrypted Transports + * @see Proto-XEP * Elements. */ package org.jivesoftware.smackx.jet.element; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/package-info.java index 927a7b356..01c58f0ea 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jet/package-info.java @@ -16,6 +16,7 @@ */ /** - * Smack's API for XEP-XXXX: Jingle Encrypted Transfers. + * Smack's API for XEP-XXXX: Jingle Encrypted Transports. + * @see Proto-XEP */ package org.jivesoftware.smackx.jet;