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;
                    }
                }
            }
        }
Esempio n. 2
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);
        }