Example #1
0
        public override void ProcessPayload(SSPClient client, OperationalSocket OpSocket)
        {
            SSPClient _client = client as SSPClient;

            if (_client != null)
            {
                byte[]        responseData  = new byte[0];
                MazeErrorCode errorCode     = MazeErrorCode.Error;
                Mazing        mazeHandshake = _client.IsServerSided ? _client.serverHS : _client.clientHS;

                if (mazeHandshake == null)
                {
                    //error could occur on a unexpected disconnect
                    client.Connection.HandShakeCompleted = false;
                    client.Connection.HandshakeSync.Pulse();
                    return;
                }

                errorCode = mazeHandshake.onReceiveData(Data, ref responseData);


                if (errorCode != MazeErrorCode.Finished && errorCode != MazeErrorCode.Success && client.TimingConfiguration.Enable_Timing)
                {
                    //something went wrong, annoy the attacker
                    Thread.Sleep(client.TimingConfiguration.Authentication_WrongPassword);
                }

                if (responseData.Length > 0)
                {
                    client.Connection.SendMessage(new MsgHandshake(responseData), new SystemHeader());
                }

                if (client == null || client.Connection == null || client.Connection.HandshakeSync == null)
                {
                    //error could occur on a unexpected disconnect
                    return;
                }

                client.Connection.HandshakeSync.Value = errorCode;
                if (errorCode != MazeErrorCode.Finished && errorCode != MazeErrorCode.Success)
                {
                    client.Connection.HandshakeSync.Pulse();
                }
                else if (errorCode == MazeErrorCode.Finished)
                {
                    //let's tell it's completed and apply the new key
                    client.Connection.ApplyNewKey(mazeHandshake, mazeHandshake.FinalKey, mazeHandshake.FinalSalt);

                    if (_client.IsServerSided)
                    {
                        if (mazeHandshake as ServerMaze != null)
                        {
                            client.Username = (mazeHandshake as ServerMaze).Username;
                        }

                        client.Connection.HandShakeCompleted = true;

                        /*try
                         * {
                         *  client.onBeforeConnect();
                         * }
                         * catch (Exception ex)
                         * {
                         *  SysLogger.Log(ex.Message, SysLogType.Error);
                         *  client.onException(ex, ErrorType.UserLand);
                         *  return; //don't send that we're ready since we're clearly not at this point
                         * }*/

                        client.Connection.SendMessage(new MsgInitOk(), new SystemHeader());

                        try
                        {
                            client.onConnect();
                        }
                        catch (Exception ex)
                        {
                            SysLogger.Log(ex.Message, SysLogType.Error);
                            client.onException(ex, ErrorType.UserLand);
                            return; //don't send that we're ready since we're clearly not at this point
                        }
                    }
                    else
                    {
                        client.Connection.HandShakeCompleted = true;
                        client.Connection.HandshakeSync.Pulse();
                    }
                }
            }
        }
Example #2
0
        public void Test_MazeAuthentication()
        {
            MazeErrorCode clientError = MazeErrorCode.Error;
            MazeErrorCode serverError = MazeErrorCode.Error;

            List <User> Server_Users = new List <User>();

            //create users
            User temp_user = new User();

            temp_user.Username  = "";
            temp_user.Password  = "";
            temp_user.PublicKey = File.ReadAllBytes("./Data/PublicKey1.dat");

            temp_user.PrivateKeys.Add(File.ReadAllBytes("./Data/PrivateKey1.dat"));
            temp_user.PrivateKeys.Add(File.ReadAllBytes("./Data/PrivateKey2.dat"));

            temp_user.GenServerKey();
            Server_Users.Add(temp_user);

            Console.WriteLine(".............................................................");

            foreach (User User in Server_Users)
            {
                Stopwatch  sw     = Stopwatch.StartNew();
                ClientMaze client = new ClientMaze(new System.Drawing.Size(512, 512), 10, 30);
                ServerMaze server = new ServerMaze(new System.Drawing.Size(512, 512), 10, 30);
                server.onFindKeyInDatabase += (string EncryptedHash, ref byte[] Key, ref byte[] Salt, ref byte[] PublicKey, ref string Username) =>
                {
                    foreach (User user in Server_Users)
                    {
                        if (user.EncryptedHash == EncryptedHash)
                        {
                            Key       = user.ServerHandshake.MazeKey.getBytes();
                            Salt      = user.ServerHandshake.PrivateSalt.getBytes();
                            PublicKey = user.PublicKey;
                            Username  = user.Username;
                            return(true);
                        }
                    }
                    return(false);
                };


                byte[] ClientResponseData = new byte[0];
                byte[] ServerResponseData = new byte[0];

                //1. Send server the bytecode
                byte[] byteCode = client.GetByteCode();

                //2. Server receives the ByteCode
                serverError = server.onReceiveData(byteCode, ref ServerResponseData);
                if (serverError != MazeErrorCode.Success)
                {
                    throw new Exception("[Server] ByteCode is not correct, disconnecting...");
                }

                //in this example we will simply keep this simple, so no additional encryption(s) will be used here except the one that is being used by the handshake it self
                client.SetLoginData(User.Username, User.Password, User.PrivateKeys, User.PublicKey);
                BigInteger mazeKey            = client.SetMazeKey();
                byte[]     encryptedPublicKey = client.GetEncryptedPublicKey();


                serverError = server.onReceiveData(encryptedPublicKey, ref ServerResponseData);
                if (serverError != MazeErrorCode.Success)
                {
                    throw new Exception("[Server] Encrypted Public Key was not found in database or something else went wrong");
                }

                clientError = client.onReceiveData(ServerResponseData, ref ClientResponseData);
                if (clientError != MazeErrorCode.Success && clientError != MazeErrorCode.Finished)
                {
                    throw new Exception("[Client] Incorrect response from server");
                }

                serverError = server.onReceiveData(ClientResponseData, ref ServerResponseData);
                if (serverError != MazeErrorCode.Success && serverError != MazeErrorCode.Finished)
                {
                    throw new Exception("[Server] Incorrect response from client");
                }
            }
        }
Example #3
0
        private static void KeepTestingHandshake()
        {
            MazeErrorCode clientError = MazeErrorCode.Error;
            MazeErrorCode serverError = MazeErrorCode.Error;
            int           multiplier  = 100;

            while (true)
            {
                Server_Users = new List <User>();

                //create users
                User temp_user = new User();
                temp_user.Username  = ASCIIEncoding.ASCII.GetString(GetRandomBytes(20));
                temp_user.Password  = ASCIIEncoding.ASCII.GetString(GetRandomBytes(20));
                temp_user.PublicKey = GetRandomBytes(128 * multiplier); //File.ReadAllBytes("./Data/PublicKey1.dat"));

                //for (int i = 0; i < temp_user.PublicKey.Length; i++)
                //    temp_user.PublicKey[i] = (byte)(i % 100);

                temp_user.PrivateKeys.Add(GetRandomBytes(128 * multiplier)); //File.ReadAllBytes("./Data/PrivateKey1.dat"));
                temp_user.PrivateKeys.Add(GetRandomBytes(128 * multiplier)); //(File.ReadAllBytes("./Data/PrivateKey2.dat"));

                Console.WriteLine("[Server] Creating user table...");
                temp_user.GenServerKey();
                Server_Users.Add(temp_user);

                Console.WriteLine(".............................................................");

                foreach (User User in Server_Users)
                {
                    Stopwatch  sw     = Stopwatch.StartNew();
                    ClientMaze client = new ClientMaze(new System.Drawing.Size(128, 128), 1, 5);
                    ServerMaze server = new ServerMaze(new System.Drawing.Size(128, 128), 1, 5);
                    server.onFindKeyInDatabase += server_onFindKeyInDatabase;


                    byte[] ClientResponseData = new byte[0];
                    byte[] ServerResponseData = new byte[0];

                    //1. Send server the bytecode
                    byte[] byteCode = client.GetByteCode();
                    Console.WriteLine("[Client] Sending ByteCode to server");


                    //2. Server receives the ByteCode
                    serverError = server.onReceiveData(byteCode, ref ServerResponseData);
                    if (serverError == MazeErrorCode.Success)
                    {
                        Console.WriteLine("[Server] ByteCode is correct, continue on with handshake");
                    }
                    else
                    {
                        Console.WriteLine("[Server] ByteCode is not correct, disconnecting...");
                    }


                    //in this example we will simply keep this simple, so no additional encryption(s) will be used here except the one that is being used by the handshake it self
                    Console.WriteLine("[Client] Setting login data... username:"******"[Client] Calculating the key");
                    BigInteger mazeKey = client.SetMazeKey();


                    Console.WriteLine("[Client] Encrypting the public key & sending public key");
                    byte[] encryptedPublicKey = client.GetEncryptedPublicKey();


                    Console.WriteLine("[Server] Received encrypted public key");
                    serverError = server.onReceiveData(encryptedPublicKey, ref ServerResponseData);
                    if (serverError != MazeErrorCode.Success)
                    {
                        Console.WriteLine("[Server] Encrypted Public Key was not found in database or something else went wrong");
                        continue;//Process.GetCurrentProcess().WaitForExit();
                    }
                    Console.WriteLine("[Server] Sending back response to client len:" + ServerResponseData.Length);

                    Console.WriteLine("[Client] Received response from server... len:" + ServerResponseData.Length + ", sending response back...");
                    clientError = client.onReceiveData(ServerResponseData, ref ClientResponseData);
                    if (clientError != MazeErrorCode.Success && clientError != MazeErrorCode.Finished)
                    {
                        Console.WriteLine("[Client] Incorrect response from server");
                        continue;//Process.GetCurrentProcess().WaitForExit();
                    }

                    Console.WriteLine("[Server] Received response from client len:" + ServerResponseData.Length);
                    serverError = server.onReceiveData(ClientResponseData, ref ServerResponseData);
                    if (serverError != MazeErrorCode.Success && serverError != MazeErrorCode.Finished)
                    {
                        Console.WriteLine("[Server] Incorrect response from client");
                        continue;//Process.GetCurrentProcess().WaitForExit();
                    }
                    Console.WriteLine("[Client] Applied the key to the encryption");
                    Console.WriteLine("[Server] Applied the key to the encryption");

                    Console.WriteLine("[Client-Key] " + BitConverter.ToString(client.wopEx.Key).Substring(0, 50) + "....");
                    Console.WriteLine("[Client-Salt] " + BitConverter.ToString(client.wopEx.Salt).Substring(0, 50) + "....");
                    Console.WriteLine("[Server-Key] " + BitConverter.ToString(server.wopEx.Key).Substring(0, 50) + "....");
                    Console.WriteLine("[Server-Salt] " + BitConverter.ToString(server.wopEx.Salt).Substring(0, 50));

                    sw.Stop();
                    Console.WriteLine("Done... Authenticated without sending login data, completed in " + sw.Elapsed);
                }
            }
        }
Example #4
0
        private static void SecureHandshake_SingleUser()
        {
            MazeErrorCode clientError = MazeErrorCode.Error;
            MazeErrorCode serverError = MazeErrorCode.Error;
            int           multiplier  = 100;

            //create users
            User temp_user = new User();

            Console.WriteLine("[Server] Creating user table...");
            //Add real data here if you want to test this out
            temp_user.Username  = "******";
            temp_user.Password  = "******";
            temp_user.PublicKey = GetRandomBytes(128 * multiplier);      //File.ReadAllBytes("./Data/PublicKey1.dat"));
            temp_user.PrivateKeys.Add(GetRandomBytes(128 * multiplier)); //File.ReadAllBytes("./Data/PrivateKey1.dat"));
            temp_user.PrivateKeys.Add(GetRandomBytes(128 * multiplier)); //(File.ReadAllBytes("./Data/PrivateKey2.dat"));

            temp_user.GenServerKey();

            ClientMaze client = new ClientMaze(new System.Drawing.Size(128, 128), 1, 5);
            ServerMaze server = new ServerMaze(new System.Drawing.Size(128, 128), 1, 5);

            server.onFindKeyInDatabase += server_onFindKeyInDatabase;

            Server_Users = new List <User>();
            Server_Users.Add(temp_user);

            while (true)
            {
                Console.WriteLine(".............................................................");

                Stopwatch sw = Stopwatch.StartNew();

                byte[] ClientResponseData = new byte[0];
                byte[] ServerResponseData = new byte[0];

                //1. Send server the bytecode
                byte[] byteCode = client.GetByteCode();
                Console.WriteLine("[Client] Sending ByteCode to server");


                //2. Server receives the ByteCode
                serverError = server.onReceiveData(byteCode, ref ServerResponseData);
                if (serverError == MazeErrorCode.Success)
                {
                    Console.WriteLine("[Server] ByteCode is correct, continue on with handshake");
                }
                else
                {
                    Console.WriteLine("[Server] ByteCode is not correct, disconnecting...");
                }


                //in this example we will simply keep this simple, so no additional encryption(s) will be used here except the one that is being used by the handshake it self
                Console.WriteLine("[Client] Setting login data... username:"******"[Client] Calculating the key");
                BigInteger mazeKey = client.SetMazeKey();


                Console.WriteLine("[Client] Encrypting the public key & sending public key");
                byte[] encryptedPublicKey = client.GetEncryptedPublicKey();


                Console.WriteLine("[Server] Received encrypted public key");
                serverError = server.onReceiveData(encryptedPublicKey, ref ServerResponseData);
                if (serverError != MazeErrorCode.Success)
                {
                    Console.WriteLine("[Server] Encrypted Public Key was not found in database or something else went wrong");
                    continue;//Process.GetCurrentProcess().WaitForExit();
                }
                Console.WriteLine("[Server] Sending back response to client len:" + ServerResponseData.Length);

                Console.WriteLine("[Client] Received response from server... len:" + ServerResponseData.Length + ", sending response back...");
                clientError = client.onReceiveData(ServerResponseData, ref ClientResponseData);
                if (clientError != MazeErrorCode.Success && clientError != MazeErrorCode.Finished)
                {
                    Console.WriteLine("[Client] Incorrect response from server");
                    continue;//Process.GetCurrentProcess().WaitForExit();
                }

                Console.WriteLine("[Server] Received response from client len:" + ServerResponseData.Length);
                serverError = server.onReceiveData(ClientResponseData, ref ServerResponseData);
                if (serverError != MazeErrorCode.Success && serverError != MazeErrorCode.Finished)
                {
                    Console.WriteLine("[Server] Incorrect response from client");
                    continue;//Process.GetCurrentProcess().WaitForExit();
                }
                Console.WriteLine("[Client] Applied the key to the encryption");
                Console.WriteLine("[Server] Applied the key to the encryption");

                Console.WriteLine("[Client-Key] " + BitConverter.ToString(client.wopEx.Key).Substring(0, 50) + "....");
                Console.WriteLine("[Client-Salt] " + BitConverter.ToString(client.wopEx.Salt).Substring(0, 50) + "....");
                Console.WriteLine("[Server-Key] " + BitConverter.ToString(server.wopEx.Key).Substring(0, 50) + "....");
                Console.WriteLine("[Server-Salt] " + BitConverter.ToString(server.wopEx.Salt).Substring(0, 50));

                sw.Stop();
                Console.WriteLine("Done... Authenticated without sending login data, completed in " + sw.Elapsed);

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("Re-Calculating the private keys");
                int           keyCount        = temp_user.PrivateKeys.Count;
                List <Stream> calcPrivateKeys = new List <Stream>();
                for (int i = 0; i < keyCount; i++)
                {
                    Console.WriteLine("Old Privatekey[" + i.ToString("D2") + "] " + BitConverter.ToString(temp_user.PrivateKeys[i]).Substring(0, 50) + "....");
                    calcPrivateKeys.Add(client.RecalculatePrivateKey(new MemoryStream(temp_user.PrivateKeys[i])));
                    Console.WriteLine("New Privatekey[" + i.ToString("D2") + "] " + BitConverter.ToString(temp_user.PrivateKeys[i]).Substring(0, 50) + "....");
                }

                //because of the MemoryStream we don't need to remove/add the keys, but in a remote server you must so I'll leave this here

                /*temp_user.PrivateKeys.Clear();
                 * for (int i = 0; i < keyCount; i++)
                 * {
                 *  temp_user.PrivateKeys.Add((calcPrivateKeys[i] as MemoryStream).ToArray());
                 * }*/

                temp_user.GenServerKey();

                //re-initialize the client/server for new login attempt ;)
                client = new ClientMaze(new System.Drawing.Size(128, 128), 1, 5);
                server = new ServerMaze(new System.Drawing.Size(128, 128), 1, 5);
                server.onFindKeyInDatabase += server_onFindKeyInDatabase;
            }
        }
Example #5
0
        internal void Connect(ConnectionState State)
        {
            IPAddress[] resolved = Dns.GetHostAddresses(Properties.HostIp);
            string      DnsIp    = "";
            bool        IsIPv6   = false;

            for (int i = 0; i < resolved.Length; i++)
            {
                if (resolved[i].AddressFamily == AddressFamily.InterNetwork ||
                    resolved[i].AddressFamily == AddressFamily.InterNetworkV6)
                {
                    IsIPv6 = resolved[i].AddressFamily == AddressFamily.InterNetworkV6;
                    DnsIp  = resolved[i].ToString();
                    break;
                }
            }

            if (DnsIp == "")
            {
                throw new Exception("Unable to resolve \"" + Properties.HostIp + "\" by using DNS");
            }

            int ConTimeout = Properties.ConnectionTimeout;

            do
            {
                this.Handle = new Socket(IsIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IAsyncResult result = this.Handle.BeginConnect(new IPEndPoint(resolved[0], Properties.Port), (IAsyncResult ar) =>
                {
                    try
                    {
                        this.Handle.EndConnect(ar);
                    }
                    catch (Exception ex)
                    {
                        /* Will throw a error if connection couldn't be made */
                        SysLogger.Log(ex.Message, SysLogType.Error);
                    }
                }, null);

                Stopwatch sw = Stopwatch.StartNew();
                if (ConTimeout > 0)
                {
                    result.AsyncWaitHandle.WaitOne(ConTimeout);
                }
                else
                {
                    result.AsyncWaitHandle.WaitOne();
                }

                sw.Stop();
                ConTimeout -= (int)sw.ElapsedMilliseconds;

                if (!this.Handle.Connected)
                {
                    this.Handle.Close();
                }
            } while (ConTimeout > 0 && !this.Handle.Connected);

            if (!Handle.Connected)
            {
                throw new Exception("Unable to establish a connection with " + Properties.HostIp + ":" + Properties.Port);
            }

            Connection = new Connection(this);
            Connection.StartReceiver();

            onBeforeConnect();

            //let's begin the handshake
            User user = new User(Properties.Username, Properties.Password, new List <Stream>(Properties.PrivateKeyFiles), Properties.PublicKeyFile);

            user.GenKey(this, SessionSide.Client, Properties.Handshake_Maze_Size, Properties.Handshake_MazeCount, Properties.Handshake_StepSize);

            this.clientHS = user.MazeHandshake;
            byte[] encryptedPublicKey = clientHS.GetEncryptedPublicKey();


            byte[] byteCode = clientHS.GetByteCode();
            Connection.SendMessage(new MsgHandshake(byteCode), new SystemHeader());

            //send our encrypted public key
            Connection.SendMessage(new MsgHandshake(encryptedPublicKey), new SystemHeader());

            //and now just wait for the handshake to finish... can't take longer then 60 seconds
            MazeErrorCode errorCode = Connection.HandshakeSync.Wait <MazeErrorCode>(MazeErrorCode.Error, 60000);

            if (errorCode != MazeErrorCode.Finished)
            {
                throw new Exception("Username or Password is incorrect.");
            }

            bool initOk = Connection.InitSync.Wait <bool>(false, 30000);

            if (!initOk)
            {
                throw new Exception("A server time-out occured");
            }

            //re-calculate the private keys
            for (int i = 0; i < Properties.PrivateKeyFiles.Length; i++)
            {
                clientHS.RecalculatePrivateKey(Properties.PrivateKeyFiles[i]);
            }

            this.Username = Properties.Username;

            this.KeepAliveTimer          = new System.Timers.Timer();
            this.KeepAliveTimer.Interval = 5000;
            this.KeepAliveTimer.Elapsed += KeepAliveTimer_Elapsed;
            this.KeepAliveTimer.Enabled  = true;

            onConnect();
        }