Skip to content

Use BouncyCastle for Diffie-Hellman key exchange #1654

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/Renci.SshNet/ConnectionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Security.Cryptography;
using System.Text;

using Org.BouncyCastle.Crypto.Agreement;

using Renci.SshNet.Common;
using Renci.SshNet.Compression;
using Renci.SshNet.Messages.Authentication;
Expand Down Expand Up @@ -355,12 +357,13 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy
{ "ecdh-sha2-nistp256", () => new KeyExchangeECDH256() },
{ "ecdh-sha2-nistp384", () => new KeyExchangeECDH384() },
{ "ecdh-sha2-nistp521", () => new KeyExchangeECDH521() },
{ "diffie-hellman-group-exchange-sha256", () => new KeyExchangeDiffieHellmanGroupExchangeSha256() },
{ "diffie-hellman-group-exchange-sha1", () => new KeyExchangeDiffieHellmanGroupExchangeSha1() },
{ "diffie-hellman-group16-sha512", () => new KeyExchangeDiffieHellmanGroup16Sha512() },
{ "diffie-hellman-group14-sha256", () => new KeyExchangeDiffieHellmanGroup14Sha256() },
{ "diffie-hellman-group14-sha1", () => new KeyExchangeDiffieHellmanGroup14Sha1() },
{ "diffie-hellman-group1-sha1", () => new KeyExchangeDiffieHellmanGroup1Sha1() },
{ "diffie-hellman-group-exchange-sha256", () => new KeyExchangeDiffieHellmanGroupExchange("diffie-hellman-group-exchange-sha256", HashAlgorithmName.SHA256) },
{ "diffie-hellman-group16-sha512", () => new KeyExchangeDiffieHellman("diffie-hellman-group16-sha512", DHStandardGroups.rfc3526_4096, HashAlgorithmName.SHA512) },
{ "diffie-hellman-group18-sha512", () => new KeyExchangeDiffieHellman("diffie-hellman-group18-sha512", DHStandardGroups.rfc3526_8192, HashAlgorithmName.SHA512) },
{ "diffie-hellman-group14-sha256", () => new KeyExchangeDiffieHellman("diffie-hellman-group14-sha256", DHStandardGroups.rfc3526_2048, HashAlgorithmName.SHA256) },
{ "diffie-hellman-group-exchange-sha1", () => new KeyExchangeDiffieHellmanGroupExchange("diffie-hellman-group-exchange-sha1", HashAlgorithmName.SHA1) },
{ "diffie-hellman-group14-sha1", () => new KeyExchangeDiffieHellman("diffie-hellman-group14-sha1", DHStandardGroups.rfc3526_2048, HashAlgorithmName.SHA1) },
{ "diffie-hellman-group1-sha1", () => new KeyExchangeDiffieHellman("diffie-hellman-group1-sha1", DHStandardGroups.rfc2409_1024, HashAlgorithmName.SHA1) },
};

Encryptions = new OrderedDictionary<string, CipherInfo>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ namespace Renci.SshNet.Messages.Transport
/// </summary>
public class KeyExchangeDhGroupExchangeGroup : Message
{
private byte[] _safePrime;
private byte[] _subGroup;
internal byte[] SafePrimeBytes { get; private set; }
internal byte[] SubGroupBytes { get; private set; }

/// <inheritdoc />
public override string MessageName
Expand Down Expand Up @@ -38,7 +38,7 @@ public override byte MessageNumber
/// </value>
public BigInteger SafePrime
{
get { return _safePrime.ToBigInteger(); }
get { return SafePrimeBytes.ToBigInteger(); }
}

/// <summary>
Expand All @@ -49,7 +49,7 @@ public BigInteger SafePrime
/// </value>
public BigInteger SubGroup
{
get { return _subGroup.ToBigInteger(); }
get { return SubGroupBytes.ToBigInteger(); }
}

/// <summary>
Expand All @@ -64,9 +64,9 @@ protected override int BufferCapacity
{
var capacity = base.BufferCapacity;
capacity += 4; // SafePrime length
capacity += _safePrime.Length; // SafePrime
capacity += SafePrimeBytes.Length; // SafePrime
capacity += 4; // SubGroup length
capacity += _subGroup.Length; // SubGroup
capacity += SubGroupBytes.Length; // SubGroup

return capacity;
}
Expand All @@ -77,17 +77,17 @@ protected override int BufferCapacity
/// </summary>
protected override void LoadData()
{
_safePrime = ReadBinary();
_subGroup = ReadBinary();
SafePrimeBytes = ReadBinary();
SubGroupBytes = ReadBinary();
}

/// <summary>
/// Called when type specific data need to be saved.
/// </summary>
protected override void SaveData()
{
WriteBinaryString(_safePrime);
WriteBinaryString(_subGroup);
WriteBinaryString(SafePrimeBytes);
WriteBinaryString(SubGroupBytes);
}

internal override void Process(Session session)
Expand Down
23 changes: 6 additions & 17 deletions src/Renci.SshNet/Security/GroupExchangeHashData.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Numerics;

using Renci.SshNet.Common;

Expand All @@ -9,8 +8,6 @@ internal sealed class GroupExchangeHashData : SshData
{
private byte[] _serverVersion;
private byte[] _clientVersion;
private byte[] _prime;
private byte[] _subGroup;

public string ServerVersion
{
Expand All @@ -36,17 +33,9 @@ public string ClientVersion

public uint MaximumGroupSize { get; set; }

public BigInteger Prime
{
private get { return _prime.ToBigInteger(); }
set { _prime = value.ToByteArray(isBigEndian: true); }
}
public byte[] Prime { get; set; }

public BigInteger SubGroup
{
private get { return _subGroup.ToBigInteger(); }
set { _subGroup = value.ToByteArray(isBigEndian: true); }
}
public byte[] SubGroup { get; set; }

public byte[] ClientExchangeValue { get; set; }

Expand Down Expand Up @@ -79,9 +68,9 @@ protected override int BufferCapacity
capacity += 4; // PreferredGroupSize
capacity += 4; // MaximumGroupSize
capacity += 4; // Prime length
capacity += _prime.Length; // Prime
capacity += Prime.Length; // Prime
capacity += 4; // SubGroup length
capacity += _subGroup.Length; // SubGroup
capacity += SubGroup.Length; // SubGroup
capacity += 4; // ClientExchangeValue length
capacity += ClientExchangeValue.Length; // ClientExchangeValue
capacity += 4; // ServerExchangeValue length
Expand All @@ -107,8 +96,8 @@ protected override void SaveData()
Write(MinimumGroupSize);
Write(PreferredGroupSize);
Write(MaximumGroupSize);
WriteBinaryString(_prime);
WriteBinaryString(_subGroup);
WriteBinaryString(Prime);
WriteBinaryString(SubGroup);
WriteBinaryString(ClientExchangeValue);
WriteBinaryString(ServerExchangeValue);
WriteBinaryString(SharedKey);
Expand Down
2 changes: 1 addition & 1 deletion src/Renci.SshNet/Security/KeyExchange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ protected bool CanTrustHostKey(KeyHostAlgorithm host)
/// <summary>
/// Validates the exchange hash.
/// </summary>
/// <returns>true if exchange hash is valid; otherwise false.</returns>
/// <returns><see langword="true"/> if exchange hash is valid; otherwise <see langword="false"/>.</returns>
protected abstract bool ValidateExchangeHash();

private protected bool ValidateExchangeHash(byte[] encodedKey, byte[] encodedSignature)
Expand Down
Loading