using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
namespace Renci.SshNet.Security
{
internal abstract class KeyExchangeDiffieHellmanGroupShaBase : KeyExchangeDiffieHellman
{
///
/// Gets the group prime.
///
///
/// The group prime.
///
public abstract BigInteger GroupPrime { get; }
///
/// Starts key exchange algorithm.
///
/// The session.
/// Key exchange init message.
public override void Start(Session session, KeyExchangeInitMessage message)
{
base.Start(session, message);
Session.RegisterMessage("SSH_MSG_KEXDH_REPLY");
Session.KeyExchangeDhReplyMessageReceived += Session_KeyExchangeDhReplyMessageReceived;
_prime = GroupPrime;
_group = new BigInteger(new byte[] { 2 });
PopulateClientExchangeValue();
SendMessage(new KeyExchangeDhInitMessage(_clientExchangeValue));
}
///
/// Finishes key exchange algorithm.
///
public override void Finish()
{
base.Finish();
Session.KeyExchangeDhReplyMessageReceived -= Session_KeyExchangeDhReplyMessageReceived;
}
///
/// Calculates key exchange hash value.
///
///
/// Key exchange hash.
///
protected override byte[] CalculateHash()
{
var keyExchangeHashData = new KeyExchangeHashData
{
ClientVersion = Session.ClientVersion,
ServerVersion = Session.ServerVersion,
ClientPayload = _clientPayload,
ServerPayload = _serverPayload,
HostKey = _hostKey,
ClientExchangeValue = _clientExchangeValue,
ServerExchangeValue = _serverExchangeValue,
SharedKey = SharedKey,
};
return Hash(keyExchangeHashData.GetBytes());
}
private void Session_KeyExchangeDhReplyMessageReceived(object sender, MessageEventArgs e)
{
var message = e.Message;
// Unregister message once received
Session.UnRegisterMessage("SSH_MSG_KEXDH_REPLY");
HandleServerDhReply(message.HostKey, message.F, message.Signature);
// When SSH_MSG_KEXDH_REPLY received key exchange is completed
Finish();
}
}
}