public static void HandleKeyData(StsSession session, ClientKeyDataMessage keyData)
        {
            session.KeyExchange.CalculateSecret(keyData.A);

            byte[] key = session.KeyExchange.CalculateSessionKey();
            if (!session.KeyExchange.VerifyClientEvidenceMessage(keyData.M1))
            {
                session.EnqueueMessageError(new ServerErrorMessage((int)ErrorCode.InvalidAccountNameOrPassword));
                return;
            }

            byte[] M2 = session.KeyExchange.CalculateServerEvidenceMessage();

            using (MemoryStream stream = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    writer.Write(M2.Length);
                    writer.Write(M2, 0, M2.Length);

                    session.EnqueueMessageOk(new ServerKeyDataMessage
                    {
                        KeyData = Convert.ToBase64String(stream.ToArray())
                    });
                }

            // enqueue new key to be set after next packet flush
            session.InitialiseEncryption(key);
        }
        public static void HandleLoginStart(StsSession session, ClientLoginStartMessage loginStart)
        {
            session.EnqueueEvent(new TaskGenericEvent <Account>(AuthDatabase.GetAccountAsync(loginStart.LoginName),
                                                                account =>
            {
                if (account == null)
                {
                    session.EnqueueMessageError(new ServerErrorMessage((int)ErrorCode.InvalidAccountNameOrPassword));
                    return;
                }

                session.Account = account;

                byte[] s            = account.S.ToByteArray();
                byte[] v            = account.V.ToByteArray();
                session.KeyExchange = new Srp6Provider(account.Email, s, v);

                byte[] B = session.KeyExchange.GenerateServerCredentials();
                using (MemoryStream stream = new MemoryStream())
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        writer.Write(s.Length);
                        writer.Write(s, 0, s.Length);
                        writer.Write(B.Length);
                        writer.Write(B, 0, B.Length);

                        session.EnqueueMessageOk(new ServerLoginStartMessage
                        {
                            KeyData = Convert.ToBase64String(stream.ToArray())
                        });
                    }

                session.State = SessionState.LoginStart;
            }));
        }