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

View File

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