KeyExchangeDiffieHellmanGroupSha1.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. using System;
  2. using Renci.SshNet.Common;
  3. using Renci.SshNet.Messages;
  4. using Renci.SshNet.Messages.Transport;
  5. namespace Renci.SshNet.Security
  6. {
  7. /// <summary>
  8. /// Represents "diffie-hellman-group1-sha1" algorithm implementation.
  9. /// </summary>
  10. public abstract class KeyExchangeDiffieHellmanGroupSha1 : KeyExchangeDiffieHellman
  11. {
  12. /// <summary>
  13. /// Gets the group prime.
  14. /// </summary>
  15. /// <value>
  16. /// The group prime.
  17. /// </value>
  18. public abstract BigInteger GroupPrime { get; }
  19. /// <summary>
  20. /// Calculates key exchange hash value.
  21. /// </summary>
  22. /// <returns>
  23. /// Key exchange hash.
  24. /// </returns>
  25. protected override byte[] CalculateHash()
  26. {
  27. var hashData = new _ExchangeHashData
  28. {
  29. ClientVersion = Session.ClientVersion,
  30. ServerVersion = Session.ServerVersion,
  31. ClientPayload = _clientPayload,
  32. ServerPayload = _serverPayload,
  33. HostKey = _hostKey,
  34. ClientExchangeValue = _clientExchangeValue,
  35. ServerExchangeValue = _serverExchangeValue,
  36. SharedKey = SharedKey,
  37. }.GetBytes();
  38. return Hash(hashData);
  39. }
  40. /// <summary>
  41. /// Starts key exchange algorithm
  42. /// </summary>
  43. /// <param name="session">The session.</param>
  44. /// <param name="message">Key exchange init message.</param>
  45. public override void Start(Session session, KeyExchangeInitMessage message)
  46. {
  47. base.Start(session, message);
  48. Session.RegisterMessage("SSH_MSG_KEXDH_REPLY");
  49. Session.MessageReceived += Session_MessageReceived;
  50. _prime = GroupPrime;
  51. _group = new BigInteger(new byte[] { 2 });
  52. PopulateClientExchangeValue();
  53. SendMessage(new KeyExchangeDhInitMessage(_clientExchangeValue));
  54. }
  55. /// <summary>
  56. /// Finishes key exchange algorithm.
  57. /// </summary>
  58. public override void Finish()
  59. {
  60. base.Finish();
  61. Session.MessageReceived -= Session_MessageReceived;
  62. }
  63. private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
  64. {
  65. var message = e.Message as KeyExchangeDhReplyMessage;
  66. if (message != null)
  67. {
  68. // Unregister message once received
  69. Session.UnRegisterMessage("SSH_MSG_KEXDH_REPLY");
  70. HandleServerDhReply(message.HostKey, message.F, message.Signature);
  71. // When SSH_MSG_KEXDH_REPLY received key exchange is completed
  72. Finish();
  73. }
  74. }
  75. private class _ExchangeHashData : SshData
  76. {
  77. #if TUNING
  78. private byte[] _serverVersion;
  79. private byte[] _clientVersion;
  80. private byte[] _clientExchangeValue;
  81. private byte[] _serverExchangeValue;
  82. private byte[] _sharedKey;
  83. public string ServerVersion
  84. {
  85. private get { return Utf8.GetString(_serverVersion, 0, _serverVersion.Length); }
  86. set { _serverVersion = Utf8.GetBytes(value); }
  87. }
  88. #else
  89. public string ServerVersion { get; set; }
  90. #endif
  91. #if TUNING
  92. public string ClientVersion
  93. {
  94. private get { return Utf8.GetString(_clientVersion, 0, _clientVersion.Length); }
  95. set { _clientVersion = Utf8.GetBytes(value); }
  96. }
  97. #else
  98. public string ClientVersion { get; set; }
  99. #endif
  100. public byte[] ClientPayload { get; set; }
  101. public byte[] ServerPayload { get; set; }
  102. public byte[] HostKey { get; set; }
  103. #if TUNING
  104. public BigInteger ClientExchangeValue
  105. {
  106. private get { return _clientExchangeValue.ToBigInteger(); }
  107. set { _clientExchangeValue = value.ToByteArray().Reverse(); }
  108. }
  109. #else
  110. public BigInteger ClientExchangeValue { get; set; }
  111. #endif
  112. #if TUNING
  113. public BigInteger ServerExchangeValue
  114. {
  115. private get { return _serverExchangeValue.ToBigInteger(); }
  116. set { _serverExchangeValue = value.ToByteArray().Reverse(); }
  117. }
  118. #else
  119. public BigInteger ServerExchangeValue { get; set; }
  120. #endif
  121. #if TUNING
  122. public BigInteger SharedKey
  123. {
  124. private get { return _sharedKey.ToBigInteger(); }
  125. set { _sharedKey = value.ToByteArray().Reverse(); }
  126. }
  127. #else
  128. public BigInteger SharedKey { get; set; }
  129. #endif
  130. #if TUNING
  131. /// <summary>
  132. /// Gets the size of the message in bytes.
  133. /// </summary>
  134. /// <value>
  135. /// The size of the messages in bytes.
  136. /// </value>
  137. protected override int BufferCapacity
  138. {
  139. get
  140. {
  141. var capacity = base.BufferCapacity;
  142. capacity += 4; // ClientVersion length
  143. capacity += _clientVersion.Length; // ClientVersion
  144. capacity += 4; // ServerVersion length
  145. capacity += _serverVersion.Length; // ServerVersion
  146. capacity += 4; // ClientPayload length
  147. capacity += ClientPayload.Length; // ClientPayload
  148. capacity += 4; // ServerPayload length
  149. capacity += ServerPayload.Length; // ServerPayload
  150. capacity += 4; // HostKey length
  151. capacity += HostKey.Length; // HostKey
  152. capacity += 4; // ClientExchangeValue length
  153. capacity += _clientExchangeValue.Length; // ClientExchangeValue
  154. capacity += 4; // ServerExchangeValue length
  155. capacity += _serverExchangeValue.Length; // ServerExchangeValue
  156. capacity += 4; // SharedKey length
  157. capacity += _sharedKey.Length; // SharedKey
  158. return capacity;
  159. }
  160. }
  161. #endif
  162. protected override void LoadData()
  163. {
  164. throw new NotImplementedException();
  165. }
  166. protected override void SaveData()
  167. {
  168. #if TUNING
  169. WriteBinaryString(_clientVersion);
  170. WriteBinaryString(_serverVersion);
  171. #else
  172. Write(ClientVersion);
  173. Write(ServerVersion);
  174. #endif
  175. WriteBinaryString(ClientPayload);
  176. WriteBinaryString(ServerPayload);
  177. WriteBinaryString(HostKey);
  178. #if TUNING
  179. WriteBinaryString(_clientExchangeValue);
  180. WriteBinaryString(_serverExchangeValue);
  181. WriteBinaryString(_sharedKey);
  182. #else
  183. Write(ClientExchangeValue);
  184. Write(ServerExchangeValue);
  185. Write(SharedKey);
  186. #endif
  187. }
  188. }
  189. }
  190. }