Skip to content

Commit 0606b3d

Browse files
committed
Use BouncyCastle for Diffie-Hellman key exchange
Removes another vestige of hand-rolled crypto, and makes the classes public + configurable for if/when we remove certain algorithms.
1 parent fd05d76 commit 0606b3d

25 files changed

+496
-1009
lines changed

src/Renci.SshNet/ConnectionInfo.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Security.Cryptography;
66
using System.Text;
77

8+
using Org.BouncyCastle.Crypto.Agreement;
9+
810
using Renci.SshNet.Common;
911
using Renci.SshNet.Compression;
1012
using Renci.SshNet.Messages.Authentication;
@@ -355,12 +357,13 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy
355357
{ "ecdh-sha2-nistp256", () => new KeyExchangeECDH256() },
356358
{ "ecdh-sha2-nistp384", () => new KeyExchangeECDH384() },
357359
{ "ecdh-sha2-nistp521", () => new KeyExchangeECDH521() },
358-
{ "diffie-hellman-group-exchange-sha256", () => new KeyExchangeDiffieHellmanGroupExchangeSha256() },
359-
{ "diffie-hellman-group-exchange-sha1", () => new KeyExchangeDiffieHellmanGroupExchangeSha1() },
360-
{ "diffie-hellman-group16-sha512", () => new KeyExchangeDiffieHellmanGroup16Sha512() },
361-
{ "diffie-hellman-group14-sha256", () => new KeyExchangeDiffieHellmanGroup14Sha256() },
362-
{ "diffie-hellman-group14-sha1", () => new KeyExchangeDiffieHellmanGroup14Sha1() },
363-
{ "diffie-hellman-group1-sha1", () => new KeyExchangeDiffieHellmanGroup1Sha1() },
360+
{ "diffie-hellman-group-exchange-sha256", () => new KeyExchangeDiffieHellmanGroupExchange("diffie-hellman-group-exchange-sha256", HashAlgorithmName.SHA256) },
361+
{ "diffie-hellman-group16-sha512", () => new KeyExchangeDiffieHellman("diffie-hellman-group16-sha512", DHStandardGroups.rfc3526_4096, HashAlgorithmName.SHA512) },
362+
{ "diffie-hellman-group18-sha512", () => new KeyExchangeDiffieHellman("diffie-hellman-group18-sha512", DHStandardGroups.rfc3526_8192, HashAlgorithmName.SHA512) },
363+
{ "diffie-hellman-group14-sha256", () => new KeyExchangeDiffieHellman("diffie-hellman-group14-sha256", DHStandardGroups.rfc3526_2048, HashAlgorithmName.SHA256) },
364+
{ "diffie-hellman-group-exchange-sha1", () => new KeyExchangeDiffieHellmanGroupExchange("diffie-hellman-group-exchange-sha1", HashAlgorithmName.SHA1) },
365+
{ "diffie-hellman-group14-sha1", () => new KeyExchangeDiffieHellman("diffie-hellman-group14-sha1", DHStandardGroups.rfc3526_2048, HashAlgorithmName.SHA1) },
366+
{ "diffie-hellman-group1-sha1", () => new KeyExchangeDiffieHellman("diffie-hellman-group1-sha1", DHStandardGroups.rfc2409_1024, HashAlgorithmName.SHA1) },
364367
};
365368

366369
Encryptions = new OrderedDictionary<string, CipherInfo>

src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeGroup.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ namespace Renci.SshNet.Messages.Transport
99
/// </summary>
1010
public class KeyExchangeDhGroupExchangeGroup : Message
1111
{
12-
private byte[] _safePrime;
13-
private byte[] _subGroup;
12+
internal byte[] SafePrimeBytes { get; private set; }
13+
internal byte[] SubGroupBytes { get; private set; }
1414

1515
/// <inheritdoc />
1616
public override string MessageName
@@ -38,7 +38,7 @@ public override byte MessageNumber
3838
/// </value>
3939
public BigInteger SafePrime
4040
{
41-
get { return _safePrime.ToBigInteger(); }
41+
get { return SafePrimeBytes.ToBigInteger(); }
4242
}
4343

4444
/// <summary>
@@ -49,7 +49,7 @@ public BigInteger SafePrime
4949
/// </value>
5050
public BigInteger SubGroup
5151
{
52-
get { return _subGroup.ToBigInteger(); }
52+
get { return SubGroupBytes.ToBigInteger(); }
5353
}
5454

5555
/// <summary>
@@ -64,9 +64,9 @@ protected override int BufferCapacity
6464
{
6565
var capacity = base.BufferCapacity;
6666
capacity += 4; // SafePrime length
67-
capacity += _safePrime.Length; // SafePrime
67+
capacity += SafePrimeBytes.Length; // SafePrime
6868
capacity += 4; // SubGroup length
69-
capacity += _subGroup.Length; // SubGroup
69+
capacity += SubGroupBytes.Length; // SubGroup
7070

7171
return capacity;
7272
}
@@ -77,17 +77,17 @@ protected override int BufferCapacity
7777
/// </summary>
7878
protected override void LoadData()
7979
{
80-
_safePrime = ReadBinary();
81-
_subGroup = ReadBinary();
80+
SafePrimeBytes = ReadBinary();
81+
SubGroupBytes = ReadBinary();
8282
}
8383

8484
/// <summary>
8585
/// Called when type specific data need to be saved.
8686
/// </summary>
8787
protected override void SaveData()
8888
{
89-
WriteBinaryString(_safePrime);
90-
WriteBinaryString(_subGroup);
89+
WriteBinaryString(SafePrimeBytes);
90+
WriteBinaryString(SubGroupBytes);
9191
}
9292

9393
internal override void Process(Session session)

src/Renci.SshNet/Security/GroupExchangeHashData.cs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Numerics;
32

43
using Renci.SshNet.Common;
54

@@ -9,8 +8,6 @@ internal sealed class GroupExchangeHashData : SshData
98
{
109
private byte[] _serverVersion;
1110
private byte[] _clientVersion;
12-
private byte[] _prime;
13-
private byte[] _subGroup;
1411

1512
public string ServerVersion
1613
{
@@ -36,17 +33,9 @@ public string ClientVersion
3633

3734
public uint MaximumGroupSize { get; set; }
3835

39-
public BigInteger Prime
40-
{
41-
private get { return _prime.ToBigInteger(); }
42-
set { _prime = value.ToByteArray(isBigEndian: true); }
43-
}
36+
public byte[] Prime { get; set; }
4437

45-
public BigInteger SubGroup
46-
{
47-
private get { return _subGroup.ToBigInteger(); }
48-
set { _subGroup = value.ToByteArray(isBigEndian: true); }
49-
}
38+
public byte[] SubGroup { get; set; }
5039

5140
public byte[] ClientExchangeValue { get; set; }
5241

@@ -79,9 +68,9 @@ protected override int BufferCapacity
7968
capacity += 4; // PreferredGroupSize
8069
capacity += 4; // MaximumGroupSize
8170
capacity += 4; // Prime length
82-
capacity += _prime.Length; // Prime
71+
capacity += Prime.Length; // Prime
8372
capacity += 4; // SubGroup length
84-
capacity += _subGroup.Length; // SubGroup
73+
capacity += SubGroup.Length; // SubGroup
8574
capacity += 4; // ClientExchangeValue length
8675
capacity += ClientExchangeValue.Length; // ClientExchangeValue
8776
capacity += 4; // ServerExchangeValue length
@@ -107,8 +96,8 @@ protected override void SaveData()
10796
Write(MinimumGroupSize);
10897
Write(PreferredGroupSize);
10998
Write(MaximumGroupSize);
110-
WriteBinaryString(_prime);
111-
WriteBinaryString(_subGroup);
99+
WriteBinaryString(Prime);
100+
WriteBinaryString(SubGroup);
112101
WriteBinaryString(ClientExchangeValue);
113102
WriteBinaryString(ServerExchangeValue);
114103
WriteBinaryString(SharedKey);

src/Renci.SshNet/Security/KeyExchange.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ protected bool CanTrustHostKey(KeyHostAlgorithm host)
482482
/// <summary>
483483
/// Validates the exchange hash.
484484
/// </summary>
485-
/// <returns>true if exchange hash is valid; otherwise false.</returns>
485+
/// <returns><see langword="true"/> if exchange hash is valid; otherwise <see langword="false"/>.</returns>
486486
protected abstract bool ValidateExchangeHash();
487487

488488
private protected bool ValidateExchangeHash(byte[] encodedKey, byte[] encodedSignature)

0 commit comments

Comments
 (0)