diff --git a/pom.xml b/pom.xml index a6d53c3..e268f0d 100644 --- a/pom.xml +++ b/pom.xml @@ -36,8 +36,8 @@ org.bouncycastle - bcprov-jdk15on - 1.67 + bcprov-jdk18on + 1.86 diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java index 0a6a3bb..c2a8a3f 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java @@ -24,7 +24,7 @@ public class PacketTransformation { public PacketTransformation(byte[] ivStruct, byte[] fakeMac) { this.ivStruct = ivStruct; - this.cipher = new EAXBlockCipher(new AESEngine()); + this.cipher = new EAXBlockCipher(AESEngine.newInstance()); this.fakeMac = fakeMac; } @@ -86,20 +86,18 @@ public class PacketTransformation { int dataLen = packet.getBody().getSize(); ByteBuffer packetBuffer = packet.writeBody(ByteBuffer.allocate(dataLen).order(ByteOrder.BIG_ENDIAN)); - byte[] result; - int len; + // TS3 derives key and nonce from the packet id, so a resend encrypts under the same pair + // again. BouncyCastle refuses that on a cipher that has seen it, hence one per packet. + EAXBlockCipher cipher = new EAXBlockCipher(AESEngine.newInstance()); + cipher.init(true, cipherParameters); - synchronized (cipher) { - cipher.init(true, cipherParameters); + byte[] result = new byte[cipher.getOutputSize(dataLen)]; + int len = cipher.processBytes(packetBuffer.array(), 0, dataLen, result, 0); - result = new byte[cipher.getOutputSize(dataLen)]; - len = cipher.processBytes(packetBuffer.array(), 0, dataLen, result, 0); - - try { - len += cipher.doFinal(result, len); - } catch (InvalidCipherTextException e) { - throw new RuntimeException(e); - } + try { + len += cipher.doFinal(result, len); + } catch (InvalidCipherTextException e) { + throw new RuntimeException(e); } ByteBuffer outputBuffer = ByteBuffer.allocate(MAC_LEN + headerWithoutMac.length + (len - MAC_LEN)); diff --git a/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java b/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java index 03461b2..e521337 100644 --- a/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java +++ b/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java @@ -53,6 +53,10 @@ public class EncryptionTest extends TestCase { byte[] packetBytes = transformation.encrypt(packet).array(); transformation.decrypt(header, ByteBuffer.wrap(packetBytes), packet.getBody().getSize()); + + // A resend encrypts the same packet again, under the same key and nonce. + byte[] resent = transformation.encrypt(packet).array(); + assertTrue(java.util.Arrays.equals(packetBytes, resent)); } }