mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 01:05:42 +00:00
KEX with Elliptic Curve curve25519
Add Kex Algos curve25519-sha256(@libssh.org)
This commit is contained in:
@@ -322,6 +322,8 @@ namespace Renci.SshNet
|
||||
|
||||
KeyExchangeAlgorithms = new Dictionary<string, Type>
|
||||
{
|
||||
{"curve25519-sha256", typeof(KeyExchangeECCurve25519)},
|
||||
{"curve25519-sha256@libssh.org", typeof(KeyExchangeECCurve25519)},
|
||||
{"ecdh-sha2-nistp256", typeof(KeyExchangeECDH256)},
|
||||
{"ecdh-sha2-nistp384", typeof(KeyExchangeECDH384)},
|
||||
{"ecdh-sha2-nistp521", typeof(KeyExchangeECDH521)},
|
||||
|
||||
@@ -310,6 +310,7 @@
|
||||
<Compile Include="Security\IKeyExchange.cs" />
|
||||
<Compile Include="Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs" />
|
||||
<Compile Include="Security\KeyExchangeEC.cs" />
|
||||
<Compile Include="Security\KeyExchangeECCurve25519.cs" />
|
||||
<Compile Include="Security\KeyExchangeECDH.cs" />
|
||||
<Compile Include="Security\KeyExchangeECDH521.cs" />
|
||||
<Compile Include="Security\KeyExchangeECDH384.cs" />
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using Renci.SshNet.Common;
|
||||
using Renci.SshNet.Messages.Transport;
|
||||
using Renci.SshNet.Security.Chaos.NaCl;
|
||||
using Renci.SshNet.Security.Chaos.NaCl.Internal.Ed25519Ref10;
|
||||
|
||||
namespace Renci.SshNet.Security
|
||||
{
|
||||
internal class KeyExchangeECCurve25519 : KeyExchangeEC
|
||||
{
|
||||
private byte[] _privateKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets algorithm name.
|
||||
/// </summary>
|
||||
public override string Name
|
||||
{
|
||||
get { return "curve25519-sha256"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size, in bits, of the computed hash code.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size, in bits, of the computed hash code.
|
||||
/// </value>
|
||||
protected override int HashSize
|
||||
{
|
||||
get { return 256; }
|
||||
}
|
||||
|
||||
/// <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_ECDH_REPLY");
|
||||
|
||||
Session.KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived;
|
||||
|
||||
var basepoint = new byte[MontgomeryCurve25519.PublicKeySizeInBytes];
|
||||
basepoint[0] = 9;
|
||||
|
||||
var rnd = new Random();
|
||||
_privateKey = new byte[MontgomeryCurve25519.PrivateKeySizeInBytes];
|
||||
rnd.NextBytes(_privateKey);
|
||||
|
||||
_clientExchangeValue = new byte[MontgomeryCurve25519.PublicKeySizeInBytes];
|
||||
MontgomeryOperations.scalarmult(_clientExchangeValue, 0, _privateKey, 0, basepoint, 0);
|
||||
|
||||
SendMessage(new KeyExchangeEcdhInitMessage(_clientExchangeValue));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finishes key exchange algorithm.
|
||||
/// </summary>
|
||||
public override void Finish()
|
||||
{
|
||||
base.Finish();
|
||||
|
||||
Session.KeyExchangeEcdhReplyMessageReceived -= Session_KeyExchangeEcdhReplyMessageReceived;
|
||||
}
|
||||
|
||||
private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs<KeyExchangeEcdhReplyMessage> e)
|
||||
{
|
||||
var message = e.Message;
|
||||
|
||||
// Unregister message once received
|
||||
Session.UnRegisterMessage("SSH_MSG_KEX_ECDH_REPLY");
|
||||
|
||||
HandleServerEcdhReply(message.KS, message.QS, message.Signature);
|
||||
|
||||
// When SSH_MSG_KEXDH_REPLY received key exchange is completed
|
||||
Finish();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the server DH reply message.
|
||||
/// </summary>
|
||||
/// <param name="hostKey">The host key.</param>
|
||||
/// <param name="serverExchangeValue">The server exchange value.</param>
|
||||
/// <param name="signature">The signature.</param>
|
||||
protected override void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, byte[] signature)
|
||||
{
|
||||
_serverExchangeValue = serverExchangeValue;
|
||||
_hostKey = hostKey;
|
||||
_serverExchangeValue = serverExchangeValue;
|
||||
_signature = signature;
|
||||
|
||||
var sharedKey = new byte[MontgomeryCurve25519.PublicKeySizeInBytes];
|
||||
MontgomeryOperations.scalarmult(sharedKey, 0, _privateKey, 0, serverExchangeValue, 0);
|
||||
SharedKey = sharedKey.ToBigInteger2();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user