KeyExchangeDiffieHellman
Provides the implementation of "diffie-hellman-groupN" algorithms.
            
                using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
namespace Renci.SshNet.Security
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    public class KeyExchangeDiffieHellman : KeyExchange
    {
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _clientPayload;
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _serverPayload;
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _clientExchangeValue;
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _serverExchangeValue;
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _hostKey;
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _signature;
        private readonly DHParameters _dhParameters;
        private readonly IncrementalHash _hash;
        [System.Runtime.CompilerServices.Nullable(2)]
        private DHBasicAgreement _keyAgreement;
        public override string Name { get; }
        public KeyExchangeDiffieHellman(string name, DHParameters parameters, HashAlgorithmName hashAlgorithm)
        {
            ThrowHelper.ThrowIfNull(name, "name");
            ThrowHelper.ThrowIfNull(parameters, "parameters");
            ThrowHelper.ThrowIfNullOrEmpty(hashAlgorithm.Name, "hashAlgorithm");
            Name = name;
            _dhParameters = parameters;
            try {
                _hash = IncrementalHash.CreateHash(hashAlgorithm);
            } catch (CryptographicException innerException) {
                throw new ArgumentException(string.Format("Could not create {0} from `{1}`.", "HashAlgorithm", hashAlgorithm), "hashAlgorithm", innerException);
            }
        }
        public override void Start(Session session, KeyExchangeInitMessage message, bool sendClientInitMessage)
        {
            base.Start(session, message, sendClientInitMessage);
            _serverPayload = message.GetBytes();
            _clientPayload = base.Session.ClientInitMessage.GetBytes();
            DHKeyPairGenerator val = new DHKeyPairGenerator();
            val.Init(new DHKeyGenerationParameters(CryptoAbstraction.SecureRandom, _dhParameters));
            AsymmetricCipherKeyPair val2 = val.GenerateKeyPair();
            _keyAgreement = new DHBasicAgreement();
            _keyAgreement.Init(val2.get_Private());
            _clientExchangeValue = val2.get_Public().get_Y().ToByteArray();
            base.Session.RegisterMessage("SSH_MSG_KEXDH_REPLY");
            base.Session.KeyExchangeDhReplyMessageReceived += Session_KeyExchangeDhReplyMessageReceived;
            SendMessage(new KeyExchangeDhInitMessage(_clientExchangeValue));
        }
        protected override byte[] CalculateHash()
        {
            KeyExchangeHashData keyExchangeHashData = new KeyExchangeHashData {
                ClientVersion = base.Session.ClientVersion,
                ServerVersion = base.Session.ServerVersion,
                ClientPayload = _clientPayload,
                ServerPayload = _serverPayload,
                HostKey = _hostKey,
                ClientExchangeValue = _clientExchangeValue,
                ServerExchangeValue = _serverExchangeValue,
                SharedKey = base.SharedKey
            };
            return Hash(keyExchangeHashData.GetBytes());
        }
        private void Session_KeyExchangeDhReplyMessageReceived([System.Runtime.CompilerServices.Nullable(2)] object sender, MessageEventArgs<KeyExchangeDhReplyMessage> e)
        {
            KeyExchangeDhReplyMessage message = e.Message;
            base.Session.KeyExchangeDhReplyMessageReceived -= Session_KeyExchangeDhReplyMessageReceived;
            base.Session.UnRegisterMessage("SSH_MSG_KEXDH_REPLY");
            _serverExchangeValue = message.F;
            _hostKey = message.HostKey;
            _signature = message.Signature;
            DHPublicKeyParameters val = new DHPublicKeyParameters(new BigInteger(message.F), _dhParameters);
            base.SharedKey = _keyAgreement.CalculateAgreement(val).ToByteArray();
            Finish();
        }
        protected override bool ValidateExchangeHash()
        {
            return ValidateExchangeHash(_hostKey, _signature);
        }
        protected override byte[] Hash(byte[] hashData)
        {
            _hash.AppendData(hashData);
            return _hash.GetHashAndReset();
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
                _hash.Dispose();
            base.Dispose(disposing);
        }
    }
}