aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java')
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java209
1 files changed, 94 insertions, 115 deletions
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 cfa6a275e..6fbf8c3dc 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlMessage.java
@@ -37,69 +37,13 @@ public class XmppAxolotlMessage {
private static final String KEYTYPE = "AES";
private static final String CIPHERMODE = "AES/GCM/NoPadding";
private static final String PROVIDER = "BC";
-
+ private final List<XmppAxolotlSession.AxolotlKey> keys;
+ private final Jid from;
+ private final int sourceDeviceId;
private byte[] innerKey;
private byte[] ciphertext = null;
private byte[] authtagPlusInnerKey = null;
private byte[] iv = null;
- private final List<XmppAxolotlSession.AxolotlKey> keys;
- private final Jid from;
- private final int sourceDeviceId;
-
- public static class XmppAxolotlPlaintextMessage {
- private final String plaintext;
- private final String fingerprint;
-
- XmppAxolotlPlaintextMessage(String plaintext, String fingerprint) {
- this.plaintext = plaintext;
- this.fingerprint = fingerprint;
- }
-
- public String getPlaintext() {
- return plaintext;
- }
-
-
- public String getFingerprint() {
- return fingerprint;
- }
- }
-
- public static class XmppAxolotlKeyTransportMessage {
- private final String fingerprint;
- private final byte[] key;
- private final byte[] iv;
-
- XmppAxolotlKeyTransportMessage(String fingerprint, byte[] key, byte[] iv) {
- this.fingerprint = fingerprint;
- this.key = key;
- this.iv = iv;
- }
-
- public String getFingerprint() {
- return fingerprint;
- }
-
- public byte[] getKey() {
- return key;
- }
-
- public byte[] getIv() {
- return iv;
- }
- }
-
- public static int parseSourceId(final Element axolotlMessage) throws IllegalArgumentException {
- final Element header = axolotlMessage.findChild(HEADER);
- if (header == null) {
- throw new IllegalArgumentException("No header found");
- }
- try {
- return Integer.parseInt(header.getAttribute(SOURCEID));
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("invalid source id");
- }
- }
private XmppAxolotlMessage(final Element axolotlMessage, final Jid from) throws IllegalArgumentException {
this.from = from;
@@ -148,6 +92,18 @@ public class XmppAxolotlMessage {
this.innerKey = generateKey();
}
+ public static int parseSourceId(final Element axolotlMessage) throws IllegalArgumentException {
+ final Element header = axolotlMessage.findChild(HEADER);
+ if (header == null) {
+ throw new IllegalArgumentException("No header found");
+ }
+ try {
+ return Integer.parseInt(header.getAttribute(SOURCEID));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("invalid source id");
+ }
+ }
+
public static XmppAxolotlMessage fromElement(Element element, Jid from) {
return new XmppAxolotlMessage(element, from);
}
@@ -164,12 +120,28 @@ public class XmppAxolotlMessage {
}
private static byte[] generateIv() {
- SecureRandom random = new SecureRandom();
- byte[] iv = new byte[16];
+ final SecureRandom random = new SecureRandom();
+ byte[] iv = new byte[Config.TWELVE_BYTE_IV ? 12 : 16];
random.nextBytes(iv);
return iv;
}
+ private static byte[] getPaddedBytes(String plaintext) {
+ int plainLength = plaintext.getBytes().length;
+ int pad = Math.max(64, (plainLength / 32 + 1) * 32) - plainLength;
+ SecureRandom random = new SecureRandom();
+ int left = random.nextInt(pad);
+ int right = pad - left;
+ StringBuilder builder = new StringBuilder(plaintext);
+ for (int i = 0; i < left; ++i) {
+ builder.insert(0, random.nextBoolean() ? "\t" : " ");
+ }
+ for (int i = 0; i < right; ++i) {
+ builder.append(random.nextBoolean() ? "\t" : " ");
+ }
+ return builder.toString().getBytes();
+ }
+
public boolean hasPayload() {
return ciphertext != null;
}
@@ -189,39 +161,13 @@ public class XmppAxolotlMessage {
System.arraycopy(this.innerKey, 0, authtagPlusInnerKey, 0, this.innerKey.length);
this.ciphertext = ciphertext;
}
- } catch (NoSuchAlgorithmException e) {
- throw new CryptoFailedException(e);
- } catch (NoSuchPaddingException e) {
- throw new CryptoFailedException(e);
- } catch (InvalidKeyException e) {
- throw new CryptoFailedException(e);
- } catch (IllegalBlockSizeException e) {
- throw new CryptoFailedException(e);
- } catch (BadPaddingException e) {
- throw new CryptoFailedException(e);
- } catch (NoSuchProviderException e) {
- throw new CryptoFailedException(e);
- } catch (InvalidAlgorithmParameterException e) {
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
+ | IllegalBlockSizeException | BadPaddingException | NoSuchProviderException
+ | InvalidAlgorithmParameterException e) {
throw new CryptoFailedException(e);
}
}
- private static byte[] getPaddedBytes(String plaintext) {
- int plainLength = plaintext.getBytes().length;
- int pad = Math.max(64, (plainLength / 32 + 1) * 32) - plainLength;
- SecureRandom random = new SecureRandom();
- int left = random.nextInt(pad);
- int right = pad - left;
- StringBuilder builder = new StringBuilder(plaintext);
- for (int i = 0; i < left; ++i) {
- builder.insert(0, random.nextBoolean() ? "\t" : " ");
- }
- for (int i = 0; i < right; ++i) {
- builder.append(random.nextBoolean() ? "\t" : " ");
- }
- return builder.toString().getBytes();
- }
-
public Jid getFrom() {
return this.from;
}
@@ -297,19 +243,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;
+ if (key.length < 32) {
+ throw new OutdatedSenderException("Key did not contain auth tag. Sender needs to update their OMEMO client");
}
-
- Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
+ final int authTagLength = key.length - 16;
+ 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;
+
+ final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
@@ -318,22 +264,55 @@ public class XmppAxolotlMessage {
String plaintext = new String(cipher.doFinal(ciphertext));
plaintextMessage = new XmppAxolotlPlaintextMessage(Config.OMEMO_PADDING ? plaintext.trim() : plaintext, session.getFingerprint());
- } catch (NoSuchAlgorithmException e) {
- throw new CryptoFailedException(e);
- } catch (NoSuchPaddingException e) {
- throw new CryptoFailedException(e);
- } catch (InvalidKeyException e) {
- throw new CryptoFailedException(e);
- } catch (InvalidAlgorithmParameterException e) {
- throw new CryptoFailedException(e);
- } catch (IllegalBlockSizeException e) {
- throw new CryptoFailedException(e);
- } catch (BadPaddingException e) {
- throw new CryptoFailedException(e);
- } catch (NoSuchProviderException e) {
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException | NoSuchProviderException e) {
throw new CryptoFailedException(e);
}
}
return plaintextMessage;
}
+
+ public static class XmppAxolotlPlaintextMessage {
+ private final String plaintext;
+ private final String fingerprint;
+
+ XmppAxolotlPlaintextMessage(String plaintext, String fingerprint) {
+ this.plaintext = plaintext;
+ this.fingerprint = fingerprint;
+ }
+
+ public String getPlaintext() {
+ return plaintext;
+ }
+
+
+ public String getFingerprint() {
+ return fingerprint;
+ }
+ }
+
+ public static class XmppAxolotlKeyTransportMessage {
+ private final String fingerprint;
+ private final byte[] key;
+ private final byte[] iv;
+
+ XmppAxolotlKeyTransportMessage(String fingerprint, byte[] key, byte[] iv) {
+ this.fingerprint = fingerprint;
+ this.key = key;
+ this.iv = iv;
+ }
+
+ public String getFingerprint() {
+ return fingerprint;
+ }
+
+ public byte[] getKey() {
+ return key;
+ }
+
+ public byte[] getIv() {
+ return iv;
+ }
+ }
} \ No newline at end of file