KeyExchangeDiffieHellman
Represents base class for Diffie Hellman key exchange algorithm.
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
using System;
using System.Numerics;
namespace Renci.SshNet.Security
{
internal abstract class KeyExchangeDiffieHellman : KeyExchange
{
protected BigInteger _group;
protected BigInteger _prime;
protected byte[] _clientPayload;
protected byte[] _serverPayload;
protected byte[] _clientExchangeValue;
protected byte[] _serverExchangeValue;
protected BigInteger _privateExponent;
protected byte[] _hostKey;
protected byte[] _signature;
protected abstract int HashSize { get; }
protected override bool ValidateExchangeHash()
{
return ValidateExchangeHash(_hostKey, _signature);
}
public override void Start(Session session, KeyExchangeInitMessage message, bool sendClientInitMessage)
{
base.Start(session, message, sendClientInitMessage);
_serverPayload = message.GetBytes();
_clientPayload = base.Session.ClientInitMessage.GetBytes();
}
protected void PopulateClientExchangeValue()
{
if (_group.IsZero)
throw new ArgumentNullException("_group");
if (_prime.IsZero)
throw new ArgumentNullException("_prime");
int bitLength = Math.Max(HashSize * 2, 1024);
BigInteger left;
do {
_privateExponent = RandomBigInt(bitLength);
left = BigInteger.ModPow(_group, _privateExponent, _prime);
} while (left < 1 || left > _prime - (BigInteger)1);
_clientExchangeValue = left.ToByteArray(false, true);
}
private static BigInteger RandomBigInt(int bitLength)
{
byte[] array = CryptoAbstraction.GenerateRandom(bitLength / 8 + ((bitLength % 8 > 0) ? 1 : 0));
array[array.Length - 1] = (byte)(array[array.Length - 1] & 127);
return new BigInteger(array);
}
protected virtual void HandleServerDhReply(byte[] hostKey, byte[] serverExchangeValue, byte[] signature)
{
_serverExchangeValue = serverExchangeValue;
_hostKey = hostKey;
base.SharedKey = BigInteger.ModPow(serverExchangeValue.ToBigInteger(), _privateExponent, _prime).ToByteArray(false, true);
_signature = signature;
}
}
}