From 23bad12f8c47aaa3d9718c1dff89f14f86c97546 Mon Sep 17 00:00:00 2001 From: P0nk Date: Tue, 15 Jun 2021 22:12:23 +0200 Subject: [PATCH] Netty WIP Implementing ByteBuf backed In/OutPacket first in a separate branch --- pom.xml | 45 +++++--- src/main/java/client/MapleClient.java | 26 ++++- .../java/constants/net/ServerConstants.java | 2 +- src/main/java/net/MapleServerHandler.java | 7 +- src/main/java/net/netty/ClientCyphers.java | 28 +++++ .../java/net/netty/ClientInitializer.java | 20 ++++ src/main/java/net/netty/InPacket.java | 4 + .../java/net/netty/InitializationVector.java | 27 +++++ .../netty/InvalidPacketHeaderException.java | 14 +++ src/main/java/net/netty/OutPacket.java | 5 + src/main/java/net/netty/PacketDecoder.java | 48 ++++++++ src/main/java/net/netty/PacketEncoder.java | 28 +++++ src/main/java/tools/MapleAESOFB.java | 106 +++++++++++------- src/main/java/tools/MaplePacketCreator.java | 7 +- 14 files changed, 301 insertions(+), 66 deletions(-) create mode 100644 src/main/java/net/netty/ClientCyphers.java create mode 100644 src/main/java/net/netty/ClientInitializer.java create mode 100644 src/main/java/net/netty/InPacket.java create mode 100644 src/main/java/net/netty/InitializationVector.java create mode 100644 src/main/java/net/netty/InvalidPacketHeaderException.java create mode 100644 src/main/java/net/netty/OutPacket.java create mode 100644 src/main/java/net/netty/PacketDecoder.java create mode 100644 src/main/java/net/netty/PacketEncoder.java diff --git a/pom.xml b/pom.xml index 7df287a87f..488df03163 100644 --- a/pom.xml +++ b/pom.xml @@ -22,21 +22,6 @@ - - com.zaxxer - HikariCP - 4.0.3 - - - org.apache.mina - mina-core - 2.1.3 - - - mysql - mysql-connector-java - 8.0.23 - com.esotericsoftware.yamlbeans yamlbeans @@ -48,6 +33,36 @@ 1.0 + + + com.zaxxer + HikariCP + 4.0.3 + + + mysql + mysql-connector-java + 8.0.23 + + + + + org.apache.mina + mina-core + 2.1.3 + + + io.netty + netty-transport + 4.1.65.Final + + + io.netty + netty-codec + 4.1.65.Final + + + org.slf4j diff --git a/src/main/java/client/MapleClient.java b/src/main/java/client/MapleClient.java index f158759f96..203a47b826 100644 --- a/src/main/java/client/MapleClient.java +++ b/src/main/java/client/MapleClient.java @@ -24,6 +24,10 @@ package client; import client.inventory.MapleInventoryType; import config.YamlConfig; import constants.game.GameConstants; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import net.netty.ClientCyphers; +import net.netty.InvalidPacketHeaderException; import net.server.Server; import net.server.audit.locks.MonitoredLockType; import net.server.audit.locks.factory.MonitoredReentrantLockFactory; @@ -61,7 +65,7 @@ import java.util.*; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Lock; -public class MapleClient { +public class MapleClient extends ChannelInboundHandlerAdapter { public static final int LOGIN_NOTLOGGEDIN = 0; public static final int LOGIN_SERVER_TRANSITION = 1; @@ -118,12 +122,32 @@ public class MapleClient { return lastPacket; } + public MapleClient(ClientCyphers cyphers) { + this.send = cyphers.getSendCypher(); + this.receive = cyphers.getReceiveCypher(); + this.session = null; // TODO remove once the other constructor is removed + } + public MapleClient(MapleAESOFB send, MapleAESOFB receive, IoSession session) { this.send = send; this.receive = receive; this.session = session; } + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + super.channelRead(ctx, msg); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (cause instanceof InvalidPacketHeaderException) { + // TODO close session through MapleSessionCoordinator + } + + super.exceptionCaught(ctx, cause); + } + public MapleAESOFB getReceiveCrypto() { return receive; } diff --git a/src/main/java/constants/net/ServerConstants.java b/src/main/java/constants/net/ServerConstants.java index 2905adbccd..9b5f6b1d8b 100644 --- a/src/main/java/constants/net/ServerConstants.java +++ b/src/main/java/constants/net/ServerConstants.java @@ -3,7 +3,7 @@ package constants.net; public class ServerConstants { //Server Version - public static short VERSION = 83; + public static final short VERSION = 83; //Debug Variables public static int[] DEBUG_VALUES = new int[10]; // Field designed for packet testing purposes diff --git a/src/main/java/net/MapleServerHandler.java b/src/main/java/net/MapleServerHandler.java index edca4bfda8..554366803d 100644 --- a/src/main/java/net/MapleServerHandler.java +++ b/src/main/java/net/MapleServerHandler.java @@ -24,6 +24,7 @@ package net; import client.MapleClient; import config.YamlConfig; import constants.net.ServerConstants; +import net.netty.InitializationVector; import net.server.Server; import net.server.audit.LockCollector; import net.server.audit.locks.MonitoredLockType; @@ -130,10 +131,8 @@ public class MapleServerHandler extends IoHandlerAdapter { FilePrinter.print(FilePrinter.SESSION, "IoSession with " + session.getRemoteAddress() + " opened on " + sdf.format(Calendar.getInstance().getTime()), false); } - byte[] ivRecv = {70, 114, 122, 82}; - byte[] ivSend = {82, 48, 120, 115}; - ivRecv[3] = (byte) (Math.random() * 255); - ivSend[3] = (byte) (Math.random() * 255); + final InitializationVector ivSend = InitializationVector.generateSend(); + final InitializationVector ivRecv = InitializationVector.generateReceive(); MapleAESOFB sendCypher = new MapleAESOFB(ivSend, (short) (0xFFFF - ServerConstants.VERSION)); MapleAESOFB recvCypher = new MapleAESOFB(ivRecv, ServerConstants.VERSION); MapleClient client = new MapleClient(sendCypher, recvCypher, session); diff --git a/src/main/java/net/netty/ClientCyphers.java b/src/main/java/net/netty/ClientCyphers.java new file mode 100644 index 0000000000..ea97b44ded --- /dev/null +++ b/src/main/java/net/netty/ClientCyphers.java @@ -0,0 +1,28 @@ +package net.netty; + +import constants.net.ServerConstants; +import tools.MapleAESOFB; + +public class ClientCyphers { + private final MapleAESOFB send; + private final MapleAESOFB receive; + + private ClientCyphers(MapleAESOFB send, MapleAESOFB receive) { + this.send = send; + this.receive = receive; + } + + public static ClientCyphers generateNew() { + MapleAESOFB send = new MapleAESOFB(InitializationVector.generateSend(), ServerConstants.VERSION); + MapleAESOFB receive = new MapleAESOFB(InitializationVector.generateReceive(), ServerConstants.VERSION); + return new ClientCyphers(send, receive); + } + + public MapleAESOFB getSendCypher() { + return send; + } + + public MapleAESOFB getReceiveCypher() { + return receive; + } +} diff --git a/src/main/java/net/netty/ClientInitializer.java b/src/main/java/net/netty/ClientInitializer.java new file mode 100644 index 0000000000..2c52725cbe --- /dev/null +++ b/src/main/java/net/netty/ClientInitializer.java @@ -0,0 +1,20 @@ +package net.netty; + +import client.MapleClient; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.SocketChannel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ClientInitializer extends ChannelInitializer { + private static final Logger log = LoggerFactory.getLogger(ClientInitializer.class); + + @Override + public void initChannel(SocketChannel socketChannel) { + final String clientIp = socketChannel.remoteAddress().getHostName(); + log.debug("Client initiated new connection from: {}", clientIp); + + MapleClient client = new MapleClient(ClientCyphers.generateNew()); + socketChannel.pipeline().addLast("MapleClient", client); + } +} diff --git a/src/main/java/net/netty/InPacket.java b/src/main/java/net/netty/InPacket.java new file mode 100644 index 0000000000..b4c536cc59 --- /dev/null +++ b/src/main/java/net/netty/InPacket.java @@ -0,0 +1,4 @@ +package net.netty; + +public class InPacket { +} diff --git a/src/main/java/net/netty/InitializationVector.java b/src/main/java/net/netty/InitializationVector.java new file mode 100644 index 0000000000..22cd624db1 --- /dev/null +++ b/src/main/java/net/netty/InitializationVector.java @@ -0,0 +1,27 @@ +package net.netty; + +public class InitializationVector { + private final byte[] bytes; + + private InitializationVector(byte[] bytes) { + this.bytes = bytes; + } + + public byte[] getBytes() { + return bytes; + } + + public static InitializationVector generateSend() { + byte[] ivSend = {82, 48, 120, getRandomByte()}; + return new InitializationVector(ivSend); + } + + public static InitializationVector generateReceive() { + byte[] ivRecv = {70, 114, 122, getRandomByte()}; + return new InitializationVector(ivRecv); + } + + private static byte getRandomByte() { + return (byte) (Math.random() * 255); + } +} diff --git a/src/main/java/net/netty/InvalidPacketHeaderException.java b/src/main/java/net/netty/InvalidPacketHeaderException.java new file mode 100644 index 0000000000..7eed5f3992 --- /dev/null +++ b/src/main/java/net/netty/InvalidPacketHeaderException.java @@ -0,0 +1,14 @@ +package net.netty; + +public class InvalidPacketHeaderException extends RuntimeException { + private final int header; + + public InvalidPacketHeaderException(String message, int header) { + super(message); + this.header = header; + } + + public int getHeader() { + return header; + } +} diff --git a/src/main/java/net/netty/OutPacket.java b/src/main/java/net/netty/OutPacket.java new file mode 100644 index 0000000000..f7f8f1dc46 --- /dev/null +++ b/src/main/java/net/netty/OutPacket.java @@ -0,0 +1,5 @@ +package net.netty; + +public interface OutPacket { + byte[] getBytes(); +} diff --git a/src/main/java/net/netty/PacketDecoder.java b/src/main/java/net/netty/PacketDecoder.java new file mode 100644 index 0000000000..99a30bb9f3 --- /dev/null +++ b/src/main/java/net/netty/PacketDecoder.java @@ -0,0 +1,48 @@ +package net.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ReplayingDecoder; +import net.mina.MapleCustomEncryption; +import tools.MapleAESOFB; + +import java.util.List; + +public class PacketDecoder extends ReplayingDecoder { + private final MapleAESOFB receiveCypher; + + public PacketDecoder(MapleAESOFB receiveCypher) { + this.receiveCypher = receiveCypher; + } + + @Override + protected void decode(ChannelHandlerContext context, ByteBuf in, List out) { + final int header = in.readInt(); + + if (!receiveCypher.checkPacket(header)) { + throw new InvalidPacketHeaderException("Attempted to decode a packet with an invalid header", header); + } + + int packetLength = decodePacketLength(header); + byte[] packet = new byte[packetLength]; + in.readBytes(packet); + receiveCypher.crypt(packet); + MapleCustomEncryption.decryptData(packet); + out.add(packet); + // TODO conditionally log the packet + } + + /** + * @param header Packet header - the first 4 bytes of the packet + * @return Packet size in bytes + */ + private static int decodePacketLength(byte[] header) { + return (((header[1] ^ header[3]) & 0xFF) << 8) | ((header[0] ^ header[2]) & 0xFF); + } + + private static int decodePacketLength(int header) { + int length = ((header >>> 16) ^ (header & 0xFFFF)); + length = ((length << 8) & 0xFF00) | ((length >>> 8) & 0xFF); + return length; + } +} diff --git a/src/main/java/net/netty/PacketEncoder.java b/src/main/java/net/netty/PacketEncoder.java new file mode 100644 index 0000000000..10bb25724e --- /dev/null +++ b/src/main/java/net/netty/PacketEncoder.java @@ -0,0 +1,28 @@ +package net.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import net.mina.MapleCustomEncryption; +import tools.MapleAESOFB; + +public class PacketEncoder extends MessageToByteEncoder { + private final MapleAESOFB sendCypher; + + public PacketEncoder(MapleAESOFB sendCypher) { + this.sendCypher = sendCypher; + } + + @Override + protected void encode(ChannelHandlerContext ctx, OutPacket in, ByteBuf out) { + byte[] packet = in.getBytes(); + out.writeBytes(getEncodedHeader(packet.length)); + MapleCustomEncryption.encryptData(packet); + sendCypher.crypt(packet); + out.writeBytes(packet); + } + + private byte[] getEncodedHeader(int length) { + return sendCypher.getPacketHeader(length); + } +} diff --git a/src/main/java/tools/MapleAESOFB.java b/src/main/java/tools/MapleAESOFB.java index 7ccfc16ac2..19ba74e279 100644 --- a/src/main/java/tools/MapleAESOFB.java +++ b/src/main/java/tools/MapleAESOFB.java @@ -21,6 +21,10 @@ */ package tools; +import net.netty.InitializationVector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -30,52 +34,73 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class MapleAESOFB { - private byte[] iv; - private Cipher cipher; - private short mapleVersion; + private static final Logger log = LoggerFactory.getLogger(MapleAESOFB.class); private final static SecretKeySpec skey = new SecretKeySpec( - new byte[]{0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, (byte) 0xB4, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00}, "AES"); + new byte[]{ + 0x13, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + (byte) 0xB4, 0x00, 0x00, 0x00, + 0x1B, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, + 0x52, 0x00, 0x00, 0x00}, "AES"); - private static final byte[] funnyBytes = new byte[]{(byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, (byte) 0x20, (byte) 0xFC, - (byte) 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1, (byte) 0x5C, (byte) 0x22, (byte) 0xF7, (byte) 0x0C, (byte) 0x44, (byte) 0x1B, (byte) 0x81, (byte) 0xBD, (byte) 0x63, (byte) 0x8D, (byte) 0xD4, (byte) 0xC3, - (byte) 0xF2, (byte) 0x10, (byte) 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, (byte) 0x6E, (byte) 0x66, (byte) 0xEA, (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, (byte) 0x06, (byte) 0x18, (byte) 0x4E, (byte) 0xEB, - (byte) 0x78, (byte) 0x95, (byte) 0xDB, (byte) 0xBA, (byte) 0xB6, (byte) 0x42, (byte) 0x7A, (byte) 0x2A, (byte) 0x83, (byte) 0x0B, (byte) 0x54, (byte) 0x67, (byte) 0x6D, (byte) 0xE8, (byte) 0x65, (byte) 0xE7, - (byte) 0x2F, (byte) 0x07, (byte) 0xF3, (byte) 0xAA, (byte) 0x27, (byte) 0x7B, (byte) 0x85, (byte) 0xB0, (byte) 0x26, (byte) 0xFD, (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7, - (byte) 0xCB, (byte) 0xCC, (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, (byte) 0x60, (byte) 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2, (byte) 0x9B, (byte) 0x39, (byte) 0x5F, (byte) 0x82, (byte) 0x21, - (byte) 0x4C, (byte) 0x69, (byte) 0xF8, (byte) 0x31, (byte) 0x87, (byte) 0xEE, (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, (byte) 0x6A, (byte) 0xBC, (byte) 0xB5, (byte) 0x6B, (byte) 0x59, (byte) 0x13, (byte) 0xF1, - (byte) 0x04, (byte) 0x00, (byte) 0xF6, (byte) 0x5A, (byte) 0x35, (byte) 0x79, (byte) 0x48, (byte) 0x8F, (byte) 0x15, (byte) 0xCD, (byte) 0x97, (byte) 0x57, (byte) 0x12, (byte) 0x3E, (byte) 0x37, (byte) 0xFF, - (byte) 0x9D, (byte) 0x4F, (byte) 0x51, (byte) 0xF5, (byte) 0xA3, (byte) 0x70, (byte) 0xBB, (byte) 0x14, (byte) 0x75, (byte) 0xC2, (byte) 0xB8, (byte) 0x72, (byte) 0xC0, (byte) 0xED, (byte) 0x7D, (byte) 0x68, - (byte) 0xC9, (byte) 0x2E, (byte) 0x0D, (byte) 0x62, (byte) 0x46, (byte) 0x17, (byte) 0x11, (byte) 0x4D, (byte) 0x6C, (byte) 0xC4, (byte) 0x7E, (byte) 0x53, (byte) 0xC1, (byte) 0x25, (byte) 0xC7, (byte) 0x9A, - (byte) 0x1C, (byte) 0x88, (byte) 0x58, (byte) 0x2C, (byte) 0x89, (byte) 0xDC, (byte) 0x02, (byte) 0x64, (byte) 0x40, (byte) 0x01, (byte) 0x5D, (byte) 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, (byte) 0x55, - (byte) 0xD5, (byte) 0xEF, (byte) 0x1A, (byte) 0x7C, (byte) 0xA7, (byte) 0x5B, (byte) 0xA6, (byte) 0x6F, (byte) 0x86, (byte) 0x9F, (byte) 0x73, (byte) 0xE6, (byte) 0x0A, (byte) 0xDE, (byte) 0x2B, (byte) 0x99, - (byte) 0x4A, (byte) 0x47, (byte) 0x9C, (byte) 0xDF, (byte) 0x09, (byte) 0x76, (byte) 0x9E, (byte) 0x30, (byte) 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, (byte) 0x3B, (byte) 0x34, (byte) 0x1D, - (byte) 0x28, (byte) 0x0F, (byte) 0x36, (byte) 0xE3, (byte) 0x23, (byte) 0xB4, (byte) 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, (byte) 0x3C, (byte) 0xFE, (byte) 0x5E, (byte) 0x32, (byte) 0x24, (byte) 0x50, - (byte) 0x1F, (byte) 0x3A, (byte) 0x43, (byte) 0x8A, (byte) 0x96, (byte) 0x41, (byte) 0x74, (byte) 0xAC, (byte) 0x52, (byte) 0x33, (byte) 0xF0, (byte) 0xD9, (byte) 0x29, (byte) 0x80, (byte) 0xB1, (byte) 0x16, - (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9, (byte) 0x84, (byte) 0x7F, (byte) 0x61, (byte) 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, (byte) 0x56, (byte) 0x3D, (byte) 0xCA, (byte) 0xF4, (byte) 0x05, - (byte) 0xC6, (byte) 0xE5, (byte) 0x08, (byte) 0x49}; + private static final byte[] funnyBytes = new byte[]{ + (byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, + (byte) 0xB7, (byte) 0x98, (byte) 0x20, (byte) 0xFC, (byte) 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1, + (byte) 0x5C, (byte) 0x22, (byte) 0xF7, (byte) 0x0C, (byte) 0x44, (byte) 0x1B, (byte) 0x81, (byte) 0xBD, + (byte) 0x63, (byte) 0x8D, (byte) 0xD4, (byte) 0xC3, (byte) 0xF2, (byte) 0x10, (byte) 0x19, (byte) 0xE0, + (byte) 0xFB, (byte) 0xA1, (byte) 0x6E, (byte) 0x66, (byte) 0xEA, (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, + (byte) 0x06, (byte) 0x18, (byte) 0x4E, (byte) 0xEB, (byte) 0x78, (byte) 0x95, (byte) 0xDB, (byte) 0xBA, + (byte) 0xB6, (byte) 0x42, (byte) 0x7A, (byte) 0x2A, (byte) 0x83, (byte) 0x0B, (byte) 0x54, (byte) 0x67, + (byte) 0x6D, (byte) 0xE8, (byte) 0x65, (byte) 0xE7, (byte) 0x2F, (byte) 0x07, (byte) 0xF3, (byte) 0xAA, + (byte) 0x27, (byte) 0x7B, (byte) 0x85, (byte) 0xB0, (byte) 0x26, (byte) 0xFD, (byte) 0x8B, (byte) 0xA9, + (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7, (byte) 0xCB, (byte) 0xCC, (byte) 0x92, (byte) 0xDA, + (byte) 0xF9, (byte) 0x93, (byte) 0x60, (byte) 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2, (byte) 0x9B, + (byte) 0x39, (byte) 0x5F, (byte) 0x82, (byte) 0x21, (byte) 0x4C, (byte) 0x69, (byte) 0xF8, (byte) 0x31, + (byte) 0x87, (byte) 0xEE, (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, (byte) 0x6A, (byte) 0xBC, (byte) 0xB5, + (byte) 0x6B, (byte) 0x59, (byte) 0x13, (byte) 0xF1, (byte) 0x04, (byte) 0x00, (byte) 0xF6, (byte) 0x5A, + (byte) 0x35, (byte) 0x79, (byte) 0x48, (byte) 0x8F, (byte) 0x15, (byte) 0xCD, (byte) 0x97, (byte) 0x57, + (byte) 0x12, (byte) 0x3E, (byte) 0x37, (byte) 0xFF, (byte) 0x9D, (byte) 0x4F, (byte) 0x51, (byte) 0xF5, + (byte) 0xA3, (byte) 0x70, (byte) 0xBB, (byte) 0x14, (byte) 0x75, (byte) 0xC2, (byte) 0xB8, (byte) 0x72, + (byte) 0xC0, (byte) 0xED, (byte) 0x7D, (byte) 0x68, (byte) 0xC9, (byte) 0x2E, (byte) 0x0D, (byte) 0x62, + (byte) 0x46, (byte) 0x17, (byte) 0x11, (byte) 0x4D, (byte) 0x6C, (byte) 0xC4, (byte) 0x7E, (byte) 0x53, + (byte) 0xC1, (byte) 0x25, (byte) 0xC7, (byte) 0x9A, (byte) 0x1C, (byte) 0x88, (byte) 0x58, (byte) 0x2C, + (byte) 0x89, (byte) 0xDC, (byte) 0x02, (byte) 0x64, (byte) 0x40, (byte) 0x01, (byte) 0x5D, (byte) 0x38, + (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, (byte) 0x55, (byte) 0xD5, (byte) 0xEF, (byte) 0x1A, (byte) 0x7C, + (byte) 0xA7, (byte) 0x5B, (byte) 0xA6, (byte) 0x6F, (byte) 0x86, (byte) 0x9F, (byte) 0x73, (byte) 0xE6, + (byte) 0x0A, (byte) 0xDE, (byte) 0x2B, (byte) 0x99, (byte) 0x4A, (byte) 0x47, (byte) 0x9C, (byte) 0xDF, + (byte) 0x09, (byte) 0x76, (byte) 0x9E, (byte) 0x30, (byte) 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, + (byte) 0xA0, (byte) 0x3B, (byte) 0x34, (byte) 0x1D, (byte) 0x28, (byte) 0x0F, (byte) 0x36, (byte) 0xE3, + (byte) 0x23, (byte) 0xB4, (byte) 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, (byte) 0x3C, (byte) 0xFE, + (byte) 0x5E, (byte) 0x32, (byte) 0x24, (byte) 0x50, (byte) 0x1F, (byte) 0x3A, (byte) 0x43, (byte) 0x8A, + (byte) 0x96, (byte) 0x41, (byte) 0x74, (byte) 0xAC, (byte) 0x52, (byte) 0x33, (byte) 0xF0, (byte) 0xD9, + (byte) 0x29, (byte) 0x80, (byte) 0xB1, (byte) 0x16, (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9, + (byte) 0x84, (byte) 0x7F, (byte) 0x61, (byte) 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, (byte) 0x56, + (byte) 0x3D, (byte) 0xCA, (byte) 0xF4, (byte) 0x05, (byte) 0xC6, (byte) 0xE5, (byte) 0x08, (byte) 0x49}; - public MapleAESOFB(byte[] iv, short mapleVersion) { + private final short mapleVersion; + private final Cipher cipher; + private byte[] iv; + + public MapleAESOFB(InitializationVector iv, short mapleVersion) { try { cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skey); - } catch (NoSuchAlgorithmException e) { - System.out.println("ERROR " + e); - } catch (NoSuchPaddingException e) { - System.out.println("ERROR " + e); - } catch (InvalidKeyException e) { - System.out.println("Error initializing the encryption cipher. Make sure you're using the Unlimited Strength cryptography jar files."); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) { + log.warn("Cypher initialization error with skey: {}", skey, e); + throw new RuntimeException(e); } - this.setIv(iv); + + this.iv = iv.getBytes(); this.mapleVersion = (short) (((mapleVersion >> 8) & 0xFF) | ((mapleVersion << 8) & 0xFF00)); } - private void setIv(byte[] iv) { - this.iv = iv; - } - private static byte[] multiplyBytes(byte[] in, int count, int mul) { - byte[] ret = new byte[count * mul]; - for (int x = 0; x < count * mul; x++) { + final int size = count * mul; + byte[] ret = new byte[size]; + for (int x = 0; x < size; x++) { ret[x] = in[x % count]; } return ret; @@ -94,12 +119,8 @@ public class MapleAESOFB { if ((x - start) % myIv.length == 0) { try { byte[] newIv = cipher.doFinal(myIv); - for (int j = 0; j < myIv.length; j++) { - myIv[j] = newIv[j]; - } - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { + System.arraycopy(newIv, 0, myIv, 0, myIv.length); + } catch (IllegalBlockSizeException | BadPaddingException e) { e.printStackTrace(); } } @@ -138,7 +159,8 @@ public class MapleAESOFB { } public boolean checkPacket(byte[] packet) { - return ((((packet[0] ^ iv[2]) & 0xFF) == ((mapleVersion >> 8) & 0xFF)) && (((packet[1] ^ iv[3]) & 0xFF) == (mapleVersion & 0xFF))); + return ((((packet[0] ^ iv[2]) & 0xFF) == ((mapleVersion >> 8) & 0xFF)) && + (((packet[1] ^ iv[3]) & 0xFF) == (mapleVersion & 0xFF))); } public boolean checkPacket(int packetHeader) { diff --git a/src/main/java/tools/MaplePacketCreator.java b/src/main/java/tools/MaplePacketCreator.java index e135021a86..1f163c2efd 100644 --- a/src/main/java/tools/MaplePacketCreator.java +++ b/src/main/java/tools/MaplePacketCreator.java @@ -36,6 +36,7 @@ import constants.inventory.ItemConstants; import constants.skills.Buccaneer; import constants.skills.Corsair; import constants.skills.ThunderBreaker; +import net.netty.InitializationVector; import net.opcodes.SendOpcode; import net.server.PlayerCoolDownValueHolder; import net.server.Server; @@ -547,14 +548,14 @@ public class MaplePacketCreator { * @param recvIv the IV in use by the server for receiving * @return */ - public static byte[] getHello(short mapleVersion, byte[] sendIv, byte[] recvIv) { + public static byte[] getHello(short mapleVersion, InitializationVector sendIv, InitializationVector recvIv) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(8); mplew.writeShort(0x0E); mplew.writeShort(mapleVersion); mplew.writeShort(1); mplew.write(49); - mplew.write(recvIv); - mplew.write(sendIv); + mplew.write(recvIv.getBytes()); + mplew.write(sendIv.getBytes()); mplew.write(8); return mplew.getPacket(); }