KeyExchangeECDH
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Agreement;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Generators;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters;
using Renci.SshNet.Security.Org.BouncyCastle.Math;
using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
using Renci.SshNet.Security.Org.BouncyCastle.Security;
using System;
namespace Renci.SshNet.Security
{
internal abstract class KeyExchangeECDH : KeyExchangeEC
{
private ECDHCBasicAgreement _keyAgreement;
private ECDomainParameters _domainParameters;
protected abstract X9ECParameters CurveParameter { get; }
public override void Start(Session session, KeyExchangeInitMessage message)
{
base.Start(session, message);
base.Session.RegisterMessage("SSH_MSG_KEX_ECDH_REPLY");
base.Session.KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived;
_domainParameters = new ECDomainParameters(CurveParameter.Curve, CurveParameter.G, CurveParameter.N, CurveParameter.H, CurveParameter.GetSeed());
ECKeyPairGenerator eCKeyPairGenerator = new ECKeyPairGenerator();
eCKeyPairGenerator.Init(new ECKeyGenerationParameters(_domainParameters, new SecureRandom()));
AsymmetricCipherKeyPair asymmetricCipherKeyPair = eCKeyPairGenerator.GenerateKeyPair();
_keyAgreement = new ECDHCBasicAgreement();
_keyAgreement.Init(asymmetricCipherKeyPair.Private);
_clientExchangeValue = ((ECPublicKeyParameters)asymmetricCipherKeyPair.Public).Q.GetEncoded();
SendMessage(new KeyExchangeEcdhInitMessage(_clientExchangeValue));
}
public override void Finish()
{
base.Finish();
base.Session.KeyExchangeEcdhReplyMessageReceived -= Session_KeyExchangeEcdhReplyMessageReceived;
}
private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs<KeyExchangeEcdhReplyMessage> e)
{
KeyExchangeEcdhReplyMessage message = e.Message;
base.Session.UnRegisterMessage("SSH_MSG_KEX_ECDH_REPLY");
HandleServerEcdhReply(message.KS, message.QS, message.Signature);
Finish();
}
private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, byte[] signature)
{
_serverExchangeValue = serverExchangeValue;
_hostKey = hostKey;
_signature = signature;
int num = (serverExchangeValue.Length - 1) / 2;
byte[] array = new byte[num];
Buffer.BlockCopy(serverExchangeValue, 1, array, 0, array.Length);
byte[] array2 = new byte[num];
Buffer.BlockCopy(serverExchangeValue, num + 1, array2, 0, array2.Length);
ECPoint q = ((FpCurve)_domainParameters.Curve).CreatePoint(new Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger(1, array), new Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger(1, array2));
ECPublicKeyParameters pubKey = new ECPublicKeyParameters("ECDH", q, _domainParameters);
Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger bigInteger = _keyAgreement.CalculateAgreement(pubKey);
base.SharedKey = bigInteger.ToByteArray().ToBigInteger2().ToByteArray()
.Reverse();
}
}
}