mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-09-27 10:19:33 +02:00
214 lines
7.2 KiB
Java
214 lines
7.2 KiB
Java
/**
|
|
*
|
|
* 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.omemo;
|
|
|
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.BODY_OMEMO_HINT;
|
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO;
|
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
|
|
import org.jivesoftware.smack.packet.Message;
|
|
|
|
import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement;
|
|
import org.jivesoftware.smackx.hints.element.StoreHint;
|
|
import org.jivesoftware.smackx.omemo.element.OmemoElement;
|
|
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
|
|
import org.jivesoftware.smackx.omemo.trust.OmemoFingerprint;
|
|
|
|
import org.jxmpp.jid.Jid;
|
|
|
|
public class OmemoMessage {
|
|
|
|
private final OmemoElement element;
|
|
private final byte[] messageKey, iv;
|
|
|
|
OmemoMessage(OmemoElement element, byte[] key, byte[] iv) {
|
|
this.element = element;
|
|
this.messageKey = key;
|
|
this.iv = iv;
|
|
}
|
|
|
|
/**
|
|
* Return the original OmemoElement (<encrypted/>).
|
|
*
|
|
* @return omemoElement TODO javadoc me please
|
|
*/
|
|
public OmemoElement getElement() {
|
|
return element;
|
|
}
|
|
|
|
/**
|
|
* Return the messageKey (or transported key in case of a KeyTransportMessage).
|
|
*
|
|
* @return key TODO javadoc me please
|
|
*/
|
|
public byte[] getKey() {
|
|
return messageKey.clone();
|
|
}
|
|
|
|
/**
|
|
* Return the initialization vector belonging to the key.
|
|
* @return initialization vector
|
|
*/
|
|
public byte[] getIv() {
|
|
return iv.clone();
|
|
}
|
|
|
|
/**
|
|
* Outgoing OMEMO message.
|
|
*/
|
|
public static class Sent extends OmemoMessage {
|
|
private final Set<OmemoDevice> intendedDevices = new HashSet<>();
|
|
private final HashMap<OmemoDevice, Throwable> skippedDevices = new HashMap<>();
|
|
|
|
/**
|
|
* Create a new outgoing OMEMO message.
|
|
* @param element OmemoElement
|
|
* @param key messageKey (or transported key)
|
|
* @param iv initialization vector belonging to key
|
|
* @param intendedDevices devices the client intended to encrypt the message for
|
|
* @param skippedDevices devices which were skipped during encryption process because encryption
|
|
* failed for some reason
|
|
*/
|
|
Sent(OmemoElement element, byte[] key, byte[] iv, Set<OmemoDevice> intendedDevices, HashMap<OmemoDevice, Throwable> skippedDevices) {
|
|
super(element, key, iv);
|
|
this.intendedDevices.addAll(intendedDevices);
|
|
this.skippedDevices.putAll(skippedDevices);
|
|
}
|
|
|
|
/**
|
|
* Return a list of all devices the sender originally intended to encrypt the message for.
|
|
* @return list of intended recipients.
|
|
*/
|
|
public Set<OmemoDevice> getIntendedDevices() {
|
|
return intendedDevices;
|
|
}
|
|
|
|
/**
|
|
* Return a map of all skipped recipients and the reasons for skipping.
|
|
* @return map of skipped recipients and reasons for that.
|
|
*/
|
|
public HashMap<OmemoDevice, Throwable> getSkippedDevices() {
|
|
return skippedDevices;
|
|
}
|
|
|
|
/**
|
|
* Determine, if some recipients were skipped during encryption.
|
|
* @return true if recipients were skipped.
|
|
*/
|
|
public boolean isMissingRecipients() {
|
|
return !getSkippedDevices().isEmpty();
|
|
}
|
|
|
|
/**
|
|
* Return the OmemoElement wrapped in a Message ready to be sent.
|
|
* The message is addressed to recipient, contains the OmemoElement
|
|
* as well as an optional clear text hint as body, a MAM storage hint
|
|
* and an EME hint about OMEMO encryption.
|
|
*
|
|
* @param recipient recipient for the to-field of the message.
|
|
* @return Message TODO javadoc me please
|
|
*/
|
|
public Message asMessage(Jid recipient) {
|
|
|
|
Message messageStanza = new Message(recipient, Message.Type.chat);
|
|
messageStanza.addExtension(getElement());
|
|
|
|
if (OmemoConfiguration.getAddOmemoHintBody()) {
|
|
messageStanza.setBody(BODY_OMEMO_HINT);
|
|
}
|
|
|
|
StoreHint.set(messageStanza);
|
|
messageStanza.addExtension(new ExplicitMessageEncryptionElement(OMEMO_NAMESPACE_V_AXOLOTL, OMEMO));
|
|
|
|
return messageStanza;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Incoming OMEMO message.
|
|
*/
|
|
public static class Received extends OmemoMessage {
|
|
private final String message;
|
|
private final OmemoFingerprint sendersFingerprint;
|
|
private final OmemoDevice senderDevice;
|
|
private final boolean preKeyMessage;
|
|
|
|
/**
|
|
* Create a new incoming OMEMO message.
|
|
* @param element original OmemoElement
|
|
* @param key message key (or transported key)
|
|
* @param iv respective initialization vector
|
|
* @param body decrypted body
|
|
* @param sendersFingerprint OmemoFingerprint of the senders identityKey
|
|
* @param senderDevice OmemoDevice of the sender
|
|
* @param preKeyMessage if this was a preKeyMessage or not
|
|
*/
|
|
Received(OmemoElement element, byte[] key, byte[] iv, String body, OmemoFingerprint sendersFingerprint, OmemoDevice senderDevice, boolean preKeyMessage) {
|
|
super(element, key, iv);
|
|
this.message = body;
|
|
this.sendersFingerprint = sendersFingerprint;
|
|
this.senderDevice = senderDevice;
|
|
this.preKeyMessage = preKeyMessage;
|
|
}
|
|
|
|
/**
|
|
* Return the decrypted body of the message.
|
|
* @return decrypted body
|
|
*/
|
|
public String getBody() {
|
|
return message;
|
|
}
|
|
|
|
/**
|
|
* Return the fingerprint of the messages sender device.
|
|
* @return fingerprint of sender
|
|
*/
|
|
public OmemoFingerprint getSendersFingerprint() {
|
|
return sendersFingerprint;
|
|
}
|
|
|
|
/**
|
|
* Return the OmemoDevice which sent the message.
|
|
* @return senderDevice TODO javadoc me please
|
|
*/
|
|
public OmemoDevice getSenderDevice() {
|
|
return senderDevice;
|
|
}
|
|
|
|
/**
|
|
* Return true, if this message was sent as a preKeyMessage.
|
|
* @return preKeyMessage or not
|
|
*/
|
|
boolean isPreKeyMessage() {
|
|
return preKeyMessage;
|
|
}
|
|
|
|
/**
|
|
* Return true, if the message was a KeyTransportMessage.
|
|
* A KeyTransportMessage is a OmemoMessage without a payload.
|
|
* @return keyTransportMessage?
|
|
*/
|
|
public boolean isKeyTransportMessage() {
|
|
return message == null;
|
|
}
|
|
}
|
|
}
|