Error while processing packet V. Key exchange failed.

0 votes
asked Jul 19, 2016 by s4ber7 (140 points)

I have an SFTP server running in the wild and I keep getting random connections from other countries. This is absolutely expected, but I would like to be able to detect this issue and reject connections from these IPs. The problem is that I don't know where to catch this exception and record the IP. I have tried placing a try catch around code in my Authentication Event Handler, but the error isn't being thrown there.

Session 273: Error: Rebex.Net.Protocols.Ssh.ZSC: Error while processing packet V. Key exchange failed. ---> Rebex.Net.Protocols.Ssh.ZSC: Key exchange failed. ---> System.Security.Cryptography.CryptographicException: Key not valid for use in specified state.

   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.Utils._ExportKey(SafeKeyHandle hKey, Int32 blobType, Object cspObject)
   at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
   at Rebex.Security.Cryptography.CryptoHelper.WS(RSA T, Byte[] U, String D, Boolean C, RD M)
   at Rebex.Security.Cryptography.CryptoHelper.YS(RSA T, Byte[] U, String D, Boolean C, RD M)
   at Rebex.Security.Cryptography.AsymmetricKeyAlgorithm.SignHash(Byte[] hash, SignatureHashAlgorithm hashAlgorithm)
   at Rebex.Net.SshPrivateKey.N(Byte[] T, Boolean U, SignatureHashAlgorithm D)
   at Rebex.Net.SshPrivateKey.CreateSignature(Byte[] hash, SignatureHashAlgorithm algorithm)
   at Rebex.Net.Protocols.Ssh.ZHD.OS(ETC T, XPD U)
   at Rebex.Net.Protocols.Ssh.YHD.JS(ETC T, XPD U)
   --- End of inner exception stack trace ---
   at Rebex.Net.Protocols.Ssh.YHD.JS(ETC T, XPD U)
   at Rebex.Net.Protocols.Ssh.MSC.DC(Int32 T, Int32 U)
   --- End of inner exception stack trace ---
   at Rebex.Net.Protocols.Ssh.MSC.DC(Int32 T, Int32 U)
   at Rebex.Net.Protocols.Ssh.MSC.DC()
   at Rebex.Net.Protocols.Ssh.MSC.HD(Int32 T, Int32 U, Int32 D, Int32 C, SocketException M)

Can you explain what this error means, and perhaps tell me where I could catch it and have access to the client IP? I only have access to the exception and session id in the ErrorOccurred Handler.

1 Answer

0 votes
answered Jul 20, 2016 by Lukas Pokorny (85,170 points)

You actually ask two different questions:

1) How to reject connections based on their IP address?

Fortunately, this is very simple - use FileServer.Connecting event:

server.Connecting += (sender, e) =>
{
    // only accept sessions from clients within 192.168.1.* network
    if (e.ClientAddress.ToString().StartsWith("192.168.1."))
        e.Accept = true;
    else
        e.Accept = false;
};

Setting Accept to false will reject clients before they even attempt SSH negotiation.


2) What does the error mean?

The "Key exchange failed" error occurred because it was not possible to use the server RSA key to sign a hash during SSH session negotiation.

The actual cause of this was the "Key not valid for use in specified state" error thrown by .NET's RSACryptoServiceProvider object. This error usually indicates that something is wrong with the RSA key or key storage - see Microsoft Forum for suggested solutions.

How often does this occur? This doesn't seem to be related to different clients - if the RSA key is unusable, I would expect this to fail for all clients attempting RSA-based host key negotiation. Are you actually able to connect to this server yourself?

However, what's definitely worth mentioning is that RSACryptoServiceProvider.ExportParameters method has been called by the AsymmetricKeyAlgorithm.SignHash method - this indicates that RSACryptoServiceProvider.SignHash was attempted first and it failed. As a workaround of the last resort, AsymmetricKeyAlgorithm.SignHash tried to export the key in order to retry the signing operation using RSAManaged class - but this truned out to be impossible because RSACryptoServiceProvider.ExportParameters method failed as well.

commented Jul 21, 2016 by s4ber7 (140 points)
edited Jul 21, 2016 by s4ber7
Ok you're right. It isn't working for any connections. That's because I just updated the binaries to BetaBuild6037 from BetaBuild6010. Once I reverted, everything started working again. Is there a new BetaBuild that will work?
commented Jul 25, 2016 by Lukas Pokorny (85,170 points)
Thanks for letting us know - this was actually caused by a bug (RSACryptoServiceProvider.SignHash was not called even when it should have been). I sent a link to the current beta build to your e-mail. Please download it and give it a try. Sorry for inconvenience!
commented Jul 29, 2016 by Lukas Pokorny (85,170 points)
We have released Rebex File Server 2016 R2.1 that fixes this issue. See http://www.rebex.net/file-server/history.aspx#2016R2.1 for details.
...