mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-12-25 12:08:00 +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.Stanza;
|
||||
|
||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement;
|
||||
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.muc.MultiUserChat;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
||||
|
@ -89,7 +91,7 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
|||
* @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 WeakHashMap<XMPPConnection, WeakHashMap<Integer,OmemoManager>> INSTANCES = new WeakHashMap<>();
|
||||
|
@ -886,4 +888,44 @@ public final class OmemoManager extends Manager {
|
|||
}
|
||||
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