using System.Text; using Renci.SshNet.Common; using Renci.SshNet.Messages.Transport; namespace Renci.SshNet.Security { internal abstract class KeyExchangeEC : KeyExchange { /// /// Specifies client payload /// protected byte[] _clientPayload; /// /// Specifies server payload /// protected byte[] _serverPayload; /// /// Specifies client exchange. /// protected byte[] _clientExchangeValue; /// /// Specifies server exchange. /// protected byte[] _serverExchangeValue; /// /// Specifies host key data. /// protected byte[] _hostKey; /// /// Specifies signature data. /// protected byte[] _signature; /// /// Gets the size, in bits, of the computed hash code. /// /// /// The size, in bits, of the computed hash code. /// protected abstract int HashSize { get; } /// /// Calculates key exchange hash value. /// /// /// Key exchange hash. /// protected override byte[] CalculateHash() { var hashData = new KeyExchangeHashData { ClientVersion = Session.ClientVersion, ServerVersion = Session.ServerVersion, ClientPayload = _clientPayload, ServerPayload = _serverPayload, HostKey = _hostKey, ClientExchangeValue = _clientExchangeValue, ServerExchangeValue = _serverExchangeValue, SharedKey = SharedKey, }; return Hash(hashData.GetBytes()); } /// /// Validates the exchange hash. /// /// /// true if exchange hash is valid; otherwise false. /// protected override bool ValidateExchangeHash() { var exchangeHash = CalculateHash(); var length = Pack.BigEndianToUInt32(_hostKey); var algorithmName = Encoding.UTF8.GetString(_hostKey, 4, (int)length); var key = Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](_hostKey); Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName; if (CanTrustHostKey(key)) { return key.VerifySignature(exchangeHash, _signature); } return false; } /// /// Starts key exchange algorithm. /// /// The session. /// Key exchange init message. public override void Start(Session session, KeyExchangeInitMessage message) { base.Start(session, message); _serverPayload = message.GetBytes(); _clientPayload = Session.ClientInitMessage.GetBytes(); } } }