From 0a679b294fd4cb0f69c205e89eac540c6a81f6c4 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Mon, 13 Feb 2023 08:30:35 +0100 Subject: [PATCH] fix(crypto): catch exceptions inside of encrypt/decrypt methods --- .../ClientLoginCryptography.cs | 34 +- .../ClientWorldCryptography.cs | 412 +++++++++--------- 2 files changed, 237 insertions(+), 209 deletions(-) diff --git a/Core/NosSmooth.Cryptography/ClientLoginCryptography.cs b/Core/NosSmooth.Cryptography/ClientLoginCryptography.cs index d1ddac3..60892f3 100644 --- a/Core/NosSmooth.Cryptography/ClientLoginCryptography.cs +++ b/Core/NosSmooth.Cryptography/ClientLoginCryptography.cs @@ -18,24 +18,38 @@ public class ClientLoginCryptography : ICryptography /// public string Decrypt(in ReadOnlySpan bytes, Encoding encoding) { - var output = new StringBuilder(); - foreach (var c in bytes) + try { - output.Append(Convert.ToChar(c - 0xF)); - } + var output = new StringBuilder(); + foreach (var c in bytes) + { + output.Append(Convert.ToChar(c - 0xF)); + } - return output.ToString(); + return output.ToString(); + } + catch + { + return string.Empty; + } } /// public byte[] Encrypt(string value, Encoding encoding) { - var output = new byte[value.Length + 1]; - for (int i = 0; i < value.Length; i++) + try + { + var output = new byte[value.Length + 1]; + for (int i = 0; i < value.Length; i++) + { + output[i] = (byte)((value[i] ^ 0xC3) + 0xF); + } + output[output.Length - 1] = 0xD8; + return output; + } + catch { - output[i] = (byte)((value[i] ^ 0xC3) + 0xF); + return Array.Empty(); } - output[output.Length - 1] = 0xD8; - return output; } } \ No newline at end of file diff --git a/Core/NosSmooth.Cryptography/ClientWorldCryptography.cs b/Core/NosSmooth.Cryptography/ClientWorldCryptography.cs index 7f98584..e98616c 100644 --- a/Core/NosSmooth.Cryptography/ClientWorldCryptography.cs +++ b/Core/NosSmooth.Cryptography/ClientWorldCryptography.cs @@ -32,139 +32,186 @@ public class ClientWorldCryptography : ICryptography /// public string Decrypt(in ReadOnlySpan bytes, Encoding encoding) { - int index = 0; - var currentPacket = new List(); - - while (index < bytes.Length) + try { - byte currentByte = bytes[index++]; + int index = 0; + var currentPacket = new List(); - if (currentByte == 0xFF) + while (index < bytes.Length) { - currentPacket.Add((byte)'\n'); - continue; - } + byte currentByte = bytes[index++]; - int length = currentByte & 0x7F; + if (currentByte == 0xFF) + { + currentPacket.Add((byte)'\n'); + continue; + } - if ((currentByte & 0x80) != 0) - { - while (length != 0) + int length = currentByte & 0x7F; + + if ((currentByte & 0x80) != 0) { - if (index < bytes.Length) + while (length != 0) { - currentByte = bytes[index++]; - int firstIndex = (currentByte & 0xF0) >> 4; - char first = '?'; - if (firstIndex != 0) + if (index < bytes.Length) { - firstIndex--; - first = firstIndex != 14 ? Keys[firstIndex] : '\u0000'; + currentByte = bytes[index++]; + int firstIndex = (currentByte & 0xF0) >> 4; + char first = '?'; + if (firstIndex != 0) + { + firstIndex--; + first = firstIndex != 14 ? Keys[firstIndex] : '\u0000'; + } + + if (first != 0x6E) + { + currentPacket.Add((byte)first); + } + + if (length <= 1) + { + break; + } + + int secondIndex = currentByte & 0xF; + char second = '?'; + if (secondIndex != 0) + { + secondIndex--; + second = secondIndex != 14 ? Keys[secondIndex] : '\u0000'; + } + + if (second != 0x6E) + { + currentPacket.Add((byte)second); + } + + length -= 2; } - - if (first != 0x6E) - { - currentPacket.Add((byte)first); - } - - if (length <= 1) + else { - break; + length--; } - - int secondIndex = currentByte & 0xF; - char second = '?'; - if (secondIndex != 0) + } + } + else + { + while (length != 0) + { + if (index < bytes.Length) { - secondIndex--; - second = secondIndex != 14 ? Keys[secondIndex] : '\u0000'; + currentPacket.Add((byte)(bytes[index] ^ 0xFF)); + index++; } - - if (second != 0x6E) + else if (index == bytes.Length) { - currentPacket.Add((byte)second); + currentPacket.Add((byte)'\n'); + index++; } - length -= 2; - } - else - { length--; } } } - else - { - while (length != 0) - { - if (index < bytes.Length) - { - currentPacket.Add((byte)(bytes[index] ^ 0xFF)); - index++; - } - else if (index == bytes.Length) - { - currentPacket.Add((byte)'\n'); - index++; - } - - length--; - } - } - } - return string.Concat(currentPacket.Select(x => (char)x)); + return string.Concat(currentPacket.Select(x => (char)x)); - // byte[] tmp = Encoding.Convert(encoding, Encoding.UTF8, currentPacket.ToArray()); - // return Encoding.UTF8.GetString(tmp); + // byte[] tmp = Encoding.Convert(encoding, Encoding.UTF8, currentPacket.ToArray()); + // return Encoding.UTF8.GetString(tmp); + } + catch + { + return string.Empty; + } } /// public byte[] Encrypt(string value, Encoding encoding) { - var output = new List(); + try + { + var output = new List(); - string mask = new string - ( - value.Select + string mask = new string ( - c => - { - sbyte b = (sbyte)c; - if (c == '#' || c == '/' || c == '%') + value.Select + ( + c => { + sbyte b = (sbyte)c; + if (c == '#' || c == '/' || c == '%') + { + return '0'; + } + + if ((b -= 0x20) == 0 || (b += unchecked((sbyte)0xF1)) < 0 || (b -= 0xB) < 0 || + b - unchecked((sbyte)0xC5) == 0) + { + return '1'; + } + return '0'; } + ).ToArray() + ); - if ((b -= 0x20) == 0 || (b += unchecked((sbyte)0xF1)) < 0 || (b -= 0xB) < 0 || - b - unchecked((sbyte)0xC5) == 0) - { - return '1'; - } + int packetLength = value.Length; + + int sequenceCounter = 0; + int currentPosition = 0; - return '0'; + while (currentPosition <= packetLength) + { + int lastPosition = currentPosition; + while (currentPosition < packetLength && mask[currentPosition] == '0') + { + currentPosition++; } - ).ToArray() - ); - int packetLength = value.Length; + int sequences; + int length; - int sequenceCounter = 0; - int currentPosition = 0; + if (currentPosition != 0) + { + length = currentPosition - lastPosition; + sequences = length / 0x7E; + for (int i = 0; i < length; i++, lastPosition++) + { + if (i == sequenceCounter * 0x7E) + { + if (sequences == 0) + { + output.Add((byte)(length - i)); + } + else + { + output.Add(0x7E); + sequences--; + sequenceCounter++; + } + } - while (currentPosition <= packetLength) - { - int lastPosition = currentPosition; - while (currentPosition < packetLength && mask[currentPosition] == '0') - { - currentPosition++; - } + output.Add((byte)((byte)value[lastPosition] ^ 0xFF)); + } + } + + if (currentPosition >= packetLength) + { + break; + } - int sequences; - int length; + lastPosition = currentPosition; + while (currentPosition < packetLength && mask[currentPosition] == '1') + { + currentPosition++; + } + + if (currentPosition == 0) + { + continue; + } - if (currentPosition != 0) - { length = currentPosition - lastPosition; sequences = length / 0x7E; for (int i = 0; i < length; i++, lastPosition++) @@ -173,142 +220,109 @@ public class ClientWorldCryptography : ICryptography { if (sequences == 0) { - output.Add((byte)(length - i)); + output.Add((byte)((length - i) | 0x80)); } else { - output.Add(0x7E); + output.Add(0x7E | 0x80); sequences--; sequenceCounter++; } } - output.Add((byte)((byte)value[lastPosition] ^ 0xFF)); + byte currentByte = (byte)value[lastPosition]; + switch (currentByte) + { + case 0x20: + currentByte = 1; + break; + case 0x2D: + currentByte = 2; + break; + case 0xFF: + currentByte = 0xE; + break; + default: + currentByte -= 0x2C; + break; + } + + if (currentByte == 0x00) + { + continue; + } + + if (i % 2 == 0) + { + output.Add((byte)(currentByte << 4)); + } + else + { + output[output.Count - 1] = (byte)(output.Last() | currentByte); + } } } - if (currentPosition >= packetLength) - { - break; - } + output.Add(0xFF); + + sbyte sessionNumber = (sbyte)((EncryptionKey >> 6) & 0xFF & 0x80000003); - lastPosition = currentPosition; - while (currentPosition < packetLength && mask[currentPosition] == '1') + if (sessionNumber < 0) { - currentPosition++; + sessionNumber = (sbyte)(((sessionNumber - 1) | 0xFFFFFFFC) + 1); } - if (currentPosition == 0) + byte sessionKey = (byte)(EncryptionKey & 0xFF); + + if (EncryptionKey != 0) { - continue; + sessionNumber = -1; } - length = currentPosition - lastPosition; - sequences = length / 0x7E; - for (int i = 0; i < length; i++, lastPosition++) + switch (sessionNumber) { - if (i == sequenceCounter * 0x7E) - { - if (sequences == 0) + case 0: + for (int i = 0; i < output.Count; i++) { - output.Add((byte)((length - i) | 0x80)); + output[i] = (byte)(output[i] + sessionKey + 0x40); } - else + + break; + case 1: + for (int i = 0; i < output.Count; i++) { - output.Add(0x7E | 0x80); - sequences--; - sequenceCounter++; + output[i] = (byte)(output[i] - (sessionKey + 0x40)); } - } - - byte currentByte = (byte)value[lastPosition]; - switch (currentByte) - { - case 0x20: - currentByte = 1; - break; - case 0x2D: - currentByte = 2; - break; - case 0xFF: - currentByte = 0xE; - break; - default: - currentByte -= 0x2C; - break; - } - - if (currentByte == 0x00) - { - continue; - } - - if (i % 2 == 0) - { - output.Add((byte)(currentByte << 4)); - } - else - { - output[output.Count - 1] = (byte)(output.Last() | currentByte); - } - } - } - output.Add(0xFF); + break; + case 2: + for (int i = 0; i < output.Count; i++) + { + output[i] = (byte)((output[i] ^ 0xC3) + sessionKey + 0x40); + } - sbyte sessionNumber = (sbyte)((EncryptionKey >> 6) & 0xFF & 0x80000003); + break; + case 3: + for (int i = 0; i < output.Count; i++) + { + output[i] = (byte)((output[i] ^ 0xC3) - (sessionKey + 0x40)); + } - if (sessionNumber < 0) - { - sessionNumber = (sbyte)(((sessionNumber - 1) | 0xFFFFFFFC) + 1); - } + break; + default: + for (int i = 0; i < output.Count; i++) + { + output[i] = (byte)(output[i] + 0x0F); + } - byte sessionKey = (byte)(EncryptionKey & 0xFF); + break; + } - if (EncryptionKey != 0) - { - sessionNumber = -1; + return output.ToArray(); } - - switch (sessionNumber) + catch { - case 0: - for (int i = 0; i < output.Count; i++) - { - output[i] = (byte)(output[i] + sessionKey + 0x40); - } - - break; - case 1: - for (int i = 0; i < output.Count; i++) - { - output[i] = (byte)(output[i] - (sessionKey + 0x40)); - } - - break; - case 2: - for (int i = 0; i < output.Count; i++) - { - output[i] = (byte)((output[i] ^ 0xC3) + sessionKey + 0x40); - } - - break; - case 3: - for (int i = 0; i < output.Count; i++) - { - output[i] = (byte)((output[i] ^ 0xC3) - (sessionKey + 0x40)); - } - - break; - default: - for (int i = 0; i < output.Count; i++) - { - output[i] = (byte)(output[i] + 0x0F); - } - - break; + return Array.Empty(); } - - return output.ToArray(); } } \ No newline at end of file -- 2.48.1