Skip to content

Commit

Permalink
KEX with Elliptic Curve curve25519
Browse files Browse the repository at this point in the history
Add Kex Algos curve25519-sha256(@libssh.org)
  • Loading branch information
darinkes committed Dec 9, 2018
1 parent 4654519 commit b58a11c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Renci.SshNet/ConnectionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy

KeyExchangeAlgorithms = new Dictionary<string, Type>
{
{"curve25519-sha256", typeof(KeyExchangeECCurve25519)},
{"[email protected]", typeof(KeyExchangeECCurve25519)},
{"ecdh-sha2-nistp256", typeof(KeyExchangeECDH256)},
{"ecdh-sha2-nistp384", typeof(KeyExchangeECDH384)},
{"ecdh-sha2-nistp521", typeof(KeyExchangeECDH521)},
Expand Down
1 change: 1 addition & 0 deletions src/Renci.SshNet/Renci.SshNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
99 changes: 99 additions & 0 deletions src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
}

0 comments on commit b58a11c

Please sign in to comment.