Permalink
Cannot retrieve contributors at this time
114 lines (95 sloc)
3.84 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
SSH.NET/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs /
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using Renci.SshNet.Abstractions; | |
| 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; | |
| } | |
| /// <summary> | |
| /// Hashes the specified data bytes. | |
| /// </summary> | |
| /// <param name="hashData">The hash data.</param> | |
| /// <returns> | |
| /// Hashed bytes | |
| /// </returns> | |
| protected override byte[] Hash(byte[] hashData) | |
| { | |
| using (var sha256 = CryptoAbstraction.CreateSHA256()) | |
| { | |
| return sha256.ComputeHash(hashData, 0, hashData.Length); | |
| } | |
| } | |
| 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> | |
| private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, byte[] signature) | |
| { | |
| _serverExchangeValue = serverExchangeValue; | |
| _hostKey = hostKey; | |
| _signature = signature; | |
| var sharedKey = new byte[MontgomeryCurve25519.PublicKeySizeInBytes]; | |
| MontgomeryOperations.scalarmult(sharedKey, 0, _privateKey, 0, serverExchangeValue, 0); | |
| SharedKey = sharedKey.ToBigInteger2().ToByteArray().Reverse(); | |
| } | |
| } | |
| } |