KeyExchangeDiffieHellmanGroupExchangeSha1.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Renci.SshNet.Messages.Transport;
  6. using System.Security.Cryptography;
  7. using Renci.SshNet.Messages;
  8. using Renci.SshNet.Common;
  9. using System.Diagnostics;
  10. namespace Renci.SshNet.Security
  11. {
  12. /// <summary>
  13. /// Represents "diffie-hellman-group-exchange-sha1" algorithm implementation.
  14. /// </summary>
  15. internal class KeyExchangeDiffieHellmanGroupExchangeSha1 : KeyExchangeDiffieHellman
  16. {
  17. /// <summary>
  18. /// Gets algorithm name.
  19. /// </summary>
  20. public override string Name
  21. {
  22. get { return "diffie-hellman-group-exchange-sha1"; }
  23. }
  24. /// <summary>
  25. /// Calculates key exchange hash value.
  26. /// </summary>
  27. /// <returns>
  28. /// Key exchange hash.
  29. /// </returns>
  30. protected override byte[] CalculateHash()
  31. {
  32. var hashData = new _ExchangeHashData
  33. {
  34. ClientVersion = this.Session.ClientVersion,
  35. ServerVersion = this.Session.ServerVersion,
  36. ClientPayload = this._clientPayload,
  37. ServerPayload = this._serverPayload,
  38. HostKey = this._hostKey,
  39. MinimumGroupSize = 1024,
  40. PreferredGroupSize = 1024,
  41. MaximumGroupSize = 1024,
  42. Prime = this._prime,
  43. SubGroup = this._group,
  44. ClientExchangeValue = this._clientExchangeValue,
  45. ServerExchangeValue = this._serverExchangeValue,
  46. SharedKey = this.SharedKey,
  47. }.GetBytes();
  48. return this.Hash(hashData);
  49. }
  50. /// <summary>
  51. /// Starts key exchange algorithm
  52. /// </summary>
  53. /// <param name="session">The session.</param>
  54. /// <param name="message">Key exchange init message.</param>
  55. public override void Start(Session session, KeyExchangeInitMessage message)
  56. {
  57. base.Start(session, message);
  58. this.Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
  59. this.Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
  60. this.Session.MessageReceived += Session_MessageReceived;
  61. // 1. send SSH_MSG_KEY_DH_GEX_REQUEST
  62. this.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024, 1024, 1024));
  63. }
  64. /// <summary>
  65. /// Finishes key exchange algorithm.
  66. /// </summary>
  67. public override void Finish()
  68. {
  69. base.Finish();
  70. this.Session.MessageReceived -= Session_MessageReceived;
  71. }
  72. private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
  73. {
  74. var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
  75. if (groupMessage != null)
  76. {
  77. // Unregister message once received
  78. this.Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
  79. // 2. Receive SSH_MSG_KEX_DH_GEX_GROUP
  80. this._prime = groupMessage.SafePrime;
  81. this._group = groupMessage.SubGroup;
  82. this.PopulateClientExchangeValue();
  83. // 3. Send SSH_MSG_KEX_DH_GEX_INIT
  84. this.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
  85. }
  86. var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
  87. if (replyMessage != null)
  88. {
  89. // Unregister message once received
  90. this.Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
  91. this.HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
  92. // When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
  93. this.Finish();
  94. }
  95. }
  96. private class _ExchangeHashData : SshData
  97. {
  98. public string ServerVersion { get; set; }
  99. public string ClientVersion { get; set; }
  100. public byte[] ClientPayload { get; set; }
  101. public byte[] ServerPayload { get; set; }
  102. public byte[] HostKey { get; set; }
  103. public UInt32 MinimumGroupSize { get; set; }
  104. public UInt32 PreferredGroupSize { get; set; }
  105. public UInt32 MaximumGroupSize { get; set; }
  106. public BigInteger Prime { get; set; }
  107. public BigInteger SubGroup { get; set; }
  108. public BigInteger ClientExchangeValue { get; set; }
  109. public BigInteger ServerExchangeValue { get; set; }
  110. public BigInteger SharedKey { get; set; }
  111. protected override void LoadData()
  112. {
  113. throw new System.NotImplementedException();
  114. }
  115. protected override void SaveData()
  116. {
  117. this.Write(this.ClientVersion);
  118. this.Write(this.ServerVersion);
  119. this.WriteBinaryString(this.ClientPayload);
  120. this.WriteBinaryString(this.ServerPayload);
  121. this.WriteBinaryString(this.HostKey);
  122. this.Write(this.MinimumGroupSize);
  123. this.Write(this.PreferredGroupSize);
  124. this.Write(this.MaximumGroupSize);
  125. this.Write(this.Prime);
  126. this.Write(this.SubGroup);
  127. this.Write(this.ClientExchangeValue);
  128. this.Write(this.ServerExchangeValue);
  129. this.Write(this.SharedKey);
  130. }
  131. }
  132. }
  133. }