public void AddUser(UserInformation userInformation) { Array.Resize(ref this.Users, this.Users.Length + 1); this.Users[this.Users.Length - 1] = userInformation; }
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); }