public static void receive(int bytesReceived, Socket socket, State state) { int bytesRead = 0; int payloadLength, bytesAvailable, bytesNeeded; while (bytesRead < bytesReceived) { bytesAvailable = bytesReceived - bytesRead; if (bytesReceived > 0) { if (state.packet.Length >= 7) { payloadLength = BitConverter.ToInt32(new byte[1].Concat(state.packet.Skip(2).Take(3)).Reverse().ToArray(), 0); bytesNeeded = payloadLength - (state.packet.Length - 7); if (bytesAvailable >= bytesNeeded) { state.packet = state.packet.Concat(state.buffer.Skip(bytesRead).Take(bytesNeeded)).ToArray(); bytesRead += bytesNeeded; bytesAvailable -= bytesNeeded; if (state.GetType() == typeof(ClientState)) { ClientCrypto.DecryptPacket(socket, (ClientState)state, state.packet); } else if (state.GetType() == typeof(ServerState)) { ServerCrypto.DecryptPacket(socket, (ServerState)state, state.packet); } state.packet = new byte[0]; } else { state.packet = state.packet.Concat(state.buffer.Skip(bytesRead).Take(bytesAvailable)).ToArray(); bytesRead = bytesReceived; bytesAvailable = 0; } } else if (bytesAvailable >= 7) { state.packet = state.packet.Concat(state.buffer.Skip(bytesRead).Take(7)).ToArray(); bytesRead += 7; bytesAvailable -= 7; } else { state.packet = state.packet.Concat(state.buffer.Skip(bytesRead).Take(bytesAvailable)).ToArray(); bytesRead = bytesReceived; bytesAvailable = 0; } } } }
public static void DecryptPacket(Socket socket, ClientState state, byte[] packet) { int messageId = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0); int payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0); int unknown = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0); byte[] cipherText = packet.Skip(2).Skip(3).Skip(2).ToArray(); byte[] plainText; if (messageId == 20100) //|| (messageId == 20103 && state.serverState.sharedKey == null) { plainText = cipherText; } else if (messageId == 20103 || messageId == 20104) { byte[] nonce = GenericHash.Hash(state.nonce.Concat(state.clientKey.PublicKey).Concat(state.serverKey).ToArray(), null, 24); plainText = PublicKeyBox.Open(cipherText, nonce, state.clientKey.PrivateKey, state.serverKey); state.serverState.nonce = plainText.Take(24).ToArray(); state.serverState.sharedKey = plainText.Skip(24).Take(32).ToArray(); plainText = plainText.Skip(24).Skip(32).ToArray(); } else { state.serverState.nonce = Utilities.Increment(Utilities.Increment(state.serverState.nonce)); plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.serverState.nonce, state.serverState.sharedKey); } try { JObject decoded = state.decoder.decode(messageId, 0, plainText); var msg = new Message(messageId, "[S > C] " + decoded["name"], plainText, unknown, state, decoded["fields"].ToString()); MainWindow.Context.AddMessageToQueueLog(msg); } catch (Exception) { var msg = new Message(messageId, "[S > C] " + "Undefined", plainText, unknown, state, ""); MainWindow.Context.AddMessageToQueueLog(msg); } ServerCrypto.EncryptPacket(state.serverState.socket, state.serverState, messageId, unknown, plainText); }