Send and receive message without message signing

This commit is contained in:
ReinforceZwei 2023-01-13 15:53:33 +08:00
parent 4be7a05006
commit e447fea16b
3 changed files with 93 additions and 16 deletions

View file

@ -79,6 +79,8 @@ namespace MinecraftClient.Protocol.Handlers
private int pendingAcknowledgments = 0; private int pendingAcknowledgments = 0;
private readonly LastSeenMessagesCollector lastSeenMessagesCollector = new(5); private readonly LastSeenMessagesCollector lastSeenMessagesCollector = new(5);
private LastSeenMessageList.Entry? lastReceivedMessage = null; private LastSeenMessageList.Entry? lastReceivedMessage = null;
private Guid playerSessionUuid = Guid.NewGuid();
private int messageCount = 0;
readonly Protocol18Forge pForge; readonly Protocol18Forge pForge;
readonly Protocol18Terrain pTerrain; readonly Protocol18Terrain pTerrain;
readonly IMinecraftComHandler handler; readonly IMinecraftComHandler handler;
@ -2437,14 +2439,27 @@ namespace MinecraftClient.Protocol.Handlers
} }
} }
// Signed Preview: Boolean if (protocolVersion < MC_1_19_3_Version)
fields.AddRange(dataTypes.GetBool(false));
if (protocolVersion >= MC_1_19_2_Version)
{ {
// Message Acknowledgment // Signed Preview: Boolean (1.19.2)
fields.AddRange(dataTypes.GetBool(false));
}
else
{
fields.AddRange(dataTypes.GetVarInt(messageCount)); // Message count (1.19.3)
}
if (protocolVersion == MC_1_19_2_Version)
{
// Message Acknowledgment (1.19.2)
fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode && Config.Signature.LoginWithSecureProfile)); fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode && Config.Signature.LoginWithSecureProfile));
} }
else if (protocolVersion >= MC_1_19_3_Version)
{
// 1.19.3
// Acknowledged: BitSet (no idea what is this)
fields.AddRange(new byte[3] { 0, 0, 0 });
}
SendPacket(PacketTypesOut.ChatCommand, fields); SendPacket(PacketTypesOut.ChatCommand, fields);
return true; return true;
@ -2502,12 +2517,21 @@ namespace MinecraftClient.Protocol.Handlers
// Signature Length & Signature: (VarInt) and Byte Array // Signature Length & Signature: (VarInt) and Byte Array
Guid uuid = handler.GetUserUuid(); Guid uuid = handler.GetUserUuid();
byte[] sign; byte[] sign;
if (protocolVersion < MC_1_19_2_Version) // 1.19.1 or lower if (protocolVersion < MC_1_19_2_Version)
{
// 1.19.1 or lower
sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt);
else if (protocolVersion < MC_1_19_3_Version) // 1.19.2 }
else if (protocolVersion < MC_1_19_3_Version)
{
// 1.19.2
sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment!.lastSeen); sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment!.lastSeen);
else // 1.19.3 }
sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); // TODO? else
{
// 1.19.3
sign = playerKeyPair.PrivateKey.SignMessage(message, timeNow, ref salt, messageCount, uuid, playerSessionUuid);
}
if (protocolVersion >= MC_1_19_3_Version) if (protocolVersion >= MC_1_19_3_Version)
fields.AddRange(dataTypes.GetBool(true)); fields.AddRange(dataTypes.GetBool(true));
@ -2516,11 +2540,14 @@ namespace MinecraftClient.Protocol.Handlers
fields.AddRange(sign); fields.AddRange(sign);
} }
// Signed Preview: Boolean
if (protocolVersion >= MC_1_19_3_Version) if (protocolVersion >= MC_1_19_3_Version)
fields.AddRange(dataTypes.GetVarInt(1)); // message count fields.AddRange(dataTypes.GetVarInt(messageCount)); // Message count (1.19.3)
else else
fields.AddRange(dataTypes.GetBool(false)); fields.AddRange(dataTypes.GetBool(false)); // Signed Preview: Boolean (1.19.2)
//if (protocolVersion >= MC_1_19_3_Version)
// messageCount++;
if (protocolVersion >= MC_1_19_2_Version) if (protocolVersion >= MC_1_19_2_Version)
{ {
@ -3196,13 +3223,11 @@ namespace MinecraftClient.Protocol.Handlers
{ {
List<byte> packet = new(); List<byte> packet = new();
var uuid = Guid.NewGuid();
byte[] timestampByte = BitConverter.GetBytes(playerKeyPair.GetExpirationMilliseconds()); byte[] timestampByte = BitConverter.GetBytes(playerKeyPair.GetExpirationMilliseconds());
Array.Reverse(timestampByte); Array.Reverse(timestampByte);
var signature = KeyUtils.ComputeHash(timestampByte.Concat(playerKeyPair.PublicKey.Key).ToArray()); var signature = KeyUtils.ComputeHash(timestampByte.Concat(playerKeyPair.PublicKey.Key).ToArray());
packet.AddRange(dataTypes.GetUUID(uuid)); packet.AddRange(dataTypes.GetUUID(playerSessionUuid));
packet.AddRange(dataTypes.GetLong(playerKeyPair.GetExpirationMilliseconds())); packet.AddRange(dataTypes.GetLong(playerKeyPair.GetExpirationMilliseconds()));
packet.AddRange(dataTypes.GetVarInt(playerKeyPair.PublicKey.Key.Length)); packet.AddRange(dataTypes.GetVarInt(playerKeyPair.PublicKey.Key.Length));
packet.AddRange(playerKeyPair.PublicKey.Key); packet.AddRange(playerKeyPair.PublicKey.Key);
@ -3222,6 +3247,27 @@ namespace MinecraftClient.Protocol.Handlers
else { return false; } else { return false; }
} }
public bool SendMessageAcknowledgment(int messageCount)
{
if (protocolVersion >= MC_1_19_3_Version)
{
try
{
List<byte> packet = new();
packet.AddRange(dataTypes.GetVarInt(messageCount));
SendPacket(PacketTypesOut.MessageAcknowledgment, packet);
return true;
}
catch (SocketException) { return false; }
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
else { return false; }
}
private byte[] GenerateSalt() private byte[] GenerateSalt()
{ {
byte[] salt = new byte[8]; byte[] salt = new byte[8];

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using ImageMagick;
using MinecraftClient.Protocol.Message; using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Keys namespace MinecraftClient.Protocol.Keys
@ -124,11 +125,36 @@ namespace MinecraftClient.Protocol.Keys
return data.ToArray(); return data.ToArray();
} }
public static byte[] GetSignatureData(string message, DateTimeOffset timestamp, ref byte[] salt, Guid sender, Guid sessionUuid) public static byte[] GetSignatureData(string message, DateTimeOffset timestamp, ref byte[] salt, int messageCount, Guid sender, Guid sessionUuid)
{ {
List<byte> data = new(); List<byte> data = new();
// TODO! // TODO!
byte[] unknownInt1 = BitConverter.GetBytes(1);
Array.Reverse(unknownInt1);
data.AddRange(unknownInt1);
data.AddRange(sender.ToBigEndianBytes());
data.AddRange(sessionUuid.ToBigEndianBytes());
byte[] msgCountByte = BitConverter.GetBytes(messageCount);
Array.Reverse(msgCountByte);
data.AddRange(msgCountByte);
data.AddRange(salt);
byte[] timestampByte = BitConverter.GetBytes(timestamp.ToUnixTimeSeconds());
Array.Reverse(timestampByte);
data.AddRange(timestampByte);
byte[] msgByte = Encoding.UTF8.GetBytes(message);
byte[] msgLengthByte = BitConverter.GetBytes(msgByte.Length);
Array.Reverse(msgLengthByte);
data.AddRange(msgLengthByte);
data.AddRange(msgByte);
byte[] unknownInt2 = BitConverter.GetBytes(0);
Array.Reverse(unknownInt2);
data.AddRange(unknownInt2);
return data.ToArray(); return data.ToArray();
} }

View file

@ -64,5 +64,10 @@ namespace MinecraftClient.Protocol.Keys
return msgSign; return msgSign;
} }
public byte[] SignMessage(string message, DateTimeOffset timestamp, ref byte[] salt, int messageCount, Guid sender, Guid sessionUuid)
{
byte[] data = KeyUtils.GetSignatureData(message, timestamp, ref salt, messageCount, sender, sessionUuid);
return SignData(data);
}
} }
} }