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);
}
}
}