Support an acceptable group of up to 8192 bits for SHA-1 and SHA-256 Diffie-Hellman Group and Key Exchange (issue #1973 and #1777), and refactor corresponding classes to avoid code duplication.

This commit is contained in:
Gert Driesen
2014-05-07 18:21:30 +00:00
parent 57496a4f3f
commit 8c4e3119ef
11 changed files with 199 additions and 297 deletions
@@ -17,6 +17,7 @@ New Features:
* Improved accuracy of IsConnected on .NET
* Added support for ssh.com (SSH-2) private keys (issue #1987)
* Support an acceptable group of up to 8192 bits for SHA-1 and SHA-256 Diffie-Hellman Group and Key Exchange (issue #1973 and #1777)
Fixes:
@@ -648,6 +648,9 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\SymmetricCipher.cs">
<Link>Security\Cryptography\SymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\GroupExchangeHashData.cs">
<Link>Security\GroupExchangeHashData.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\HostAlgorithm.cs">
<Link>Security\HostAlgorithm.cs</Link>
</Compile>
@@ -669,6 +672,9 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
@@ -889,7 +895,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -612,6 +612,9 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\SymmetricCipher.cs">
<Link>Security\Cryptography\SymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\GroupExchangeHashData.cs">
<Link>Security\GroupExchangeHashData.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\HostAlgorithm.cs">
<Link>Security\HostAlgorithm.cs</Link>
</Compile>
@@ -633,6 +636,9 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
@@ -847,7 +853,7 @@
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -621,6 +621,9 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\SymmetricCipher.cs">
<Link>Security\Cryptography\SymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\GroupExchangeHashData.cs">
<Link>Security\GroupExchangeHashData.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\HostAlgorithm.cs">
<Link>Security\HostAlgorithm.cs</Link>
</Compile>
@@ -642,6 +645,9 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
@@ -859,7 +865,7 @@
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -604,6 +604,9 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\SymmetricCipher.cs">
<Link>Security\Cryptography\SymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\GroupExchangeHashData.cs">
<Link>Security\GroupExchangeHashData.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\HostAlgorithm.cs">
<Link>Security\HostAlgorithm.cs</Link>
</Compile>
@@ -625,6 +628,9 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
@@ -651,6 +651,9 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\SymmetricCipher.cs">
<Link>Security\Cryptography\SymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\GroupExchangeHashData.cs">
<Link>Security\GroupExchangeHashData.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\HostAlgorithm.cs">
<Link>Security\HostAlgorithm.cs</Link>
</Compile>
@@ -672,6 +675,9 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
@@ -883,7 +889,7 @@
<Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -159,6 +159,8 @@
<Compile Include="Security\Cryptography\Hashes\SHA512Hash.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Security\GroupExchangeHashData.cs" />
<Compile Include="Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs" />
<Compile Include="Security\KeyExchangeEllipticCurveDiffieHellman.cs" />
<Compile Include="ShellStream.NET40.cs" />
<Compile Include="ExpectAsyncResult.cs" />
@@ -0,0 +1,56 @@
using System;
using Renci.SshNet.Common;
namespace Renci.SshNet.Security
{
internal class GroupExchangeHashData : SshData
{
public string ServerVersion { get; set; }
public string ClientVersion { get; set; }
public byte[] ClientPayload { get; set; }
public byte[] ServerPayload { get; set; }
public byte[] HostKey { get; set; }
public UInt32 MinimumGroupSize { get; set; }
public UInt32 PreferredGroupSize { get; set; }
public UInt32 MaximumGroupSize { get; set; }
public BigInteger Prime { get; set; }
public BigInteger SubGroup { get; set; }
public BigInteger ClientExchangeValue { get; set; }
public BigInteger ServerExchangeValue { get; set; }
public BigInteger SharedKey { get; set; }
protected override void LoadData()
{
throw new NotImplementedException();
}
protected override void SaveData()
{
this.Write(this.ClientVersion);
this.Write(this.ServerVersion);
this.WriteBinaryString(this.ClientPayload);
this.WriteBinaryString(this.ServerPayload);
this.WriteBinaryString(this.HostKey);
this.Write(this.MinimumGroupSize);
this.Write(this.PreferredGroupSize);
this.Write(this.MaximumGroupSize);
this.Write(this.Prime);
this.Write(this.SubGroup);
this.Write(this.ClientExchangeValue);
this.Write(this.ServerExchangeValue);
this.Write(this.SharedKey);
}
}
}
@@ -1,14 +1,9 @@
using System;
using Renci.SshNet.Messages.Transport;
using Renci.SshNet.Messages;
using Renci.SshNet.Common;
namespace Renci.SshNet.Security
namespace Renci.SshNet.Security
{
/// <summary>
/// Represents "diffie-hellman-group-exchange-sha1" algorithm implementation.
/// </summary>
internal class KeyExchangeDiffieHellmanGroupExchangeSha1 : KeyExchangeDiffieHellman
public class KeyExchangeDiffieHellmanGroupExchangeSha1 : KeyExchangeDiffieHellmanGroupExchangeShaBase
{
/// <summary>
/// Gets algorithm name.
@@ -17,145 +12,5 @@ namespace Renci.SshNet.Security
{
get { return "diffie-hellman-group-exchange-sha1"; }
}
/// <summary>
/// Calculates key exchange hash value.
/// </summary>
/// <returns>
/// Key exchange hash.
/// </returns>
protected override byte[] CalculateHash()
{
var hashData = new _ExchangeHashData
{
ClientVersion = this.Session.ClientVersion,
ServerVersion = this.Session.ServerVersion,
ClientPayload = this._clientPayload,
ServerPayload = this._serverPayload,
HostKey = this._hostKey,
MinimumGroupSize = 1024,
PreferredGroupSize = 1024,
MaximumGroupSize = 1024,
Prime = this._prime,
SubGroup = this._group,
ClientExchangeValue = this._clientExchangeValue,
ServerExchangeValue = this._serverExchangeValue,
SharedKey = this.SharedKey,
}.GetBytes();
return this.Hash(hashData);
}
/// <summary>
/// Starts key exchange algorithm
/// </summary>
/// <param name="session">The session.</param>
/// <param name="message">Key exchange init message.</param>
public override void Start(Session session, KeyExchangeInitMessage message)
{
base.Start(session, message);
this.Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
this.Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
this.Session.MessageReceived += Session_MessageReceived;
// 1. send SSH_MSG_KEY_DH_GEX_REQUEST
this.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024, 1024, 1024));
}
/// <summary>
/// Finishes key exchange algorithm.
/// </summary>
public override void Finish()
{
base.Finish();
this.Session.MessageReceived -= Session_MessageReceived;
}
private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
{
var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
if (groupMessage != null)
{
// Unregister message once received
this.Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
// 2. Receive SSH_MSG_KEX_DH_GEX_GROUP
this._prime = groupMessage.SafePrime;
this._group = groupMessage.SubGroup;
this.PopulateClientExchangeValue();
// 3. Send SSH_MSG_KEX_DH_GEX_INIT
this.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
}
var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
if (replyMessage != null)
{
// Unregister message once received
this.Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
this.HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
// When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
this.Finish();
}
}
private class _ExchangeHashData : SshData
{
public string ServerVersion { get; set; }
public string ClientVersion { get; set; }
public byte[] ClientPayload { get; set; }
public byte[] ServerPayload { get; set; }
public byte[] HostKey { get; set; }
public UInt32 MinimumGroupSize { get; set; }
public UInt32 PreferredGroupSize { get; set; }
public UInt32 MaximumGroupSize { get; set; }
public BigInteger Prime { get; set; }
public BigInteger SubGroup { get; set; }
public BigInteger ClientExchangeValue { get; set; }
public BigInteger ServerExchangeValue { get; set; }
public BigInteger SharedKey { get; set; }
protected override void LoadData()
{
throw new NotImplementedException();
}
protected override void SaveData()
{
this.Write(this.ClientVersion);
this.Write(this.ServerVersion);
this.WriteBinaryString(this.ClientPayload);
this.WriteBinaryString(this.ServerPayload);
this.WriteBinaryString(this.HostKey);
this.Write(this.MinimumGroupSize);
this.Write(this.PreferredGroupSize);
this.Write(this.MaximumGroupSize);
this.Write(this.Prime);
this.Write(this.SubGroup);
this.Write(this.ClientExchangeValue);
this.Write(this.ServerExchangeValue);
this.Write(this.SharedKey);
}
}
}
}
@@ -1,15 +1,11 @@
using System;
using Renci.SshNet.Messages.Transport;
using Renci.SshNet.Messages;
using Renci.SshNet.Common;
using Renci.SshNet.Security.Cryptography;
using Renci.SshNet.Security.Cryptography;
namespace Renci.SshNet.Security
{
/// <summary>
/// Represents "diffie-hellman-group-exchange-sha256" algorithm implementation.
/// </summary>
public class KeyExchangeDiffieHellmanGroupExchangeSha256 : KeyExchangeDiffieHellman
public class KeyExchangeDiffieHellmanGroupExchangeSha256 : KeyExchangeDiffieHellmanGroupExchangeShaBase
{
/// <summary>
/// Gets algorithm name.
@@ -19,63 +15,6 @@ namespace Renci.SshNet.Security
get { return "diffie-hellman-group-exchange-sha256"; }
}
/// <summary>
/// Starts key exchange algorithm
/// </summary>
/// <param name="session">The session.</param>
/// <param name="message">Key exchange init message.</param>
public override void Start(Session session, KeyExchangeInitMessage message)
{
base.Start(session, message);
this.Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
this.Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
this.Session.MessageReceived += Session_MessageReceived;
// 1. send SSH_MSG_KEY_DH_GEX_REQUEST
this.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024,1024,1024));
}
/// <summary>
/// Finishes key exchange algorithm.
/// </summary>
public override void Finish()
{
base.Finish();
this.Session.MessageReceived -= Session_MessageReceived;
}
/// <summary>
/// Calculates key exchange hash value.
/// </summary>
/// <returns>
/// Key exchange hash.
/// </returns>
protected override byte[] CalculateHash()
{
var hashData = new _ExchangeHashData
{
ClientVersion = this.Session.ClientVersion,
ServerVersion = this.Session.ServerVersion,
ClientPayload = this._clientPayload,
ServerPayload = this._serverPayload,
HostKey = this._hostKey,
MinimumGroupSize = 1024,
PreferredGroupSize = 1024,
MaximumGroupSize = 1024,
Prime = this._prime,
SubGroup = this._group,
ClientExchangeValue = this._clientExchangeValue,
ServerExchangeValue = this._serverExchangeValue,
SharedKey = this.SharedKey,
}.GetBytes();
return this.Hash(hashData);
}
/// <summary>
/// Hashes the specified data bytes.
/// </summary>
@@ -90,88 +29,5 @@ namespace Renci.SshNet.Security
return md.ComputeHash(hashBytes);
}
}
private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
{
var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
if (groupMessage != null)
{
// Unregister message once received
this.Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
// 2. Receive SSH_MSG_KEX_DH_GEX_GROUP
this._prime = groupMessage.SafePrime;
this._group = groupMessage.SubGroup;
this.PopulateClientExchangeValue();
// 3. Send SSH_MSG_KEX_DH_GEX_INIT
this.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
}
var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
if (replyMessage != null)
{
// Unregister message once received
this.Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
this.HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
// When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
this.Finish();
}
}
private class _ExchangeHashData : SshData
{
public string ServerVersion { get; set; }
public string ClientVersion { get; set; }
public byte[] ClientPayload { get; set; }
public byte[] ServerPayload { get; set; }
public byte[] HostKey { get; set; }
public UInt32 MinimumGroupSize { get; set; }
public UInt32 PreferredGroupSize { get; set; }
public UInt32 MaximumGroupSize { get; set; }
public BigInteger Prime { get; set; }
public BigInteger SubGroup { get; set; }
public BigInteger ClientExchangeValue { get; set; }
public BigInteger ServerExchangeValue { get; set; }
public BigInteger SharedKey { get; set; }
protected override void LoadData()
{
throw new NotImplementedException();
}
protected override void SaveData()
{
this.Write(this.ClientVersion);
this.Write(this.ServerVersion);
this.WriteBinaryString(this.ClientPayload);
this.WriteBinaryString(this.ServerPayload);
this.WriteBinaryString(this.HostKey);
this.Write(this.MinimumGroupSize);
this.Write(this.PreferredGroupSize);
this.Write(this.MaximumGroupSize);
this.Write(this.Prime);
this.Write(this.SubGroup);
this.Write(this.ClientExchangeValue);
this.Write(this.ServerExchangeValue);
this.Write(this.SharedKey);
}
}
}
}
@@ -0,0 +1,102 @@
using Renci.SshNet.Messages;
using Renci.SshNet.Messages.Transport;
namespace Renci.SshNet.Security
{
public abstract class KeyExchangeDiffieHellmanGroupExchangeShaBase : KeyExchangeDiffieHellman
{
private const int MinimumGroupSize = 1024;
private const int PreferredGroupSize = 1024;
private const int MaximumProupSize = 8192;
/// <summary>
/// Calculates key exchange hash value.
/// </summary>
/// <returns>
/// Key exchange hash.
/// </returns>
protected override byte[] CalculateHash()
{
var hashData = new GroupExchangeHashData
{
ClientVersion = Session.ClientVersion,
ServerVersion = Session.ServerVersion,
ClientPayload = _clientPayload,
ServerPayload = _serverPayload,
HostKey = _hostKey,
MinimumGroupSize = MinimumGroupSize,
PreferredGroupSize = PreferredGroupSize,
MaximumGroupSize = MaximumProupSize,
Prime = _prime,
SubGroup = _group,
ClientExchangeValue = _clientExchangeValue,
ServerExchangeValue = _serverExchangeValue,
SharedKey = SharedKey,
}.GetBytes();
return this.Hash(hashData);
}
/// <summary>
/// Starts key exchange algorithm
/// </summary>
/// <param name="session">The session.</param>
/// <param name="message">Key exchange init message.</param>
public override void Start(Session session, KeyExchangeInitMessage message)
{
base.Start(session, message);
Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
Session.MessageReceived += Session_MessageReceived;
// 1. send SSH_MSG_KEY_DH_GEX_REQUEST
SendMessage(new KeyExchangeDhGroupExchangeRequest(MinimumGroupSize, PreferredGroupSize,
MaximumProupSize));
}
/// <summary>
/// Finishes key exchange algorithm.
/// </summary>
public override void Finish()
{
base.Finish();
Session.MessageReceived -= Session_MessageReceived;
}
private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
{
var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
if (groupMessage != null)
{
// Unregister message once received
Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
// 2. Receive SSH_MSG_KEX_DH_GEX_GROUP
_prime = groupMessage.SafePrime;
_group = groupMessage.SubGroup;
PopulateClientExchangeValue();
// 3. Send SSH_MSG_KEX_DH_GEX_INIT
SendMessage(new KeyExchangeDhGroupExchangeInit(_clientExchangeValue));
}
else
{
var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
if (replyMessage != null)
{
// Unregister message once received
Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
// When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
Finish();
}
}
}
}
}