using System; using ACE.Common.Cryptography; using ACE.Server.Network.Sequence; namespace ACE.Server.Network { public class SessionConnectionData { /// /// random shared 64 bit secret /// for final phase of login and connect handshake /// clear text transmitted S2C and C2S during three-way handshake /// This gives server a high degree of confidence that whoever is replying to the connection request is the same as the one who logged in. /// It's assumed that in most cases only the intended recipient of the cookie, the one who logged in, /// knows the cookie and can prove it in a ConnectionResponse packet. /// public ulong ConnectionCookie { get; private set; } /// /// random shared 32 bit secret /// initialization vector for C2S CRC stream cipher /// The starting point of a 32 bit wheel. /// clear text transmitted S2C during during three-way handshake /// public byte[] ClientSeed { get; private set; } /// /// random shared 32 bit secret /// initialization vector for S2C CRC stream cipher /// The starting point of a 32 bit wheel. /// clear text transmitted S2C during during three-way handshake /// public byte[] ServerSeed { get; private set; } public UIntSequence PacketSequence { get; set; } public uint FragmentSequence { get; set; } /// /// Client->Server stream cipher wrapper /// public CryptoSystem CryptoClient = null; /// /// Server->Client stream cipher /// public ISAAC IssacServer = null; public SessionConnectionData() { // since the network processor is single threaded this can instantiate the .NET Core System.Random class without locking Random rand = new Random(); // the client and server seeds determine where on the 32 bit wheel the stream cipher begins // by picking a random initialization vector it makes it more difficult for an adversary to forge packets ClientSeed = new byte[4]; ServerSeed = new byte[4]; rand.NextBytes(ClientSeed); rand.NextBytes(ServerSeed); CryptoClient = new CryptoSystem(ClientSeed); IssacServer = new ISAAC(ServerSeed); byte[] bytes = new byte[8]; rand.NextBytes(bytes); ConnectionCookie = BitConverter.ToUInt64(bytes, 0); PacketSequence = new UIntSequence(false); } /// /// Discard the references to the byte arrays so the memory can be freed up by GC. /// After the seeds are sent to the client and the two ISAAC objects are constructed they are no longer needed. /// public void DiscardSeeds() { ClientSeed = null; ServerSeed = null; } public override string ToString() { return $"Seeds: [Client {BitConverter.ToString(ClientSeed).Replace("-","")}, Server {BitConverter.ToString(ServerSeed).Replace("-", "")}]"; } } }