aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2017-01-09 21:47:07 +0100
committerDaniel Gultsch <daniel@gultsch.de>2017-01-09 21:47:07 +0100
commitf0c3b31a42ac6269a0ca299f2fa470586f6120be (patch)
tree5892421a1f2144dd4ac4b2becab641b10a179a57 /src
parenta1cb855739b96c29d91225d125d3018a5f665468 (diff)
treat omemo keys >= 32 bytes as containing auth tag. add config flag to put auth tag in key
Diffstat (limited to 'src')
-rw-r--r--src/main/java/eu/siacs/conversations/Config.java1
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java47
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java31
3 files changed, 54 insertions, 25 deletions
diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java
index 91bc1431..1a992e48 100644
--- a/src/main/java/eu/siacs/conversations/Config.java
+++ b/src/main/java/eu/siacs/conversations/Config.java
@@ -83,6 +83,7 @@ public final class Config {
public static final long OMEMO_AUTO_EXPIRY = 7 * MILLISECONDS_IN_DAY;
public static final boolean REMOVE_BROKEN_DEVICES = false;
public static final boolean OMEMO_PADDING = false;
+ public static boolean PUT_AUTH_TAG_INTO_KEY = false;
public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb
diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
index 7f54ce2f..65ac7b0a 100644
--- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
@@ -1007,14 +1007,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
}
@Nullable
- private XmppAxolotlMessage buildHeader(Conversation conversation) {
- final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(
- account.getJid().toBareJid(), getOwnDeviceId());
-
+ private boolean buildHeader(XmppAxolotlMessage axolotlMessage, Conversation conversation) {
Set<XmppAxolotlSession> remoteSessions = findSessionsForConversation(conversation);
Collection<XmppAxolotlSession> ownSessions = findOwnSessions();
if (remoteSessions.isEmpty()) {
- return null;
+ return false;
}
for (XmppAxolotlSession session : remoteSessions) {
axolotlMessage.addDevice(session);
@@ -1023,26 +1020,26 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
axolotlMessage.addDevice(session);
}
- return axolotlMessage;
+ return true;
}
@Nullable
public XmppAxolotlMessage encrypt(Message message) {
- XmppAxolotlMessage axolotlMessage = buildHeader(message.getConversation());
-
- if (axolotlMessage != null) {
- final String content;
- if (message.hasFileOnRemoteHost()) {
- content = message.getFileParams().url.toString();
- } else {
- content = message.getBody();
- }
- try {
- axolotlMessage.encrypt(content);
- } catch (CryptoFailedException e) {
- Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage());
- return null;
- }
+ final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().toBareJid(), getOwnDeviceId());
+ final String content;
+ if (message.hasFileOnRemoteHost()) {
+ content = message.getFileParams().url.toString();
+ } else {
+ content = message.getBody();
+ }
+ try {
+ axolotlMessage.encrypt(content);
+ } catch (CryptoFailedException e) {
+ Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage());
+ return null;
+ }
+ if (!buildHeader(axolotlMessage,message.getConversation())) {
+ return null;
}
return axolotlMessage;
@@ -1069,8 +1066,12 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
executor.execute(new Runnable() {
@Override
public void run() {
- XmppAxolotlMessage axolotlMessage = buildHeader(conversation);
- onMessageCreatedCallback.run(axolotlMessage);
+ final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().toBareJid(), getOwnDeviceId());
+ if (buildHeader(axolotlMessage,conversation)) {
+ onMessageCreatedCallback.run(axolotlMessage);
+ } else {
+ onMessageCreatedCallback.run(null);
+ }
}
});
}
diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java
index 2d6bba55..1f532370 100644
--- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java
+++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java
@@ -3,7 +3,6 @@ package eu.siacs.conversations.crypto.axolotl;
import android.util.Base64;
import android.util.Log;
-import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@@ -24,6 +23,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import eu.siacs.conversations.Config;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -42,6 +42,7 @@ public class XmppAxolotlMessage {
private byte[] innerKey;
private byte[] ciphertext = null;
+ private byte[] authtagPlusInnerKey = null;
private byte[] iv = null;
private final Map<Integer, XmppAxolotlSession.AxolotlKey> keys;
private final Jid from;
@@ -166,6 +167,14 @@ public class XmppAxolotlMessage {
Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
this.ciphertext = cipher.doFinal(Config.OMEMO_PADDING ? getPaddedBytes(plaintext) : plaintext.getBytes());
+ if (Config.PUT_AUTH_TAG_INTO_KEY && this.ciphertext != null) {
+ this.authtagPlusInnerKey = new byte[16+16];
+ byte[] ciphertext = new byte[this.ciphertext.length - 16];
+ System.arraycopy(this.ciphertext,0,ciphertext,0,ciphertext.length);
+ System.arraycopy(this.ciphertext,ciphertext.length,authtagPlusInnerKey,16,16);
+ System.arraycopy(this.innerKey,0,authtagPlusInnerKey,0,this.innerKey.length);
+ this.ciphertext = ciphertext;
+ }
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| IllegalBlockSizeException | BadPaddingException | NoSuchProviderException
| InvalidAlgorithmParameterException e) {
@@ -202,7 +211,12 @@ public class XmppAxolotlMessage {
}
public void addDevice(XmppAxolotlSession session) {
- XmppAxolotlSession.AxolotlKey key = session.processSending(innerKey);
+ XmppAxolotlSession.AxolotlKey key;
+ if (authtagPlusInnerKey != null) {
+ key = session.processSending(authtagPlusInnerKey);
+ } else {
+ key = session.processSending(innerKey);
+ }
if (key != null) {
keys.put(session.getRemoteAddress().getDeviceId(), key);
}
@@ -254,6 +268,19 @@ public class XmppAxolotlMessage {
byte[] key = unpackKey(session, sourceDeviceId);
if (key != null) {
try {
+
+ if (key.length >= 32) {
+ int authtaglength = key.length - 16;
+ Log.d(Config.LOGTAG,"found auth tag as part of omemo key");
+ byte[] newCipherText = new byte[key.length - 16 + ciphertext.length];
+ byte[] newKey = new byte[16];
+ System.arraycopy(ciphertext, 0, newCipherText, 0, ciphertext.length);
+ System.arraycopy(key, 16, newCipherText, ciphertext.length, authtaglength);
+ System.arraycopy(key,0,newKey,0,newKey.length);
+ ciphertext = newCipherText;
+ key = newKey;
+ }
+
Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER);
SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE);
IvParameterSpec ivSpec = new IvParameterSpec(iv);