internal NetClient(Socket sock, RSA crypto, OnMessageRecieved handler, OnClientConnect onConn) : this(null, ((IPEndPoint)sock.RemoteEndPoint).Address, (short)((IPEndPoint)sock.RemoteEndPoint).Port, handler, onConn, -1) { decrypt = crypto; Connection = sock; Running = true; ServerSide = true; // Initiate crypto-handshake by sending public keys Connection.Send(NetSupport.WithHeader(crypto.Serialize())); }
public virtual void Send(byte[] message) { NetSupport.DoStateCheck(IsAlive, true); lock (messageBuffer) messageBuffer.Enqueue(Crypto.Encrypt(NetSupport.WithHeader(message))); }
protected internal bool SyncListener(ref bool cryptoEstablished, ref int mLen, out bool acceptedData, Queue <byte> ibuf, byte[] buffer) { if (cryptoEstablished) { lock (messageBuffer) { foreach (byte[] message in messageBuffer) { Connection.Send(NetSupport.WithHeader(message)); } messageBuffer.Clear(); } } if (acceptedData = Connection.Available > 0) { int read = Connection.Receive(buffer); ibuf.EnqueueAll(buffer, 0, read); } if (mLen == 0 && ibuf.Count >= 4) { mLen = Support.ReadInt(ibuf.Dequeue(4), 0); } if (mLen != 0 && ibuf.Count >= mLen) { // Got a full message. Parse! byte[] message = ibuf.Dequeue(mLen); if (!cryptoEstablished) { if (ServerSide) { try { if (Crypto == null) { Crypto = Rijndael128.Deserialize(decrypt.Decrypt(message), out int _); } else { CBC = new PCBC(Crypto, decrypt.Decrypt(message)); } } catch (Exception) { Console.WriteLine("A fatal error ocurrd when attempting to establish a secure channel! Stopping..."); Thread.Sleep(5000); Environment.Exit(-1); } } else { // Reconstruct RSA object from remote public keys and use it to encrypt our serialized AES key/iv RSA asymm = RSA.Deserialize(message, out int _); Connection.Send(NetSupport.WithHeader(asymm.Encrypt(Crypto.Serialize()))); Connection.Send(NetSupport.WithHeader(asymm.Encrypt(CBC.IV))); } if (CBC != null) { cryptoEstablished = true; onConn(this); } } else { // Decrypt the incoming message byte[] read = Crypto.Decrypt(message); // Read the decrypted message length int mlenInner = Support.ReadInt(read, 0); // Send the message to the handler and get a response string response = handler(read.SubArray(4, 4 + mlenInner).ToUTF8String(), out bool live); // Send the response (if given one) and drop the connection if the handler tells us to if (response != null) { Connection.Send(NetSupport.WithHeader(Crypto.Encrypt(NetSupport.WithHeader(response.ToUTF8Bytes())))); } if (!live) { Running = false; try { Connection.Close(); } catch (Exception) { } return(true); } } // Reset expexted message length mLen = 0; } return(false); }