Revert "Volatile encryption (#515)" (#516)

This reverts commit 0f15d4a273.
This commit is contained in:
TheMode 2021-11-03 09:17:23 +01:00 committed by GitHub
parent 0f15d4a273
commit acc711c640
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 33 deletions

View File

@ -22,7 +22,6 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.util.Arrays; import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
@ -51,9 +50,8 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
MinecraftServer.LOGGER.error("{} tried to login with an invalid nonce!", loginUsername); MinecraftServer.LOGGER.error("{} tried to login with an invalid nonce!", loginUsername);
return; return;
} }
final KeyPair keyPair = MojangAuth.getKeyPair();
final SecretKey secretKey = MojangCrypt.decryptByteToSecretKey(keyPair.getPrivate(), sharedSecret); final byte[] digestedData = MojangCrypt.digestData("", MojangAuth.getKeyPair().getPublic(), getSecretKey());
final byte[] digestedData = MojangCrypt.digestData("", keyPair.getPublic(), secretKey);
if (digestedData == null) { if (digestedData == null) {
// Incorrect key, probably because of the client // Incorrect key, probably because of the client
MinecraftServer.LOGGER.error("Connection {} failed initializing encryption.", socketConnection.getRemoteAddress()); MinecraftServer.LOGGER.error("Connection {} failed initializing encryption.", socketConnection.getRemoteAddress());
@ -80,7 +78,7 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
// Invalid response // Invalid response
return; return;
} }
socketConnection.setEncryptionKey(secretKey); socketConnection.setEncryptionKey(getSecretKey());
UUID profileUUID = UUID.fromString(gameProfile.get("id").getAsString() UUID profileUUID = UUID.fromString(gameProfile.get("id").getAsString()
.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); .replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
final String profileName = gameProfile.get("name").getAsString(); final String profileName = gameProfile.get("name").getAsString();
@ -106,6 +104,10 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
ByteArrayData.encodeByteArray(writer, verifyToken); ByteArrayData.encodeByteArray(writer, verifyToken);
} }
private SecretKey getSecretKey() {
return MojangCrypt.decryptByteToSecretKey(MojangAuth.getKeyPair().getPrivate(), sharedSecret);
}
private byte[] getNonce() { private byte[] getNonce() {
return MojangAuth.getKeyPair().getPrivate() == null ? return MojangAuth.getKeyPair().getPrivate() == null ?
this.verifyToken : MojangCrypt.decryptUsingKey(MojangAuth.getKeyPair().getPrivate(), this.verifyToken); this.verifyToken : MojangCrypt.decryptUsingKey(MojangAuth.getKeyPair().getPrivate(), this.verifyToken);

View File

@ -69,7 +69,8 @@ public class LoginStartPacket implements ClientPreplayPacket {
} }
final PlayerSocketConnection socketConnection = (PlayerSocketConnection) connection; final PlayerSocketConnection socketConnection = (PlayerSocketConnection) connection;
socketConnection.setConnectionState(ConnectionState.LOGIN); socketConnection.setConnectionState(ConnectionState.LOGIN);
socketConnection.sendPacket(new EncryptionRequestPacket(socketConnection)); EncryptionRequestPacket encryptionRequestPacket = new EncryptionRequestPacket(socketConnection);
socketConnection.sendPacket(encryptionRequestPacket);
} else { } else {
final boolean bungee = BungeeCordProxy.isEnabled(); final boolean bungee = BungeeCordProxy.isEnabled();
// Offline // Offline

View File

@ -36,7 +36,6 @@ import java.nio.channels.SocketChannel;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.zip.DataFormatException; import java.util.zip.DataFormatException;
import java.util.zip.Inflater; import java.util.zip.Inflater;
@ -48,18 +47,18 @@ import java.util.zip.Inflater;
@ApiStatus.Internal @ApiStatus.Internal
public class PlayerSocketConnection extends PlayerConnection { public class PlayerSocketConnection extends PlayerConnection {
private final static Logger LOGGER = LoggerFactory.getLogger(PlayerSocketConnection.class); private final static Logger LOGGER = LoggerFactory.getLogger(PlayerSocketConnection.class);
private static final AtomicReferenceFieldUpdater<PlayerSocketConnection, EncryptionInfo> ENCRYPTION_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(PlayerSocketConnection.class, EncryptionInfo.class, "encryptionInfo");
private final Worker worker; private final Worker worker;
private final SocketChannel channel; private final SocketChannel channel;
private SocketAddress remoteAddress; private SocketAddress remoteAddress;
private volatile EncryptionInfo encryptionInfo; private boolean encrypted = false;
private boolean compressed = false; private boolean compressed = false;
//Could be null. Only used for Mojang Auth //Could be null. Only used for Mojang Auth
private byte[] nonce = new byte[4]; private byte[] nonce = new byte[4];
private Cipher decryptCipher;
private Cipher encryptCipher;
// Data from client packets // Data from client packets
private String loginUsername; private String loginUsername;
@ -93,11 +92,11 @@ public class PlayerSocketConnection extends PlayerConnection {
public void processPackets(Worker.Context workerContext, PacketProcessor packetProcessor) { public void processPackets(Worker.Context workerContext, PacketProcessor packetProcessor) {
final BinaryBuffer readBuffer = workerContext.readBuffer; final BinaryBuffer readBuffer = workerContext.readBuffer;
// Decrypt data // Decrypt data
EncryptionInfo encryptionInfo = this.encryptionInfo; if (encrypted) {
if (encryptionInfo != null) { final Cipher cipher = decryptCipher;
ByteBuffer input = readBuffer.asByteBuffer(0, readBuffer.writerOffset()); ByteBuffer input = readBuffer.asByteBuffer(0, readBuffer.writerOffset());
try { try {
encryptionInfo.decryptCipher().update(input, input.duplicate()); cipher.update(input, input.duplicate());
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
MinecraftServer.getExceptionManager().handleException(e); MinecraftServer.getExceptionManager().handleException(e);
return; return;
@ -176,10 +175,12 @@ public class PlayerSocketConnection extends PlayerConnection {
* @throws IllegalStateException if encryption is already enabled for this connection * @throws IllegalStateException if encryption is already enabled for this connection
*/ */
public void setEncryptionKey(@NotNull SecretKey secretKey) { public void setEncryptionKey(@NotNull SecretKey secretKey) {
final EncryptionInfo prev = ENCRYPTION_UPDATER.getAndSet(this, Check.stateCondition(encrypted, "Encryption is already enabled!");
new EncryptionInfo(MojangCrypt.getCipher(2, secretKey), MojangCrypt.getCipher(1, secretKey))); synchronized (bufferLock) {
if (prev != null) this.decryptCipher = MojangCrypt.getCipher(2, secretKey);
throw new IllegalStateException("Encryption was already enabled for this connection"); this.encryptCipher = MojangCrypt.getCipher(1, secretKey);
this.encrypted = true;
}
} }
/** /**
@ -230,11 +231,11 @@ public class PlayerSocketConnection extends PlayerConnection {
@ApiStatus.Internal @ApiStatus.Internal
public void write(@NotNull ByteBuffer buffer, int index, int length) { public void write(@NotNull ByteBuffer buffer, int index, int length) {
EncryptionInfo encryptionInfo = this.encryptionInfo; synchronized (bufferLock) {
if (encryptionInfo != null) { if (encrypted) { // Encryption support
ByteBuffer output = PacketUtils.localBuffer(); ByteBuffer output = PacketUtils.localBuffer();
try { try {
encryptionInfo.encryptCipher().update(buffer.slice(index, length), output); this.encryptCipher.update(buffer.slice(index,length), output);
buffer = output.flip(); buffer = output.flip();
index = 0; index = 0;
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
@ -243,7 +244,6 @@ public class PlayerSocketConnection extends PlayerConnection {
} }
} }
synchronized (bufferLock) {
BinaryBuffer localBuffer = tickBuffer.getPlain(); BinaryBuffer localBuffer = tickBuffer.getPlain();
final int capacity = localBuffer.capacity(); final int capacity = localBuffer.capacity();
if (length <= capacity) { if (length <= capacity) {
@ -472,7 +472,4 @@ public class PlayerSocketConnection extends PlayerConnection {
public void setNonce(byte[] nonce) { public void setNonce(byte[] nonce) {
this.nonce = nonce; this.nonce = nonce;
} }
public record EncryptionInfo(Cipher decryptCipher, Cipher encryptCipher) {
}
} }