mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Add first JET classes
This commit is contained in:
parent
760571c3a0
commit
3c8542c85a
6 changed files with 244 additions and 1 deletions
|
@ -0,0 +1,48 @@
|
||||||
|
package org.jivesoftware.smackx.jingle_encrypted_transfer;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.Manager;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by vanitas on 13.07.17.
|
||||||
|
*/
|
||||||
|
public class JingleEncryptedTransferManager extends Manager {
|
||||||
|
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:jingle:jet:0";
|
||||||
|
|
||||||
|
private static final WeakHashMap<XMPPConnection, JingleEncryptedTransferManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
|
private static final Map<String, JingleEncryptionMethod> encryptionProviders = new HashMap<>();
|
||||||
|
|
||||||
|
private JingleEncryptedTransferManager(XMPPConnection connection) {
|
||||||
|
super(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JingleEncryptedTransferManager getInstanceFor(XMPPConnection connection) {
|
||||||
|
JingleEncryptedTransferManager manager = INSTANCES.get(connection);
|
||||||
|
|
||||||
|
if (manager == null) {
|
||||||
|
manager = new JingleEncryptedTransferManager(connection);
|
||||||
|
INSTANCES.put(connection, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void registerEncryptionProvider(String namespace, JingleEncryptionMethod provider) {
|
||||||
|
encryptionProviders.put(namespace, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterEncryptionProvider(String namespace) {
|
||||||
|
encryptionProviders.remove(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JingleEncryptionMethod getEncryptionProvider(String namespace) {
|
||||||
|
return encryptionProviders.get(namespace);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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_encrypted_transfer;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.FullJid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by vanitas on 13.07.17.
|
||||||
|
*/
|
||||||
|
public interface JingleEncryptionMethod {
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
ExtensionElementProvider<ExtensionElement> getEncryptionElementProvider();
|
||||||
|
|
||||||
|
class JingleEncryptionException extends Exception {
|
||||||
|
public JingleEncryptionException(Throwable throwable) {
|
||||||
|
super(throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.jivesoftware.smackx.jingle_encrypted_transfer;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by vanitas on 13.07.17.
|
||||||
|
*/
|
||||||
|
public class JingleEncryptionMethodManager {
|
||||||
|
|
||||||
|
public static HashMap<String, ExtensionElementProvider<ExtensionElement>> securityKeyTransportProviders = new HashMap<>();
|
||||||
|
|
||||||
|
private JingleEncryptionMethodManager() {
|
||||||
|
// $(man true)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerSecurityKeyTransportProvider(String namespace, ExtensionElementProvider<ExtensionElement> provider) {
|
||||||
|
securityKeyTransportProviders.put(namespace, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtensionElementProvider<ExtensionElement> getSecurityKeyTransportProvider(String namespace) {
|
||||||
|
return securityKeyTransportProviders.get(namespace);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.jivesoftware.smackx.jingle_encrypted_transfer.element;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
import org.jivesoftware.smackx.jingle_encrypted_transfer.JingleEncryptedTransferManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by vanitas on 13.07.17.
|
||||||
|
*/
|
||||||
|
public class SecurityElement implements ExtensionElement {
|
||||||
|
public static final String ELEMENT = "security";
|
||||||
|
public static final String ATTR_NAME = "name";
|
||||||
|
public static final String ATTR_TYPE = "type";
|
||||||
|
|
||||||
|
private final ExtensionElement child;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public SecurityElement(String name, ExtensionElement child) {
|
||||||
|
this.name = name;
|
||||||
|
this.child = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence toXML() {
|
||||||
|
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||||
|
xml.attribute(ATTR_NAME, name).attribute(ATTR_TYPE, child.getNamespace());
|
||||||
|
xml.rightAngleBracket();
|
||||||
|
xml.element(child);
|
||||||
|
xml.closeElement(this);
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return JingleEncryptedTransferManager.NAMESPACE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.jivesoftware.smackx.jingle_encrypted_transfer.provider;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||||
|
import org.jivesoftware.smack.util.Objects;
|
||||||
|
import org.jivesoftware.smackx.jingle_encrypted_transfer.JingleEncryptedTransferManager;
|
||||||
|
import org.jivesoftware.smackx.jingle_encrypted_transfer.JingleEncryptionMethodManager;
|
||||||
|
import org.jivesoftware.smackx.jingle_encrypted_transfer.element.SecurityElement;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by vanitas on 13.07.17.
|
||||||
|
*/
|
||||||
|
public class SecurityProvider extends ExtensionElementProvider<SecurityElement> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(SecurityProvider.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SecurityElement parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||||
|
String name = parser.getAttributeValue(JingleEncryptedTransferManager.NAMESPACE, SecurityElement.ATTR_NAME);
|
||||||
|
String type = parser.getAttributeValue(JingleEncryptedTransferManager.NAMESPACE, SecurityElement.ATTR_TYPE);
|
||||||
|
ExtensionElement child;
|
||||||
|
|
||||||
|
Objects.requireNonNull(type);
|
||||||
|
|
||||||
|
ExtensionElementProvider<ExtensionElement> encryptionElementProvider =
|
||||||
|
JingleEncryptionMethodManager.getSecurityKeyTransportProvider(type);
|
||||||
|
|
||||||
|
if (encryptionElementProvider != null) {
|
||||||
|
child = encryptionElementProvider.parse(parser);
|
||||||
|
} else {
|
||||||
|
LOGGER.log(Level.WARNING, "Unknown child element in SecurityElement: " + type);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SecurityElement(name, child);
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,10 +42,12 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
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.jingle_encrypted_transfer.JingleEncryptionMethod;
|
||||||
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;
|
||||||
|
@ -89,7 +91,7 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
* @author Paul Schaub
|
* @author Paul Schaub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public final class OmemoManager extends Manager {
|
public final class OmemoManager extends Manager implements JingleEncryptionMethod {
|
||||||
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<>();
|
||||||
|
@ -886,4 +888,44 @@ public final class OmemoManager extends Manager {
|
||||||
}
|
}
|
||||||
return omemoCarbonCopyListener;
|
return omemoCarbonCopyListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionElement encryptJingleTransfer(FullJid recipient, byte[] keyData) throws JingleEncryptionException, InterruptedException, NoSuchAlgorithmException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
|
BareJid bareJid = recipient.asBareJid();
|
||||||
|
Message EncryptedMessage;
|
||||||
|
try {
|
||||||
|
EncryptedMessage = encrypt(bareJid, Base64.encodeToString(keyData));
|
||||||
|
} catch (CryptoFailedException | UndecidedOmemoIdentityException | CannotEstablishOmemoSessionException e) {
|
||||||
|
throw new JingleEncryptionException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtensionElement encryptionElement = EncryptedMessage.getExtension(OmemoElement.ENCRYPTED, OMEMO_NAMESPACE_V_AXOLOTL);
|
||||||
|
if (encryptionElement == null) {
|
||||||
|
throw new AssertionError("OmemoElement MUST NOT be null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptionElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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)) {
|
||||||
|
throw new IllegalArgumentException("Passed ExtensionElement MUST be an OmemoElement!");
|
||||||
|
}
|
||||||
|
|
||||||
|
OmemoElement omemoElement = (OmemoElement) encryptionElement;
|
||||||
|
Message pseudoMessage = new Message();
|
||||||
|
pseudoMessage.setFrom(sender.asBareJid());
|
||||||
|
pseudoMessage.addExtension(omemoElement);
|
||||||
|
|
||||||
|
ClearTextMessage decryptedPseudoMessage;
|
||||||
|
try {
|
||||||
|
decryptedPseudoMessage = decrypt(sender.asBareJid(), pseudoMessage);
|
||||||
|
} catch (CryptoFailedException | CorruptedOmemoKeyException | NoRawSessionException e) {
|
||||||
|
throw new JingleEncryptionException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base64.decode(decryptedPseudoMessage.getBody());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue