diff --git a/src/main/java/net/md_5/bungee/ServerConnection.java b/src/main/java/net/md_5/bungee/ServerConnection.java index 0a7c9541..70f7edb9 100644 --- a/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/src/main/java/net/md_5/bungee/ServerConnection.java @@ -1,19 +1,23 @@ package net.md_5.bungee; -import java.io.BufferedOutputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; +import java.security.PublicKey; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import javax.crypto.SecretKey; import net.md_5.bungee.packet.DefinedPacket; import net.md_5.bungee.packet.Packet1Login; import net.md_5.bungee.packet.Packet2Handshake; import net.md_5.bungee.packet.PacketCDClientStatus; import net.md_5.bungee.packet.PacketFAPluginMessage; +import net.md_5.bungee.packet.PacketFCEncryptionResponse; import net.md_5.bungee.packet.PacketFDEncryptionRequest; import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketInputStream; +import org.bouncycastle.crypto.io.CipherInputStream; +import org.bouncycastle.crypto.io.CipherOutputStream; /** * Class representing a connection from the proxy to the server; ie upstream. @@ -46,12 +50,27 @@ public class ServerConnection extends GenericConnection out.write(handshake.getPacket()); PacketFDEncryptionRequest encryptRequest = new PacketFDEncryptionRequest(in.readPacket()); - out.write(new PacketCDClientStatus((byte) 0).getPacket()); + SecretKey myKey = EncryptionUtil.getSecret(); + PublicKey pub = EncryptionUtil.getPubkey(encryptRequest); + + PacketFCEncryptionResponse response = new PacketFCEncryptionResponse(EncryptionUtil.getShared(myKey, pub), EncryptionUtil.encrypt(pub, encryptRequest.verifyToken)); + out.write(response.getPacket()); + + int ciphId = Util.getId(in.readPacket()); + if (ciphId != 0xFC) + { + throw new RuntimeException("Server did not send encryption enable"); + } + + in = new PacketInputStream(new CipherInputStream(socket.getInputStream(), EncryptionUtil.getCipher(false, myKey))); + out = new CipherOutputStream(out, EncryptionUtil.getCipher(true, myKey)); + for (byte[] custom : user.loginPackets) { out.write(custom); } + out.write(new PacketCDClientStatus((byte) 0).getPacket()); byte[] loginResponse = in.readPacket(); if (Util.getId(loginResponse) == 0xFF) { @@ -66,8 +85,6 @@ public class ServerConnection extends GenericConnection out.write(new PacketFAPluginMessage("REGISTER", channel.getBytes()).getPacket()); } - out = new BufferedOutputStream(out, 64); - return new ServerConnection(name, socket, in, out, login); } catch (KickException ex) {