aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2017-01-14 20:30:47 +0100
committerChristian Schneppe <christian@pix-art.de>2017-01-14 20:30:47 +0100
commit51de021fb736f4ef5921d94cd0406f768915af54 (patch)
tree785d57900d6cef1ae9ff1c44800fca01652c7339 /src/main
parentbba3ad747bd456aec8e699c0986926de25f8a9a7 (diff)
treat omemo keys >= 32 bytes as containing auth tag. add config flag to put auth tag in key
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/de/pixart/messenger/Config.java1
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java46
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java28
3 files changed, 52 insertions, 23 deletions
diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java
index cd708213d..9141f3944 100644
--- a/src/main/java/de/pixart/messenger/Config.java
+++ b/src/main/java/de/pixart/messenger/Config.java
@@ -93,6 +93,7 @@ public final class Config {
public static final long OMEMO_AUTO_EXPIRY = 7 * MILLISECONDS_IN_DAY; // delete old OMEMO devices after 7 days od inactivity
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 int MAX_DISPLAY_MESSAGE_CHARS = 4096;
diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
index 16a4919fc..11f51eaa2 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
@@ -1003,14 +1003,12 @@ 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);
@@ -1019,26 +1017,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;
@@ -1065,8 +1063,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/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java
index 94064a661..fa91ee122 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java
@@ -40,6 +40,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;
@@ -164,6 +165,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) {
@@ -200,7 +209,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);
}
@@ -252,6 +266,18 @@ 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);