mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-10-19 15:20:21 +08:00
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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-147
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-146
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+102
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user