Refactor JET in order to match spec

This commit is contained in:
vanitasvitae 2017-08-16 16:42:11 +02:00
parent 5edd630fd0
commit eb413f30b1
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
9 changed files with 78 additions and 70 deletions

View File

@ -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 Logger LOGGER = Logger.getLogger(JetManager.class.getName());
private static final WeakHashMap<XMPPConnection, JetManager> INSTANCES = new WeakHashMap<>(); private static final WeakHashMap<XMPPConnection, JetManager> INSTANCES = new WeakHashMap<>();
private static final HashMap<String, JingleEncryptionMethod> encryptionMethods = new HashMap<>(); private static final HashMap<String, JingleEnvelopeManager> envelopeManagers = new HashMap<>();
private static final HashMap<String, ExtensionElementProvider<?>> encryptionMethodProviders = new HashMap<>(); private static final HashMap<String, ExtensionElementProvider<?>> envelopeProviders = new HashMap<>();
private final JingleManager jingleManager; private final JingleManager jingleManager;
@ -78,17 +78,17 @@ public final class JetManager extends Manager implements JingleDescriptionManage
return manager; return manager;
} }
public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEncryptionMethod method) throws Exception { public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEnvelopeManager envelopeManager) throws Exception {
return sendEncryptedFile(file, null, recipient, method); 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()) { if (file == null || !file.exists()) {
throw new IllegalArgumentException("File MUST NOT be null and MUST exist."); throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
} }
ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection()); 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); throw new SmackException.FeatureNotSupportedException(getNamespace(), recipient);
} }
@ -106,35 +106,35 @@ public final class JetManager extends Manager implements JingleDescriptionManage
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient); JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient);
content.setTransport(transportManager.createTransportForInitiator(content)); 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); content.setSecurity(security);
session.sendInitiate(connection()); session.sendInitiate(connection());
return offer; return offer;
} }
public void registerEncryptionMethod(JingleEncryptionMethod method) { public void registerEnvelopeManager(JingleEnvelopeManager method) {
encryptionMethods.put(method.getNamespace(), method); envelopeManagers.put(method.getJingleEnvelopeNamespace(), method);
} }
public void unregisterEncryptionMethod(String namespace) { public void unregisterEnvelopeManager(String namespace) {
encryptionMethods.remove(namespace); envelopeManagers.remove(namespace);
} }
public JingleEncryptionMethod getEncryptionMethod(String namespace) { public JingleEnvelopeManager getEnvelopeManager(String namespace) {
return encryptionMethods.get(namespace); return envelopeManagers.get(namespace);
} }
public static void registerEncryptionMethodProvider(String namespace, ExtensionElementProvider<?> provider) { public static void registerEnvelopeProvider(String namespace, ExtensionElementProvider<?> provider) {
encryptionMethodProviders.put(namespace, provider); envelopeProviders.put(namespace, provider);
} }
public static void removeEncryptionMethodProvider(String namespace) { public static void unregisterEnvelopeProvider(String namespace) {
encryptionMethodProviders.remove(namespace); envelopeProviders.remove(namespace);
} }
public static ExtensionElementProvider<?> getEncryptionMethodProvider(String namespace) { public static ExtensionElementProvider<?> getEnvelopeProvider(String namespace) {
return encryptionMethodProviders.get(namespace); return envelopeProviders.get(namespace);
} }
@Override @Override

View File

@ -28,11 +28,15 @@ import org.jxmpp.jid.FullJid;
/** /**
* Classes that implement this interface can be used to encrypt Jingle File Transfers. * 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 { class JingleEncryptionException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -44,5 +48,5 @@ public interface JingleEncryptionMethod {
XMPPConnection getConnection(); XMPPConnection getConnection();
String getNamespace(); String getJingleEnvelopeNamespace();
} }

View File

@ -31,7 +31,7 @@ import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.ciphers.AesGcmNoPadding; import org.jivesoftware.smackx.ciphers.AesGcmNoPadding;
import org.jivesoftware.smackx.jet.JetManager; 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.jet.element.JetSecurityElement;
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback; import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.component.JingleSecurity; import org.jivesoftware.smackx.jingle.component.JingleSecurity;
@ -49,7 +49,7 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
public static final String NAMESPACE_V0 = "urn:xmpp:jingle:jet:0"; public static final String NAMESPACE_V0 = "urn:xmpp:jingle:jet:0";
public static final String NAMESPACE = NAMESPACE_V0; public static final String NAMESPACE = NAMESPACE_V0;
private final String methodNamespace; private final String envelopeNamespace;
private AesGcmNoPadding aesKey; private AesGcmNoPadding aesKey;
private final ExtensionElement child; private final ExtensionElement child;
@ -59,26 +59,26 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
public JetSecurity(JetSecurityElement element) { public JetSecurity(JetSecurityElement element) {
super(); super();
this.child = element.getChild(); this.child = element.getChild();
this.methodNamespace = element.getMethodNamespace(); this.envelopeNamespace = element.getEnvelopeNamespace();
this.contentName = element.getContentName(); this.contentName = element.getContentName();
this.cipherName = element.getCipherName(); 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, throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidAlgorithmParameterException, InvalidKeyException, InterruptedException, InvalidAlgorithmParameterException, InvalidKeyException, InterruptedException,
JingleEncryptionMethod.JingleEncryptionException, SmackException.NotConnectedException, JingleEnvelopeManager.JingleEncryptionException, SmackException.NotConnectedException,
SmackException.NoResponseException { SmackException.NoResponseException {
this.methodNamespace = method.getNamespace(); this.envelopeNamespace = envelopeManager.getJingleEnvelopeNamespace();
this.aesKey = AesGcmNoPadding.createEncryptionKey(cipherName); this.aesKey = AesGcmNoPadding.createEncryptionKey(cipherName);
this.child = method.encryptJingleTransfer(recipient, aesKey.getKeyAndIv()); this.child = envelopeManager.encryptJingleTransfer(recipient, aesKey.getKeyAndIv());
this.contentName = contentName; this.contentName = contentName;
this.cipherName = cipherName; this.cipherName = cipherName;
} }
private void decryptEncryptionKey(JingleEncryptionMethod method, FullJid sender) private void decryptEncryptionKey(JingleEnvelopeManager method, FullJid sender)
throws InterruptedException, JingleEncryptionMethod.JingleEncryptionException, XMPPException.XMPPErrorException, throws InterruptedException, JingleEnvelopeManager.JingleEncryptionException, XMPPException.XMPPErrorException,
SmackException.NotConnectedException, SmackException.NoResponseException, NoSuchAlgorithmException, SmackException.NotConnectedException, SmackException.NoResponseException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException { InvalidAlgorithmParameterException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException {
byte[] keyAndIv = method.decryptJingleTransfer(sender, child); byte[] keyAndIv = method.decryptJingleTransfer(sender, child);
@ -125,18 +125,18 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
return; return;
} }
JingleEncryptionMethod method = JetManager.getInstanceFor(connection).getEncryptionMethod(getMethodNamespace()); JingleEnvelopeManager method = JetManager.getInstanceFor(connection).getEnvelopeManager(getEnvelopeNamespace());
if (method == null) { if (method == null) {
throw new AssertionError("No JingleEncryptionMethodManager found for " + getMethodNamespace()); throw new AssertionError("No JingleEncryptionMethodManager found for " + getEnvelopeNamespace());
} }
try { try {
decryptEncryptionKey(method, sender); 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); LOGGER.log(Level.SEVERE, "Could not decrypt security key: " + e, e);
} }
} }
public String getMethodNamespace() { public String getEnvelopeNamespace() {
return methodNamespace; return envelopeNamespace;
} }
} }

View File

@ -32,16 +32,16 @@ import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
* </jingle> * </jingle>
*/ */
public class JetSecurityElement extends JingleContentSecurityElement { public class JetSecurityElement extends JingleContentSecurityElement {
public static final String ATTR_NAME = "name"; public static final String ATTR_CONTENT_NAME = "name";
public static final String ATTR_TYPE = "type"; public static final String ATTR_ENVELOPE_TYPE = "type";
public static final String ATTR_CIPHER = "cipher"; public static final String ATTR_CIPHER_TYPE = "cipher";
private final ExtensionElement child; private final ExtensionElement child;
private final String name; private final String contentName;
private final String cipherName; private final String cipherName;
public JetSecurityElement(String name, String cipherName, ExtensionElement child) { public JetSecurityElement(String contentName, String cipherName, ExtensionElement child) {
this.name = name; this.contentName = contentName;
this.child = child; this.child = child;
this.cipherName = cipherName; this.cipherName = cipherName;
} }
@ -49,9 +49,9 @@ public class JetSecurityElement extends JingleContentSecurityElement {
@Override @Override
public CharSequence toXML() { public CharSequence toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this); XmlStringBuilder xml = new XmlStringBuilder(this);
xml.attribute(ATTR_NAME, name) xml.attribute(ATTR_CONTENT_NAME, contentName)
.attribute(ATTR_CIPHER, cipherName) .attribute(ATTR_CIPHER_TYPE, cipherName)
.attribute(ATTR_TYPE, child.getNamespace()); .attribute(ATTR_ENVELOPE_TYPE, child.getNamespace());
xml.rightAngleBracket(); xml.rightAngleBracket();
xml.element(child); xml.element(child);
xml.closeElement(this); xml.closeElement(this);
@ -63,7 +63,7 @@ public class JetSecurityElement extends JingleContentSecurityElement {
return JetSecurity.NAMESPACE; return JetSecurity.NAMESPACE;
} }
public String getMethodNamespace() { public String getEnvelopeNamespace() {
return child.getNamespace(); return child.getNamespace();
} }
@ -72,7 +72,7 @@ public class JetSecurityElement extends JingleContentSecurityElement {
} }
public String getContentName() { public String getContentName() {
return name; return contentName;
} }
public String getCipherName() { public String getCipherName() {

View File

@ -37,16 +37,16 @@ public class JetSecurityProvider extends JingleContentSecurityProvider<JetSecuri
@Override @Override
public JetSecurityElement parse(XmlPullParser parser, int initialDepth) throws Exception { public JetSecurityElement parse(XmlPullParser parser, int initialDepth) throws Exception {
String name = parser.getAttributeValue("", JetSecurityElement.ATTR_NAME); String name = parser.getAttributeValue("", JetSecurityElement.ATTR_CONTENT_NAME);
String cipher = parser.getAttributeValue("", JetSecurityElement.ATTR_CIPHER); String cipher = parser.getAttributeValue("", JetSecurityElement.ATTR_CIPHER_TYPE);
String type = parser.getAttributeValue("", JetSecurityElement.ATTR_TYPE); String type = parser.getAttributeValue("", JetSecurityElement.ATTR_ENVELOPE_TYPE);
ExtensionElement child; ExtensionElement child;
Objects.requireNonNull(type); Objects.requireNonNull(type);
Objects.requireNonNull(cipher); Objects.requireNonNull(cipher);
ExtensionElementProvider<?> encryptionElementProvider = ExtensionElementProvider<?> encryptionElementProvider =
JetManager.getEncryptionMethodProvider(type); JetManager.getEnvelopeProvider(type);
if (encryptionElementProvider != null) { if (encryptionElementProvider != null) {
child = encryptionElementProvider.parse(parser); child = encryptionElementProvider.parse(parser);

View File

@ -38,13 +38,13 @@ import org.xml.sax.SAXException;
public class JetElementTest extends SmackTestSuite { public class JetElementTest extends SmackTestSuite {
@Test @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); ExtensionElement child = new SecurityStub().encryptJingleTransfer(null, null);
JetSecurityElement element = new JetSecurityElement("content1", Aes128GcmNoPadding.NAMESPACE, child); JetSecurityElement element = new JetSecurityElement("content1", Aes128GcmNoPadding.NAMESPACE, child);
JetSecurity security = new JetSecurity(element); JetSecurity security = new JetSecurity(element);
assertEquals(SecurityStub.NAMESPACE, security.getMethodNamespace()); assertEquals(SecurityStub.NAMESPACE, security.getEnvelopeNamespace());
assertEquals(Aes128GcmNoPadding.NAMESPACE, element.getCipherName()); assertEquals(Aes128GcmNoPadding.NAMESPACE, element.getCipherName());
assertEquals(SecurityStub.NAMESPACE, element.getMethodNamespace()); assertEquals(SecurityStub.NAMESPACE, element.getEnvelopeNamespace());
assertEquals("content1", element.getContentName()); assertEquals("content1", element.getContentName());
String xml = "<security xmlns='" + JetSecurity.NAMESPACE + "' " + String xml = "<security xmlns='" + JetSecurity.NAMESPACE + "' " +
@ -56,7 +56,7 @@ public class JetElementTest extends SmackTestSuite {
assertXMLEqual(xml, security.getElement().toXML().toString()); assertXMLEqual(xml, security.getElement().toXML().toString());
} }
private static class SecurityStub implements JingleEncryptionMethod { private static class SecurityStub implements JingleEnvelopeManager {
public static final String NAMESPACE = "urn:xmpp:security-stub"; public static final String NAMESPACE = "urn:xmpp:security-stub";
@Override @Override
@ -80,7 +80,7 @@ public class JetElementTest extends SmackTestSuite {
} }
@Override @Override
public byte[] decryptJingleTransfer(FullJid sender, ExtensionElement encryptionElement) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { public byte[] decryptJingleTransfer(FullJid sender, ExtensionElement envelope) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException {
return new byte[0]; return new byte[0];
} }
@ -90,7 +90,7 @@ public class JetElementTest extends SmackTestSuite {
} }
@Override @Override
public String getNamespace() { public String getJingleEnvelopeNamespace() {
return NAMESPACE; return NAMESPACE;
} }
} }

View File

@ -298,7 +298,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
.setName(name) .setName(name)
.setCreator(creator) .setCreator(creator)
.setSenders(senders) .setSenders(senders)
.setDisposition(disposition);; .setDisposition(disposition);
if (description != null) { if (description != null) {
builder.setDescription(description.getElement()); builder.setDescription(description.getElement());

View File

@ -80,7 +80,7 @@ public class JetIntegrationTest extends AbstractOmemoIntegrationTest {
jb = JetManager.getInstanceFor(conTwo); jb = JetManager.getInstanceFor(conTwo);
ia = JingleIBBTransportManager.getInstanceFor(conOne); ia = JingleIBBTransportManager.getInstanceFor(conOne);
ib = JingleIBBTransportManager.getInstanceFor(conTwo); ib = JingleIBBTransportManager.getInstanceFor(conTwo);
JetManager.registerEncryptionMethodProvider(OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL, new OmemoVAxolotlProvider()); JetManager.registerEnvelopeProvider(OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL, new OmemoVAxolotlProvider());
} }
@SmackIntegrationTest @SmackIntegrationTest
@ -97,8 +97,8 @@ public class JetIntegrationTest extends AbstractOmemoIntegrationTest {
unidirectionalTrust(oa, ob); unidirectionalTrust(oa, ob);
unidirectionalTrust(ob, oa); unidirectionalTrust(ob, oa);
ja.registerEncryptionMethod(oa); ja.registerEnvelopeManager(oa);
jb.registerEncryptionMethod(ob); jb.registerEnvelopeManager(ob);
File source = prepareNewTestFile("source"); File source = prepareNewTestFile("source");
final File target = new File(tempDir, "target"); final File target = new File(tempDir, "target");

View File

@ -46,7 +46,7 @@ import org.jivesoftware.smackx.carbons.CarbonManager;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement; import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement;
import org.jivesoftware.smackx.hints.element.StoreHint; import org.jivesoftware.smackx.hints.element.StoreHint;
import org.jivesoftware.smackx.jet.JingleEncryptionMethod; import org.jivesoftware.smackx.jet.JingleEnvelopeManager;
import org.jivesoftware.smackx.mam.MamManager; import org.jivesoftware.smackx.mam.MamManager;
import org.jivesoftware.smackx.muc.MultiUserChat; import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager; import org.jivesoftware.smackx.muc.MultiUserChatManager;
@ -91,7 +91,7 @@ import org.jxmpp.stringprep.XmppStringprepException;
* @author Paul Schaub * @author Paul Schaub
*/ */
public final class OmemoManager extends Manager implements JingleEncryptionMethod { public final class OmemoManager extends Manager implements JingleEnvelopeManager {
private static final Logger LOGGER = Logger.getLogger(OmemoManager.class.getName()); private static final Logger LOGGER = Logger.getLogger(OmemoManager.class.getName());
private static final WeakHashMap<XMPPConnection, WeakHashMap<Integer,OmemoManager>> INSTANCES = new WeakHashMap<>(); private static final WeakHashMap<XMPPConnection, WeakHashMap<Integer,OmemoManager>> INSTANCES = new WeakHashMap<>();
@ -760,11 +760,15 @@ public final class OmemoManager extends Manager implements JingleEncryptionMetho
return connection(); return connection();
} }
@Override public static String getNamespace() {
public String getNamespace() {
return OMEMO_NAMESPACE_V_AXOLOTL; return OMEMO_NAMESPACE_V_AXOLOTL;
} }
@Override
public String getJingleEnvelopeNamespace() {
return getNamespace();
}
/** /**
* Return the OMEMO service object. * Return the OMEMO service object.
* *
@ -870,13 +874,13 @@ public final class OmemoManager extends Manager implements JingleEncryptionMetho
} }
@Override @Override
public byte[] decryptJingleTransfer(FullJid sender, ExtensionElement encryptionElement) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { public byte[] decryptJingleTransfer(FullJid sender, ExtensionElement envelope) throws JingleEncryptionException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException {
if (!encryptionElement.getNamespace().equals(OMEMO_NAMESPACE_V_AXOLOTL) if (!envelope.getNamespace().equals(OMEMO_NAMESPACE_V_AXOLOTL)
|| !encryptionElement.getElementName().equals(OmemoElement.ENCRYPTED)) { || !envelope.getElementName().equals(OmemoElement.ENCRYPTED)) {
throw new IllegalArgumentException("Passed ExtensionElement MUST be an OmemoElement!"); throw new IllegalArgumentException("Passed ExtensionElement MUST be an OmemoElement!");
} }
OmemoElement omemoElement = (OmemoElement) encryptionElement; OmemoElement omemoElement = (OmemoElement) envelope;
Message pseudoMessage = new Message(); Message pseudoMessage = new Message();
pseudoMessage.setFrom(sender.asBareJid()); pseudoMessage.setFrom(sender.asBareJid());
pseudoMessage.addExtension(omemoElement); pseudoMessage.addExtension(omemoElement);