Esempio n. 1
0
        public NetworkCommand ProcessCommand()
        {
            NetworkCommand command = this.ReceiveCommand();

            this.LastReceivedCommand = command;
            switch (command)
            {
            case NetworkCommand.Ping:
            {
                long time = this.ReceiveLong();
                this.SendCommand(NetworkCommand.PingBack, time);
            }
            break;

            case NetworkCommand.PingBack:
            {
                long     time    = this.ReceiveLong();
                TimeSpan elapsed = TimeSpan.FromTicks(DateTime.Now.Ticks - time);
                this.LogString(this, "Returning ping time: " + elapsed.ToString() + "\r\n");
            }
            break;

            case NetworkCommand.ComputeECPoint:
            {
                var factor         = ecc.GetRandomFactorModN();
                var multiplication = ecc.ECMultiplication(factor);
                var factorBytes    = factor.ToByteArray();
                Array.Resize(ref factorBytes, ecc.BytesCount);
                var eccBytes = multiplication.UncompressedBytes;
                this.SendCommand(NetworkCommand.Response_ComputeECPoint, factorBytes.Concat(eccBytes));
            }
            break;

            case NetworkCommand.Response_ComputeECPoint:
            {
                byte[] data         = this.ReceiveBytes(ecc.BytesCount * 3);
                var    factor       = data.Take(ecc.BytesCount).ToBigInteger();
                var    verification = ecc.ECMultiplication(factor).UncompressedBytes;
                bool   ok           = Enumerable.Range(0, verification.Length).All(idx => data[ecc.BytesCount + idx] == verification[idx]);
                if (!ok)
                {
                    throw new InvalidOperationException("ECC verification failed!!");
                }
            }
            break;

            case NetworkCommand.RegisterClient:
            {
                var    point             = new ECC521Point(this.ReceiveBytes(ecc.CompressedBytesCount), true);
                string clientIdentifiers = this.ReadString();
                this.serverChallenge = ecc.GetRandomFactorModN();
                var    clientChallengePoint = point.Multiply(this.serverChallenge);
                string userName             = ConfigurationFile.LoadFromFile().GetUserName(clientIdentifiers);
                var    currentTime          = DateTime.Now.Ticks;
                this.SendCommand(NetworkCommand.SolveServerChallenge,
                                 clientChallengePoint.UncompressedBytes.
                                 Concat(BitConverter.GetBytes(currentTime)).
                                 Concat(userName.StringToVariableLengthBytes()));
            }
            break;

            case NetworkCommand.SolveServerChallenge:
            {
                var point           = new ECC521Point(this.ReceiveBytes(ecc.BytesCount * 2), false);
                var serverTimeBytes = this.ReceiveBytes(8);
                this.RegisteredUserName = this.ReadString();
                var secretPoint = point.Multiply(this.clientSecretKey.ModInverse(ecc.N));
                var solution    = RIPEMD160.Hash(secretPoint.CompressedBytes);
                this.SendCommand(NetworkCommand.FollowsServerChallengeSolution, solution.Concat(serverTimeBytes));
                this.SetSharedKey(SHA256.Hash(secretPoint.UncompressedBytes), solution.Take(128 / 8).ToArray());
            }
            break;

            case NetworkCommand.FollowsServerChallengeSolution:
            {
                byte[] ripemd160Solution = this.ReceiveBytes(160 / 8);
                var    challengeDuration = TimeSpan.FromTicks(DateTime.Now.Ticks - BitConverter.ToInt64(this.ReceiveBytes(8), 0));
                var    secretPoint       = ecc.G.Multiply(serverChallenge);
                byte[] verification      = RIPEMD160.Hash(secretPoint.CompressedBytes);
                if (!ripemd160Solution.IsSameAs(verification))
                {
                    throw new InvalidOperationException("Authentication failed.");
                }
                this.SetSharedKey(SHA256.Hash(secretPoint.UncompressedBytes), verification.Take(128 / 8).ToArray());
                this.LogString(this, "Client challenge duration: " + challengeDuration.ToString() + "\r\n");
            }
            break;

            case NetworkCommand.IncomingMessageReplyToAll:
            case NetworkCommand.IncomingMessageNoReply:
            {
                string incomingMessage = this.DecodeIncomingMessage();
                this.ProcessStringCommand(this, incomingMessage);
            }
            break;

            case NetworkCommand.RegisterNewUserName:
            {
                string          clientIdentifiers = this.ReadString();
                string          userName          = this.ReadString();
                UserInformation userInformation   = new UserInformation()
                {
                    ClientIdentifiers = clientIdentifiers,
                    UserName          = userName
                };
                var configurationFile = ConfigurationFile.LoadFromFile();
                configurationFile.AddUser(userInformation);
                configurationFile.SaveToFile();
            }
            break;
            }
            return(command);
        }