KeyExchangeDiffieHellmanGroupExchangeShaBase.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using Renci.SshNet.Messages;
  2. using Renci.SshNet.Messages.Transport;
  3. namespace Renci.SshNet.Security
  4. {
  5. public abstract class KeyExchangeDiffieHellmanGroupExchangeShaBase : KeyExchangeDiffieHellman
  6. {
  7. private const int MinimumGroupSize = 1024;
  8. private const int PreferredGroupSize = 1024;
  9. private const int MaximumProupSize = 8192;
  10. /// <summary>
  11. /// Calculates key exchange hash value.
  12. /// </summary>
  13. /// <returns>
  14. /// Key exchange hash.
  15. /// </returns>
  16. protected override byte[] CalculateHash()
  17. {
  18. var hashData = new GroupExchangeHashData
  19. {
  20. ClientVersion = Session.ClientVersion,
  21. ServerVersion = Session.ServerVersion,
  22. ClientPayload = _clientPayload,
  23. ServerPayload = _serverPayload,
  24. HostKey = _hostKey,
  25. MinimumGroupSize = MinimumGroupSize,
  26. PreferredGroupSize = PreferredGroupSize,
  27. MaximumGroupSize = MaximumProupSize,
  28. Prime = _prime,
  29. SubGroup = _group,
  30. ClientExchangeValue = _clientExchangeValue,
  31. ServerExchangeValue = _serverExchangeValue,
  32. SharedKey = SharedKey,
  33. }.GetBytes();
  34. return this.Hash(hashData);
  35. }
  36. /// <summary>
  37. /// Starts key exchange algorithm
  38. /// </summary>
  39. /// <param name="session">The session.</param>
  40. /// <param name="message">Key exchange init message.</param>
  41. public override void Start(Session session, KeyExchangeInitMessage message)
  42. {
  43. base.Start(session, message);
  44. Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
  45. Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
  46. Session.MessageReceived += Session_MessageReceived;
  47. // 1. send SSH_MSG_KEY_DH_GEX_REQUEST
  48. SendMessage(new KeyExchangeDhGroupExchangeRequest(MinimumGroupSize, PreferredGroupSize,
  49. MaximumProupSize));
  50. }
  51. /// <summary>
  52. /// Finishes key exchange algorithm.
  53. /// </summary>
  54. public override void Finish()
  55. {
  56. base.Finish();
  57. Session.MessageReceived -= Session_MessageReceived;
  58. }
  59. private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
  60. {
  61. var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
  62. if (groupMessage != null)
  63. {
  64. // Unregister message once received
  65. Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
  66. // 2. Receive SSH_MSG_KEX_DH_GEX_GROUP
  67. _prime = groupMessage.SafePrime;
  68. _group = groupMessage.SubGroup;
  69. PopulateClientExchangeValue();
  70. // 3. Send SSH_MSG_KEX_DH_GEX_INIT
  71. SendMessage(new KeyExchangeDhGroupExchangeInit(_clientExchangeValue));
  72. }
  73. else
  74. {
  75. var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
  76. if (replyMessage != null)
  77. {
  78. // Unregister message once received
  79. Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
  80. HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
  81. // When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
  82. Finish();
  83. }
  84. }
  85. }
  86. }
  87. }