private void authService_AuthenticateUserPublicKey(object sender, AuthUserPublicKeyEventArgs e)
        {
            var authService = (SshAuthenticationService)sender;

            e.Result = AuthenticationResult.Success;

            // Write to event log.
            LogClientAuthEvent(authService.Client, AuthenticationMethod.PublicKey, e);
        }
        protected void ProcessMsgUserAuthRequestPublicKey(SshStreamReader msgReader)
        {
            if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName);

            // Raise event to specify requested auth method.
            if (AuthenticationMethodRequested != null) AuthenticationMethodRequested(this,
                new AuthMethodRequestedEventArgs(AuthenticationMethod.PublicKey));

            // Read request information.
            bool isAuthRequest = msgReader.ReadBoolean();
            string keyAlgName = msgReader.ReadString();
            byte[] keyAndCertsData = msgReader.ReadByteString();

            // Try to find public key algorithm.
            PublicKeyAlgorithm keyAlg = null;

            try
            {
                keyAlg = (PublicKeyAlgorithm)_client.PublicKeyAlgorithms.Single(item =>
                    item.Name == keyAlgName).Clone();
            }
            catch (InvalidOperationException)
            {
                // Public key algorithm is not supported.
                SendMsgUserAuthFailure(false);
            }

            // Load key and certificats data for algorithm.
            keyAlg.LoadKeyAndCertificatesData(keyAndCertsData);

            // Check if request is actual auth request or query of whether specified public key is
            // acceptable.
            if (isAuthRequest)
            {
                // Read client signature.
                var signatureData = msgReader.ReadByteString();
                var signature = keyAlg.GetSignature(signatureData);

                // Verify signature.
                var payloadData = ((MemoryStream)msgReader.BaseStream).ToArray();

                if (VerifyPublicKeySignature(keyAlg, payloadData, 0, payloadData.Length -
                   signatureData.Length - 4, signature))
                {
                    // Raise event to get result of auth attempt.
                    var authUserEventArgs = new AuthUserPublicKeyEventArgs(_lastUserName,
                        keyAlg.ExportPublicKey());

                    AuthenticateUserPublicKey(this, authUserEventArgs);

                    // Check result of auth attempt.
                    switch (authUserEventArgs.Result)
                    {
                        case AuthenticationResult.Success:
                            // Auth has succeeded.
                            AuthenticateUser(_lastServiceName);

                            break;
                        case AuthenticationResult.FurtherAuthRequired:
                            // Auth has succeeded, but further auth is required.
                            SendMsgUserAuthFailure(true);

                            break;
                        case AuthenticationResult.Failure:
                            // Auth has failed.
                            SendMsgUserAuthFailure(false);

                            break;
                    }
                }
                else
                {
                    // Signature is invalid.
                    SendMsgUserAuthFailure(false);
                }
            }
            else
            {
                // Public key is acceptable.
                SendMsgUserAuthPkOk(keyAlgName, keyAndCertsData);
            }
        }
        protected void ProcessMsgUserAuthRequestPublicKey(SshStreamReader msgReader)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            // Raise event to specify requested auth method.
            if (AuthenticationMethodRequested != null)
            {
                AuthenticationMethodRequested(this,
                                              new AuthMethodRequestedEventArgs(AuthenticationMethod.PublicKey));
            }

            // Read request information.
            bool   isAuthRequest = msgReader.ReadBoolean();
            string keyAlgName    = msgReader.ReadString();

            byte[] keyAndCertsData = msgReader.ReadByteString();

            // Try to find public key algorithm.
            PublicKeyAlgorithm keyAlg = null;

            try
            {
                keyAlg = (PublicKeyAlgorithm)_client.PublicKeyAlgorithms.Single(item =>
                                                                                item.Name == keyAlgName).Clone();
            }
            catch (InvalidOperationException)
            {
                // Public key algorithm is not supported.
                SendMsgUserAuthFailure(false);
            }

            // Load key and certificats data for algorithm.
            keyAlg.LoadKeyAndCertificatesData(keyAndCertsData);

            // Check if request is actual auth request or query of whether specified public key is
            // acceptable.
            if (isAuthRequest)
            {
                // Read client signature.
                var signatureData = msgReader.ReadByteString();
                var signature     = keyAlg.GetSignature(signatureData);

                // Verify signature.
                var payloadData = ((MemoryStream)msgReader.BaseStream).ToArray();

                if (VerifyPublicKeySignature(keyAlg, payloadData, 0, payloadData.Length -
                                             signatureData.Length - 4, signature))
                {
                    // Raise event to get result of auth attempt.
                    var authUserEventArgs = new AuthUserPublicKeyEventArgs(_lastUserName,
                                                                           keyAlg.ExportPublicKey());

                    AuthenticateUserPublicKey(this, authUserEventArgs);

                    // Check result of auth attempt.
                    switch (authUserEventArgs.Result)
                    {
                    case AuthenticationResult.Success:
                        // Auth has succeeded.
                        AuthenticateUser(_lastServiceName);

                        break;

                    case AuthenticationResult.FurtherAuthRequired:
                        // Auth has succeeded, but further auth is required.
                        SendMsgUserAuthFailure(true);

                        break;

                    case AuthenticationResult.Failure:
                        // Auth has failed.
                        SendMsgUserAuthFailure(false);

                        break;
                    }
                }
                else
                {
                    // Signature is invalid.
                    SendMsgUserAuthFailure(false);
                }
            }
            else
            {
                // Public key is acceptable.
                SendMsgUserAuthPkOk(keyAlgName, keyAndCertsData);
            }
        }