public override bool Pass(INodeEndpointProtocolRequest request)
            {
                lock (this.stepLock)
                {
                    switch (this.currentStep)
                    {
                    case Step.WaitingForAuthData:
                    {
                        this.currentStep = Step.WaitingForAuthResult;
                        byte[] authData          = request.Message;
                        byte[] encryptedAuthData = Md5AuthDataAndPassword(authData, this.passwordMD5);
                        this.client.Send(encryptedAuthData);
                    }
                        return(false);

                    case Step.WaitingForAuthResult:
                    {
                        this.currentStep = Step.WaitingForAesKey;
                        if (request.RequestMessage() != "PASS")
                        {
                            this.client.Disconnect();
                        }
                        else
                        {
                            byte[] publicKey, privateKey;
                            Crypting.RsaGenerateKey(out publicKey, out privateKey);

                            this.client.Send(publicKey);
                            this.privateKey = privateKey;
                        }
                    }
                        return(false);

                    case Step.WaitingForAesKey:
                    {
                        this.currentStep = Step.Done;

                        byte[] encryptedMessage = request.Message;
                        byte[] message          = Crypting.RsaDecrypt(encryptedMessage, this.privateKey);
                        this.privateKey = null;

                        int keyLength = StreamProtocol <Stream> .ReadLeadBytes(message);

                        byte[] key = new byte[keyLength];
                        byte[] iv  = new byte[message.Length - sizeof(int) - keyLength];
                        Array.Copy(message, sizeof(int), key, 0, key.Length);
                        Array.Copy(message, sizeof(int) + keyLength, iv, 0, iv.Length);
                        SetKey(key, iv);
                        this.connectionEvent.Set();
                    }
                        return(false);
                    }
                }
                return(true);
            }